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