Documentation (synchronization primitives)
Documentation (core parking lot API)
Documentation (type-safe lock API)
This library provides compact and efficient implementations of Mutex,
RwLock, RecursiveRwLock, Condvar and Once, as well as a
ReentrantMutex type. It also exposes a low-level API for creating your own
synchronization primitives.
Notable features of the primitives provided by this library include:
MutexandOnceonly require 1 byte of storage space, whileCondvarandRwLockonly require 1 word of storage space. The small size ofMutexin particular encourages the use of fine-grained locks to increase parallelism.- Uncontended lock acquisition and release is done through fast inline paths which only require a single atomic operation.
- Microcontention (a contended lock with a short critical section) is efficiently handled by spinning a few times while trying to acquire a lock.
- The locks are adaptive and will suspend a thread after a few failed spin attempts. This makes the locks suitable for both long and short critical sections.
RwLockuses a task-fair locking policy which generally gives waiting writers priority over new readers.Condvaris guaranteed not to produce spurious wakeups. A thread will only be woken up if it timed out or it was woken up by a notification.Condvar::notify_allrequeues waiters directly onto the associatedMutexand wakes them as the lock becomes available. This avoids a thundering herd where every thread immediately tries to acquire the mutex.RwLocksupports atomically downgrading a write lock into a read lock.MutexandRwLockallow raw unlocking without a RAII guard object.Mutex<()>andRwLock<()>allow raw locking without a RAII guard object.MutexandRwLocksupport explicit fair unlocking, which hands the lock directly to a waiting thread.ReentrantMutexandRecursiveRwLocktypes which support recursive locking.- An experimental deadlock detector that works for
Mutex,RwLock,RecursiveRwLockandReentrantMutex. This feature is disabled by default and can be enabled via thedeadlock_detectionfeature. RwLockandRecursiveRwLocksupport atomically upgrading an "upgradable" read lock into a write lock.- Optional support for serde. Enable via the
feature
serde. NOTE! this support is forMutex,ReentrantMutex,RwLock, andRecursiveRwLockonly;CondvarandOnceare not currently supported. - Lock guards can be sent to other threads when the
send_guardfeature is enabled.
To keep these primitives small, all thread queuing and suspending
functionality is offloaded to the parking lot. The idea behind this is
based on the WebKit WTF::ParkingLot
class, which essentially consists of a hash table mapping of lock addresses
to queues of parked (sleeping) threads. The WebKit parking lot was itself
inspired by Linux futexes,
but it is more powerful since it allows invoking callbacks while holding a queue
lock.
There are a few restrictions when using this library on stable Rust:
- The
wasm32-unknown-unknowntarget is only fully supported on nightly with-C target-feature=+atomicsinRUSTFLAGSand-Zbuild-std=panic_abort,stdpassed to cargo. parking_lot will work mostly fine on stable, the only difference is it will panic instead of block forever if you hit a deadlock. Just make sure not to enable-C target-feature=+atomicson stable as that will allow wasm to run with multiple threads which will completely break parking_lot's concurrency guarantees.
To enable nightly-only functionality, you need to enable the nightly feature
in Cargo (see below).
Add this to your Cargo.toml:
[dependencies]
parking_lot = "0.12"To enable nightly-only features, add this to your Cargo.toml instead:
[dependencies]
parking_lot = { version = "0.12", features = ["nightly"] }The experimental deadlock detector can be enabled with the
deadlock_detection Cargo feature.
To allow sending MutexGuards and RwLock*Guards to other threads, enable the
send_guard option.
Note that the deadlock_detection and send_guard features are incompatible
and cannot be used together.
The core parking lot API is provided by the parking_lot_core crate. It is
separate from the synchronization primitives in the parking_lot crate so that
changes to the core API do not cause breaking changes for users of parking_lot.
The current minimum required Rust version is 1.95, but this may change at any time.
Licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.