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;