Loading...
Note: File does not exist in v6.2.
1// SPDX-License-Identifier: GPL-2.0
2
3//! A kernel mutex.
4//!
5//! This module allows Rust code to use the kernel's `struct mutex`.
6
7use crate::bindings;
8
9/// Creates a [`Mutex`] initialiser with the given name and a newly-created lock class.
10///
11/// It uses the name if one is given, otherwise it generates one based on the file name and line
12/// number.
13#[macro_export]
14macro_rules! new_mutex {
15 ($inner:expr $(, $name:literal)? $(,)?) => {
16 $crate::sync::Mutex::new(
17 $inner, $crate::optional_name!($($name)?), $crate::static_lock_class!())
18 };
19}
20pub use new_mutex;
21
22/// A mutual exclusion primitive.
23///
24/// Exposes the kernel's [`struct mutex`]. When multiple threads attempt to lock the same mutex,
25/// only one at a time is allowed to progress, the others will block (sleep) until the mutex is
26/// unlocked, at which point another thread will be allowed to wake up and make progress.
27///
28/// Since it may block, [`Mutex`] needs to be used with care in atomic contexts.
29///
30/// Instances of [`Mutex`] need a lock class and to be pinned. The recommended way to create such
31/// instances is with the [`pin_init`](crate::pin_init) and [`new_mutex`] macros.
32///
33/// # Examples
34///
35/// The following example shows how to declare, allocate and initialise a struct (`Example`) that
36/// contains an inner struct (`Inner`) that is protected by a mutex.
37///
38/// ```
39/// use kernel::sync::{new_mutex, Mutex};
40///
41/// struct Inner {
42/// a: u32,
43/// b: u32,
44/// }
45///
46/// #[pin_data]
47/// struct Example {
48/// c: u32,
49/// #[pin]
50/// d: Mutex<Inner>,
51/// }
52///
53/// impl Example {
54/// fn new() -> impl PinInit<Self> {
55/// pin_init!(Self {
56/// c: 10,
57/// d <- new_mutex!(Inner { a: 20, b: 30 }),
58/// })
59/// }
60/// }
61///
62/// // Allocate a boxed `Example`.
63/// let e = Box::pin_init(Example::new())?;
64/// assert_eq!(e.c, 10);
65/// assert_eq!(e.d.lock().a, 20);
66/// assert_eq!(e.d.lock().b, 30);
67/// # Ok::<(), Error>(())
68/// ```
69///
70/// The following example shows how to use interior mutability to modify the contents of a struct
71/// protected by a mutex despite only having a shared reference:
72///
73/// ```
74/// use kernel::sync::Mutex;
75///
76/// struct Example {
77/// a: u32,
78/// b: u32,
79/// }
80///
81/// fn example(m: &Mutex<Example>) {
82/// let mut guard = m.lock();
83/// guard.a += 10;
84/// guard.b += 20;
85/// }
86/// ```
87///
88/// [`struct mutex`]: srctree/include/linux/mutex.h
89pub type Mutex<T> = super::Lock<T, MutexBackend>;
90
91/// A kernel `struct mutex` lock backend.
92pub struct MutexBackend;
93
94// SAFETY: The underlying kernel `struct mutex` object ensures mutual exclusion.
95unsafe impl super::Backend for MutexBackend {
96 type State = bindings::mutex;
97 type GuardState = ();
98
99 unsafe fn init(
100 ptr: *mut Self::State,
101 name: *const core::ffi::c_char,
102 key: *mut bindings::lock_class_key,
103 ) {
104 // SAFETY: The safety requirements ensure that `ptr` is valid for writes, and `name` and
105 // `key` are valid for read indefinitely.
106 unsafe { bindings::__mutex_init(ptr, name, key) }
107 }
108
109 unsafe fn lock(ptr: *mut Self::State) -> Self::GuardState {
110 // SAFETY: The safety requirements of this function ensure that `ptr` points to valid
111 // memory, and that it has been initialised before.
112 unsafe { bindings::mutex_lock(ptr) };
113 }
114
115 unsafe fn unlock(ptr: *mut Self::State, _guard_state: &Self::GuardState) {
116 // SAFETY: The safety requirements of this function ensure that `ptr` is valid and that the
117 // caller is the owner of the mutex.
118 unsafe { bindings::mutex_unlock(ptr) };
119 }
120}