Crates.io | usync |
lib.rs | usync |
version | 0.2.1 |
source | src |
created_at | 2020-10-08 22:29:26.242901 |
updated_at | 2022-05-29 16:10:15.74261 |
description | fast, drop-in, synchronization primitives |
homepage | |
repository | https://github.com/kprotty/usync |
max_upload_size | |
id | 297434 |
size | 158,200 |
This library provides implementations of Mutex
, RwLock
, Condvar
, Barrier
and
Once
that are word-sized and generally fast as those in parking_lot
.
It also provides a ReentrantMutex
type which supports recursive locking.
The primitives provided by this library have several advantages over those in the Rust standard library:
Box
to hold
OS-specific synchronization primitives. The small size of Mutex
in
particular encourages the use of fine-grained locks to increase
parallelism.static
global variables. The standard library primitives require
dynamic initialization and thus need to be lazily initialized with
lazy_static!
.Condvar::notify_all
will generally only wake up a single thread and requeue the
rest to wait on the associated Mutex
. This avoids a thundering herd
problem where all threads try to acquire the lock at the same time.Mutex
and RwLock
allow raw unlocking without a RAII guard object.Mutex<()>
and RwLock<()>
allow raw locking without a RAII guard
object.ReentrantMutex
type which supports recursive locking.send_guard
feature is
enabled.To keep these primitives word sized, their state is multiplexed between counters, queues of threads, and combinations of both. This draws similarities to Windows' Slim Synchronization Primitives. No external locking of global queues as seen in Linux futex or parking_lot is employed. The queues are all embedded in each primitive and interacted with lock-free operations to decrease worst-case contention latency.
Having to juggle around queues with the synchronization state unfortunately means
that "no spurious wakeups" cannot be guaranteed for Condvar
and that extreme read-only workflows
for RwLock
can't use optimized atomics to improve throughput. These perf limits shouldn't matter
in practice though, even more so when other cache effects come into play. On the bright side,
writer/exclusive heavy workloads scale much better than existing solutions and are heavily
optimized for micro-contention.
There are a few restrictions when using this library on stable Rust:
const_*
functions (e.g. const_mutex(val)
) to
statically initialize the locking primitives. Using e.g. Mutex::new(val)
does not work on stable Rust yet.To enable nightly-only functionality, you need to enable the nightly
feature
in Cargo (see below).
Add this to your Cargo.toml
:
[dependencies]
usync = "0.2.1"
To enable nightly-only features, add this to your Cargo.toml
instead:
[dependencies]
usync = { version = "0.2.1", features = ["nightly"] }
To allow sending MutexGuard
s and RwLock*Guard
s to other threads, enable the
send_guard
option.
Licensed under MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT).