Inside Rust's std and parking_lot mutexes – who wins?
Parking_lot design and tiny locks
- Original WTF::ParkingLot was designed to make locks extremely small, enabling fine‑grained locking (e.g., 2‑bit locks in every JSCore object header).
- Multiple commenters clarify that while the Rust
parking_lotalgorithm only needs ~2 bits,parking_lot::RawMutexis a full byte and does not expose the remaining 6 bits to users. - To get true bit‑stealing behavior in Rust, you’d likely need to build your own lock using
parking_lot_core, not the high‑levelparking_lot::Mutex. - Several people note that
parking_lot::Mutex<T>often ends up word‑aligned, erasing the theoretical size advantage in typical use.
Rust std::Mutex vs parking_lot and platform behavior
- Old
std::sync::Mutexwrappedpthread_mutex_tin aBox, causing heap allocation, indirection, and non‑movability. - New std mutexes are “thin wrappers” around futex/WaitOnAddress/SRW primitives, const‑constructible and small, with the OS managing wait queues.
- A key reason std didn’t just adopt
parking_lot:parking_lotallocates a global hash table, which can deadlock with custom allocators that themselves use std locks. - Discussion of native lock sizes:
pthread_mutex_t(40 bytes) and Windows80 bytes) are described as bulky compared to the new futex‑style mutexes.CRITICAL_SECTION(
Mutex poisoning: value vs drawbacks
- One camp sees poisoning as a major misfeature: most code just calls
.lock().unwrap(), poisoning enables easy DoS, and many uses ofMutexdon’t actually require atomic invariants. - The other camp argues poisoning is “table stakes” for correctness: a panic in a critical section often means invariants may be broken; blindly continuing is dangerous, especially in long‑running services.
- Examples are given where recovery from poison is useful (e.g., GPU resource cleanup in
Drop), but such cases are rare. - A std contributor notes there are no historical reports of real‑world poison recovery, and std is working on separating poisoning into an opt‑in wrapper (e.g.,
Mutex<Poison<T>>), so the defaultMutexwould no longer poison.
Panics, unwinding, and alternatives
- Some participants wish Rust had no panic unwinding at all, due to complexity and subtle invariants during unwinding.
- Ideas floated include scoped panic hooks and RAII‑style cleanup via registered hooks instead of unwinding, but this is acknowledged as speculative and difficult to design without breaking existing use cases like HTTP servers.
Choosing concurrency primitives
- Several commenters recommend avoiding mutexes in most application code in favor of message‑passing (channels) or RCU, both for maintainability and scalability.
- Others report mutex‑based designs being easier to adapt than channel‑based ones for complex back‑pressure and prioritization logic.
- There are anecdotes of serious performance issues from contention (even on refcounts), reinforcing that profiling should guide the choice of primitives.