mutex.rs 3.6 KB

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