Skip to content

perf(runtime): migrate std::sync::Mutex to parking_lot where not held across await#430

Open
lgahdl wants to merge 1 commit into
nullislabs:developfrom
bleu:perf/280-parking-lot-migration
Open

perf(runtime): migrate std::sync::Mutex to parking_lot where not held across await#430
lgahdl wants to merge 1 commit into
nullislabs:developfrom
bleu:perf/280-parking-lot-migration

Conversation

@lgahdl

@lgahdl lgahdl commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fixes #280. Migrated every std::sync::Mutex site the issue named to parking_lot::Mutex — faster under contention, one word instead of a boxed OS primitive, no lock poisoning.

Audited each site individually before migrating (the issue's own explicit caveat — a guard held across an .await must not become a parking_lot guard, since it's !Send and would block the executor thread):

  • crates/nexum-runtime/src/host/logs/{mod,stdio,store}.rsstore.rs is real production code (InMemoryRunLogStore); mod.rs/stdio.rs sites are #[cfg(test)] mocks. All non-async or async-but-lock-dropped-before-any-.await.
  • crates/nexum-runtime/src/test_utils/{chain,clock,store}.rstest-utils-feature-gated mocks. chain.rs's async move { ... } blocks acquire the lock, do synchronous work, and return — never await while holding it. Verified directly, not inferred.
  • crates/nexum-sdk/src/tracing.rs — the one Mutex here is inside #[cfg(test)] mod tests, so it's a [dev-dependencies] addition and never touches the actual wasm32 guest build.

Scope correction: crates/nexum-runtime/src/host/pool_router.rs, named in the issue alongside ledger/watched Mutex fields, no longer exists — grepped the whole tree for both, found neither. That part of the issue's scope is stale; nothing to migrate there.

parking_lot was already in the tree transitively (0.12.5, per cargo tree), so adding it as a direct dependency resolved to the same version — Cargo.lock diff is just two new dependency-edge lines, no version bumps.

Dropped the poison-handling boilerplate everywhere it touched (.unwrap(), .expect("... poisoned"), .unwrap_or_else(|e| e.into_inner())) since parking_lot::Mutex::lock() returns the guard directly.

The one existing tokio::sync lock is untouched, as scoped by the issue.

Test plan

  • cargo build --release --target wasm32-wasip2 for all 12 guest modules — clean (confirms the nexum-sdk dev-dependency never reaches the wasm32 build)
  • cargo clippy --workspace --all-targets --all-features --locked -- -D warnings — clean
  • cargo fmt --all -- --check — clean
  • cargo test --workspace --all-features --locked — full suite green

@lgahdl
lgahdl requested a review from mfw78 as a code owner July 16, 2026 15:27
… across await

Audited every std::sync::Mutex site named in the issue: all are short
critical sections over plain data with no guard held across an
.await - confirmed per site, not assumed (host/logs/store.rs is real
production code; the rest are test-only or test_utils mocks). Moved
each to parking_lot::Mutex, dropping the poison handling on lock()
(.unwrap(), .expect("... poisoned"), .unwrap_or_else(|e| e.into_inner()))
since parking_lot never poisons.

parking_lot was already in the tree transitively (0.12.5); added as
a direct workspace dependency, .workspace = true in nexum-runtime's
[dependencies] (host/logs/store.rs is real code) and nexum-sdk's
[dev-dependencies] (tracing.rs's Mutex is test-only, so this never
touches the wasm32 guest build - confirmed by building all 12 guest
modules for wasm32-wasip2 after the change).

crates/nexum-runtime/src/host/pool_router.rs, named in the issue's
scope list alongside `ledger`/`watched` Mutex fields, no longer
exists - grepped the whole tree for both, found neither. That part
of the original scope is moot; nothing left to migrate there.

No locks held across .await anywhere in the touched files - verified
directly against each site, not inferred from context - so no
tokio::sync::Mutex conversions were needed. The one pre-existing
tokio::sync lock is untouched, as scoped.

Fixes nullislabs#280.
@lgahdl
lgahdl force-pushed the perf/280-parking-lot-migration branch from bbb3915 to 1841607 Compare July 17, 2026 14:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

perf: migrate std::sync locks to parking_lot where not held across await

1 participant