Expand description
§Synchronous and Asynchronous Synchronization Primitives
Low-level synchronization primitives that provide both synchronous and asynchronous interfaces.
§Features
- Asynchronous counterparts of synchronous methods.
Loomsupport:features = ["loom"].- No spin-locks and no busy loops.
§Lock
saa::Lock is a Low-level shared-exclusive lock that provides both synchronous and asynchronous interfaces. Synchronous locking methods such as lock_sync or lock_shared_sync can be used with their asynchronous counterparts, lock_exclusive_async or lock_shared_async, at the same time. saa::Lock implements a heap-allocation-free fair wait queue that is shared among both synchronous and asynchronous methods.
§Notes
Use of synchronous methods in an asynchronous context may lead to a deadlock. Suppose a scenario where an asynchronous runtime provides two threads executing three tasks.
- ThreadId(0):
task-0: share-waiting / pending||task-1: "synchronous"-lock-waiting. - ThreadId(1):
task-2: release-lock / ready: wake-up task-0->task-2: lock-waiting / pending.
In the above example, task-0 logically has acquired a shared lock which was transferred from task-2, it may remain in the task queue indefinitely, depending on the scheduling policy of the asynchronous runtime.
§Examples
use saa::Lock;
let lock = Lock::default();
lock.lock_sync();
assert!(!lock.try_lock());
assert!(!lock.try_share());
assert!(!lock.release_share());
assert!(lock.release_lock());
async {
lock.share_async();
assert!(lock.release_share());
};§Semaphore
saa::Semaphore is a synchronization primitive that allows a fixed number of threads to access a resource concurrently.
§Examples
use saa::Semaphore;
let semaphore = Semaphore::default();
semaphore.acquire_many_sync(Semaphore::MAX_PERMITS - 1);
assert!(semaphore.try_acquire());
assert!(!semaphore.try_acquire());
assert!(semaphore.release());
assert!(!semaphore.release_many(Semaphore::MAX_PERMITS));
assert!(semaphore.release_many(Semaphore::MAX_PERMITS - 1));
async {
semaphore.acquire_async().await;
assert!(semaphore.release());
};