Skip to main content

kernel_api/sync/
mod.rs

1//! Provides kernel synchronisation primitives.
2//!
3//! # Overview
4//!
5//! The following is an overview of the available synchronisation objects:
6//! - [`Spinlock`]: Provides mutual exclusion by [busy-waiting](https://en.wikipedia.org/wiki/Busy_waiting) until
7//!   the protected resource is available.
8//! - [`RwSpinlock`]: An alternative to a plain `Spinlock` which allows for multiple concurrent readers, which
9//!   can be more efficient for read-heavy workloads.
10//! - [`IrqCell`]: A single-threaded mutual exclusion primitive, similar to [`RefCell`](`core::cell::RefCell`),
11//!   which attempts to reduce deadlocks by disabling interrupts while locked.
12//! - [`OnceLock`]: Used for thread-safe, one-time initialization of a variable, with potentially different
13//!   initializers based on the caller.
14//! - [`LazyLock`]: Used for thread-safe, one-time initialization of a variable, using one nullary initializer
15//!   function provided at creation.
16
17use core::ops::{Deref, DerefMut};
18
19#[cfg(not(feature = "use_std"))]
20pub use mutex::{Spinlock, SpinlockGuard, SpinlockGuardExt, MappedSpinlockGuard};
21#[cfg(feature = "use_std")]
22pub use parking_lot::{Mutex as Spinlock, MutexGuard as SpinlockGuard, MappedMutexGuard as MappedSpinlockGuard};
23
24#[cfg(not(feature = "use_std"))]
25pub use once::{LazyLock, Once, OnceLock};
26#[cfg(feature = "use_std")]
27pub use std::sync::{LazyLock, Once, OnceLock};
28
29#[cfg(not(feature = "use_std"))]
30pub use rwlock::{RwSpinlock, RwReadGuard, RwUpgradableReadGuard, RwWriteGuard};
31#[cfg(feature = "use_std")]
32pub use parking_lot::{RwLock as RwSpinlock, RwLockReadGuard as RwReadGuard, RwLockUpgradableReadGuard as RwUpgradableReadGuard, RwLockWriteGuard as RwWriteGuard};
33
34#[cfg(not(feature = "use_std"))]
35pub use irq_cell::{IrqCell, IrqGuard};
36
37#[cfg(not(feature = "use_std"))]
38mod mutex;
39
40#[cfg(not(feature = "use_std"))]
41pub(crate) mod rwlock;
42
43#[cfg(not(feature = "use_std"))]
44mod once;
45
46#[cfg(not(feature = "use_std"))]
47mod irq_cell;
48
49#[doc(hidden)]
50pub struct Syncify<T>(T);
51
52impl<T> Syncify<T> {
53	/// # Safety
54	///
55	/// The contained value must only be accessed (including dropping) on other threads if it is [`Sync`]/[`Send`].
56	pub unsafe fn new(t: T) -> Self { Self(t) }
57
58	pub fn into_inner(self) -> T { self.0 }
59}
60
61impl<T> Deref for Syncify<T> {
62	type Target = T;
63
64	fn deref(&self) -> &Self::Target {
65		&self.0
66	}
67}
68
69impl<T> DerefMut for Syncify<T> {
70	fn deref_mut(&mut self) -> &mut Self::Target {
71		&mut self.0
72	}
73}
74
75unsafe impl<T> Sync for Syncify<T> {}
76unsafe impl<T> Send for Syncify<T> {}