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. |
31 | pub const fn new() -> Self { |
32 | Self(Opaque::uninit()) |
33 | } |
34 | |
35 | pub(crate) fn as_ptr(&self) -> *mut bindings::lock_class_key { |
36 | self.0.get() |
37 | } |
38 | } |
39 | |
40 | /// Defines a new static lock class and returns a pointer to it. |
41 | #[doc(hidden)] |
42 | #[macro_export] |
43 | macro_rules! static_lock_class { |
44 | () => {{ |
45 | static CLASS: $crate::sync::LockClassKey = $crate::sync::LockClassKey::new(); |
46 | &CLASS |
47 | }}; |
48 | } |
49 | |
50 | /// Returns the given string, if one is provided, otherwise generates one based on the source code |
51 | /// location. |
52 | #[doc(hidden)] |
53 | #[macro_export] |
54 | macro_rules! optional_name { |
55 | () => { |
56 | $crate::c_str!(::core::concat!(::core::file!(), ":" , ::core::line!())) |
57 | }; |
58 | ($name:literal) => { |
59 | $crate::c_str!($name) |
60 | }; |
61 | } |
62 | |