spinning_top/
lib.rs

1//! Provides simple spinlocks based on the abstractions provided by the [`lock_api`] crate.
2//!
3//! [`lock_api`]: https://docs.rs/lock_api/
4//!
5//! # Examples
6//!
7//! Use [`Spinlock`] for mutual exclusion:
8//!
9//! ```
10//! use spinning_top::Spinlock;
11//!
12//! fn main() {
13//!     let data = String::from("Hello");
14//!     // Wrap some data in a spinlock
15//!     let spinlock = Spinlock::new(data);
16//!
17//!     // Lock the spinlock to get a mutex guard for the data
18//!     let mut locked_data = spinlock.lock();
19//!     // The guard implements the `Deref` trait, so we can use it like a `&String`
20//!     assert_eq!(locked_data.as_str(), "Hello");
21//!     // It also implements `DerefMut` so mutation is possible too. This is safe
22//!     // because the spinlock ensures mutual exclusion
23//!     locked_data.make_ascii_uppercase();
24//!     assert_eq!(locked_data.as_str(), "HELLO");
25//!
26//!     // the guard automatically frees the lock at the end of the scope
27//! }
28//! ```
29//!
30//! Use [`RwSpinlock`] if you need a readers-writer lock:
31//!
32//! ```
33//! use spinning_top::RwSpinlock;
34//!
35//! let lock = RwSpinlock::new(5);
36//!
37//! // many reader locks can be held at once
38//! {
39//!     let r1 = lock.read();
40//!     let r2 = lock.read();
41//!     assert_eq!(*r1, 5);
42//!     assert_eq!(*r2, 5);
43//! } // read locks are dropped at this point
44//!
45//! // only one write lock may be held, however
46//! {
47//!     let mut w = lock.write();
48//!     *w += 1;
49//!     assert_eq!(*w, 6);
50//! } // write lock is dropped here
51//! ```
52
53#![cfg_attr(not(test), no_std)]
54#![cfg_attr(docsrs, feature(doc_auto_cfg))]
55#![warn(missing_docs)]
56#![warn(missing_debug_implementations)]
57
58/// The spinlock implemenation is based on the abstractions provided by the `lock_api` crate.
59pub use lock_api;
60
61pub use rw_spinlock::{BackoffRwSpinlock, RawRwSpinlock, RwSpinlock};
62pub use spinlock::{BackoffSpinlock, RawSpinlock, Spinlock};
63
64/// Type aliases for guards.
65pub mod guard {
66    #[cfg(feature = "arc_lock")]
67    pub use super::rw_spinlock::{
68        ArcBackoffRwSpinlockReadGuard, ArcBackoffRwSpinlockUpgradableReadGuard,
69        ArcBackoffRwSpinlockWriteGuard, ArcRwSpinlockReadGuard, ArcRwSpinlockUpgradableReadGuard,
70        ArcRwSpinlockWriteGuard,
71    };
72    pub use super::rw_spinlock::{
73        BackoffRwSpinlockReadGuard, BackoffRwSpinlockUpgradableReadGuard,
74        BackoffRwSpinlockWriteGuard, RwSpinlockReadGuard, RwSpinlockUpgradableReadGuard,
75        RwSpinlockWriteGuard,
76    };
77    #[cfg(feature = "arc_lock")]
78    pub use super::spinlock::{ArcBackoffSpinlockGuard, ArcSpinlockGuard};
79    pub use super::spinlock::{
80        BackoffSpinlockGuard, MappedBackoffSpinlockGuard, MappedSpinlockGuard, SpinlockGuard,
81    };
82}
83
84pub mod relax;
85mod rw_spinlock;
86mod spinlock;