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 
15 pub use arc::{Arc, ArcBorrow, UniqueArc};
16 pub use condvar::{new_condvar, CondVar, CondVarTimeoutResult};
17 pub use lock::mutex::{new_mutex, Mutex};
18 pub use lock::spinlock::{new_spinlock, SpinLock};
19 pub use locked_by::LockedBy;
20 
21 /// Represents a lockdep class. It's a wrapper around C's `lock_class_key`.
22 #[repr(transparent)]
23 pub struct LockClassKey(Opaque<bindings::lock_class_key>);
24 
25 // SAFETY: `bindings::lock_class_key` is designed to be used concurrently from multiple threads and
26 // provides its own synchronization.
27 unsafe impl Sync for LockClassKey {}
28 
29 impl LockClassKey {
30     /// Creates a new lock class key.
new() -> Self31     pub const fn new() -> Self {
32         Self(Opaque::uninit())
33     }
34 
as_ptr(&self) -> *mut bindings::lock_class_key35     pub(crate) fn as_ptr(&self) -> *mut bindings::lock_class_key {
36         self.0.get()
37     }
38 }
39 
40 impl Default for LockClassKey {
default() -> Self41     fn default() -> Self {
42         Self::new()
43     }
44 }
45 
46 /// Defines a new static lock class and returns a pointer to it.
47 #[doc(hidden)]
48 #[macro_export]
49 macro_rules! static_lock_class {
50     () => {{
51         static CLASS: $crate::sync::LockClassKey = $crate::sync::LockClassKey::new();
52         &CLASS
53     }};
54 }
55 
56 /// Returns the given string, if one is provided, otherwise generates one based on the source code
57 /// location.
58 #[doc(hidden)]
59 #[macro_export]
60 macro_rules! optional_name {
61     () => {
62         $crate::c_str!(::core::concat!(::core::file!(), ":", ::core::line!()))
63     };
64     ($name:literal) => {
65         $crate::c_str!($name)
66     };
67 }
68