1 // SPDX-License-Identifier: GPL-2.0
2 
3 //! Synchronisation primitives.
4 //!
5 //! This module contains the kernel APIs related to synchronisation that have been ported or
6 //! wrapped for usage by Rust code in the kernel.
7 
8 use crate::types::Opaque;
9 
10 mod arc;
11 mod condvar;
12 pub mod lock;
13 mod locked_by;
14 pub mod poll;
15 pub mod rcu;
16 
17 pub use arc::{Arc, ArcBorrow, UniqueArc};
18 pub use condvar::{new_condvar, CondVar, CondVarTimeoutResult};
19 pub use lock::global::{global_lock, GlobalGuard, GlobalLock, GlobalLockBackend, GlobalLockedBy};
20 pub use lock::mutex::{new_mutex, Mutex, MutexGuard};
21 pub use lock::spinlock::{new_spinlock, SpinLock, SpinLockGuard};
22 pub use locked_by::LockedBy;
23 
24 /// Represents a lockdep class. It's a wrapper around C's `lock_class_key`.
25 #[repr(transparent)]
26 pub struct LockClassKey(Opaque<bindings::lock_class_key>);
27 
28 // SAFETY: `bindings::lock_class_key` is designed to be used concurrently from multiple threads and
29 // provides its own synchronization.
30 unsafe impl Sync for LockClassKey {}
31 
32 impl LockClassKey {
as_ptr(&self) -> *mut bindings::lock_class_key33     pub(crate) fn as_ptr(&self) -> *mut bindings::lock_class_key {
34         self.0.get()
35     }
36 }
37 
38 /// Defines a new static lock class and returns a pointer to it.
39 #[doc(hidden)]
40 #[macro_export]
41 macro_rules! static_lock_class {
42     () => {{
43         static CLASS: $crate::sync::LockClassKey =
44             // SAFETY: lockdep expects uninitialized memory when it's handed a statically allocated
45             // lock_class_key
46             unsafe { ::core::mem::MaybeUninit::uninit().assume_init() };
47         &CLASS
48     }};
49 }
50 
51 /// Returns the given string, if one is provided, otherwise generates one based on the source code
52 /// location.
53 #[doc(hidden)]
54 #[macro_export]
55 macro_rules! optional_name {
56     () => {
57         $crate::c_str!(::core::concat!(::core::file!(), ":", ::core::line!()))
58     };
59     ($name:literal) => {
60         $crate::c_str!($name)
61     };
62 }
63