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 impl Default for LockClassKey { 41 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