mutex.rs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. mod guard;
  2. mod wait;
  3. use core::{
  4. cell::UnsafeCell,
  5. sync::atomic::{AtomicBool, Ordering},
  6. };
  7. pub use guard::MutexGuard;
  8. pub use wait::Wait;
  9. #[derive(Debug, Default)]
  10. pub struct Mutex<T, W>
  11. where
  12. T: ?Sized,
  13. W: Wait,
  14. {
  15. locked: AtomicBool,
  16. wait: W,
  17. value: UnsafeCell<T>,
  18. }
  19. impl<T, W> Mutex<T, W>
  20. where
  21. W: Wait,
  22. {
  23. pub const fn new(value: T, wait: W) -> Self {
  24. Self {
  25. locked: AtomicBool::new(false),
  26. wait,
  27. value: UnsafeCell::new(value),
  28. }
  29. }
  30. }
  31. impl<T, W> Mutex<T, W>
  32. where
  33. T: ?Sized,
  34. W: Wait,
  35. {
  36. /// # Safety
  37. /// This function is unsafe because the caller MUST ensure that we've got the
  38. /// exclusive access before calling this function.
  39. unsafe fn get_lock(&self) -> MutexGuard<'_, T, W> {
  40. MutexGuard {
  41. lock: self,
  42. // SAFETY: We are holding the lock, so we can safely access the value.
  43. value: unsafe { &mut *self.value.get() },
  44. }
  45. }
  46. pub fn try_lock(&self) -> Option<MutexGuard<'_, T, W>> {
  47. self.locked
  48. .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
  49. .ok()
  50. .map(|_| unsafe { self.get_lock() })
  51. }
  52. fn try_lock_weak(&self) -> Option<MutexGuard<'_, T, W>> {
  53. self.locked
  54. .compare_exchange_weak(false, true, Ordering::Acquire, Ordering::Relaxed)
  55. .ok()
  56. .map(|_| unsafe { self.get_lock() })
  57. }
  58. #[cold]
  59. fn lock_slow_path(&self) -> MutexGuard<'_, T, W> {
  60. loop {
  61. if let Some(guard) = self.try_lock_weak() {
  62. return guard;
  63. }
  64. self.wait.wait(|| !self.locked.load(Ordering::Relaxed));
  65. }
  66. }
  67. pub fn lock(&self) -> MutexGuard<'_, T, W> {
  68. if let Some(guard) = self.try_lock() {
  69. // Quick path
  70. guard
  71. } else {
  72. self.lock_slow_path()
  73. }
  74. }
  75. pub fn get_mut(&mut self) -> &mut T {
  76. // SAFETY: The exclusive access to the lock is guaranteed by the borrow checker.
  77. unsafe { &mut *self.value.get() }
  78. }
  79. }
  80. impl<T, W> Clone for Mutex<T, W>
  81. where
  82. T: ?Sized + Clone,
  83. W: Wait,
  84. {
  85. fn clone(&self) -> Self {
  86. Self::new(self.lock().clone(), W::new())
  87. }
  88. }
  89. // SAFETY: As long as the value protected by the lock is able to be shared between threads,
  90. // we can send the lock between threads.
  91. unsafe impl<T, W> Send for Mutex<T, W>
  92. where
  93. T: ?Sized + Send,
  94. W: Wait,
  95. {
  96. }
  97. // SAFETY: `RwLock` can provide exclusive access to the value it protects, so it is safe to
  98. // implement `Sync` for it as long as the protected value is `Send`.
  99. unsafe impl<T, W> Sync for Mutex<T, W>
  100. where
  101. T: ?Sized + Send,
  102. W: Wait,
  103. {
  104. }