Skip to main content

parking_lot_core/
lib.rs

1//! This library exposes a low-level API for creating your own efficient
2//! synchronization primitives.
3//!
4//! # The parking lot
5//!
6//! To keep synchronization primitives small, all thread queuing and suspending
7//! functionality is offloaded to the *parking lot*. The idea behind this is based
8//! on the WebKit [`WTF::ParkingLot`](https://webkit.org/blog/6161/locking-in-webkit/)
9//! class, which essentially consists of a hash table mapping of lock addresses
10//! to queues of parked (sleeping) threads. The WebKit parking lot was itself
11//! inspired by Linux [futexes](https://man7.org/linux/man-pages/man2/futex.2.html),
12//! but it is more powerful since it allows invoking callbacks while holding a
13//! queue lock.
14//!
15//! There are two main operations that can be performed on the parking lot:
16//!
17//!  - *Parking* refers to suspending the thread while simultaneously enqueuing it
18//!    on a queue keyed by some address.
19//!  - *Unparking* refers to dequeuing a thread from a queue keyed by some address
20//!    and resuming it.
21//!
22//! See the documentation of the individual functions for more details.
23//!
24//! Parking-lot operations never unwind. If an operation panics, the process
25//! aborts.
26//!
27//! # Use in global allocators
28//!
29//! Synchronization primitives built on this parking lot must not be used
30//! internally by a global allocator. Parking-lot operations may allocate
31//! memory, including while internal locks are held. If the allocator then
32//! blocks on one of these primitives, it may recursively invoke itself or
33//! deadlock.
34//!
35//! # Building custom synchronization primitives
36//!
37//! Building custom synchronization primitives is very simple since the parking
38//! lot takes care of all the hard parts for you. A simple example for a
39//! custom primitive would be to integrate a `Mutex` inside another data type.
40//! Since a mutex only requires 2 bits, it can share space with other data.
41//! For example, one could create an `ArcMutex` type that combines the atomic
42//! reference count and the two mutex bits in the same atomic word.
43
44#![warn(missing_docs)]
45#![warn(rust_2018_idioms)]
46#![cfg_attr(
47    all(target_env = "sgx", target_vendor = "fortanix"),
48    feature(sgx_platform)
49)]
50#![cfg_attr(
51    all(
52        feature = "nightly",
53        target_family = "wasm",
54        target_feature = "atomics"
55    ),
56    feature(stdarch_wasm_atomic_wait)
57)]
58
59mod parking_lot;
60mod spinwait;
61mod thread_parker;
62mod word_lock;
63
64pub use self::parking_lot::deadlock;
65pub use self::parking_lot::{DEFAULT_PARK_TOKEN, DEFAULT_UNPARK_TOKEN};
66pub use self::parking_lot::{
67    FilterOp, ParkResult, ParkToken, RequeueOp, UnparkResult, UnparkToken,
68};
69pub use self::parking_lot::{park, unpark_all, unpark_filter, unpark_one, unpark_requeue};
70pub use self::spinwait::SpinWait;