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