1 //! Locks that have the same behaviour as a mutex.
2 //!
3 //! The [`Mutex`] in the root of the crate, can be configured using the `ticket_mutex` feature.
4 //! If it's enabled, [`TicketMutex`] and [`TicketMutexGuard`] will be re-exported as [`Mutex`]
5 //! and [`MutexGuard`], otherwise the [`SpinMutex`] and guard will be re-exported.
6 //!
7 //! `ticket_mutex` is disabled by default.
8 //!
9 //! [`Mutex`]: ../struct.Mutex.html
10 //! [`MutexGuard`]: ../struct.MutexGuard.html
11 //! [`TicketMutex`]: ./struct.TicketMutex.html
12 //! [`TicketMutexGuard`]: ./struct.TicketMutexGuard.html
13 //! [`SpinMutex`]: ./struct.SpinMutex.html
14 //! [`SpinMutexGuard`]: ./struct.SpinMutexGuard.html
15 
16 #[cfg(feature = "spin_mutex")]
17 #[cfg_attr(docsrs, doc(cfg(feature = "spin_mutex")))]
18 pub mod spin;
19 #[cfg(feature = "spin_mutex")]
20 #[cfg_attr(docsrs, doc(cfg(feature = "spin_mutex")))]
21 pub use self::spin::{SpinMutex, SpinMutexGuard};
22 
23 #[cfg(feature = "ticket_mutex")]
24 #[cfg_attr(docsrs, doc(cfg(feature = "ticket_mutex")))]
25 pub mod ticket;
26 #[cfg(feature = "ticket_mutex")]
27 #[cfg_attr(docsrs, doc(cfg(feature = "ticket_mutex")))]
28 pub use self::ticket::{TicketMutex, TicketMutexGuard};
29 
30 #[cfg(feature = "fair_mutex")]
31 #[cfg_attr(docsrs, doc(cfg(feature = "fair_mutex")))]
32 pub mod fair;
33 #[cfg(feature = "fair_mutex")]
34 #[cfg_attr(docsrs, doc(cfg(feature = "fair_mutex")))]
35 pub use self::fair::{FairMutex, FairMutexGuard, Starvation};
36 
37 use crate::{RelaxStrategy, Spin};
38 use core::{
39     fmt,
40     ops::{Deref, DerefMut},
41 };
42 
43 #[cfg(all(not(feature = "spin_mutex"), not(feature = "use_ticket_mutex")))]
44 compile_error!("The `mutex` feature flag was used (perhaps through another feature?) without either `spin_mutex` or `use_ticket_mutex`. One of these is required.");
45 
46 #[cfg(all(not(feature = "use_ticket_mutex"), feature = "spin_mutex"))]
47 type InnerMutex<T, R> = self::spin::SpinMutex<T, R>;
48 #[cfg(all(not(feature = "use_ticket_mutex"), feature = "spin_mutex"))]
49 type InnerMutexGuard<'a, T> = self::spin::SpinMutexGuard<'a, T>;
50 
51 #[cfg(feature = "use_ticket_mutex")]
52 type InnerMutex<T, R> = self::ticket::TicketMutex<T, R>;
53 #[cfg(feature = "use_ticket_mutex")]
54 type InnerMutexGuard<'a, T> = self::ticket::TicketMutexGuard<'a, T>;
55 
56 /// A spin-based lock providing mutually exclusive access to data.
57 ///
58 /// The implementation uses either a ticket mutex or a regular spin mutex depending on whether the `spin_mutex` or
59 /// `ticket_mutex` feature flag is enabled.
60 ///
61 /// # Example
62 ///
63 /// ```
64 /// use spin;
65 ///
66 /// let lock = spin::Mutex::new(0);
67 ///
68 /// // Modify the data
69 /// *lock.lock() = 2;
70 ///
71 /// // Read the data
72 /// let answer = *lock.lock();
73 /// assert_eq!(answer, 2);
74 /// ```
75 ///
76 /// # Thread safety example
77 ///
78 /// ```
79 /// use spin;
80 /// use std::sync::{Arc, Barrier};
81 ///
82 /// let thread_count = 1000;
83 /// let spin_mutex = Arc::new(spin::Mutex::new(0));
84 ///
85 /// // We use a barrier to ensure the readout happens after all writing
86 /// let barrier = Arc::new(Barrier::new(thread_count + 1));
87 ///
88 /// # let mut ts = Vec::new();
89 /// for _ in (0..thread_count) {
90 ///     let my_barrier = barrier.clone();
91 ///     let my_lock = spin_mutex.clone();
92 /// # let t =
93 ///     std::thread::spawn(move || {
94 ///         let mut guard = my_lock.lock();
95 ///         *guard += 1;
96 ///
97 ///         // Release the lock to prevent a deadlock
98 ///         drop(guard);
99 ///         my_barrier.wait();
100 ///     });
101 /// # ts.push(t);
102 /// }
103 ///
104 /// barrier.wait();
105 ///
106 /// let answer = { *spin_mutex.lock() };
107 /// assert_eq!(answer, thread_count);
108 ///
109 /// # for t in ts {
110 /// #     t.join().unwrap();
111 /// # }
112 /// ```
113 pub struct Mutex<T: ?Sized, R = Spin> {
114     inner: InnerMutex<T, R>,
115 }
116 
117 unsafe impl<T: ?Sized + Send, R> Sync for Mutex<T, R> {}
118 unsafe impl<T: ?Sized + Send, R> Send for Mutex<T, R> {}
119 
120 /// A generic guard that will protect some data access and
121 /// uses either a ticket lock or a normal spin mutex.
122 ///
123 /// For more info see [`TicketMutexGuard`] or [`SpinMutexGuard`].
124 ///
125 /// [`TicketMutexGuard`]: ./struct.TicketMutexGuard.html
126 /// [`SpinMutexGuard`]: ./struct.SpinMutexGuard.html
127 pub struct MutexGuard<'a, T: 'a + ?Sized> {
128     inner: InnerMutexGuard<'a, T>,
129 }
130 
131 impl<T, R> Mutex<T, R> {
132     /// Creates a new [`Mutex`] wrapping the supplied data.
133     ///
134     /// # Example
135     ///
136     /// ```
137     /// use spin::Mutex;
138     ///
139     /// static MUTEX: Mutex<()> = Mutex::new(());
140     ///
141     /// fn demo() {
142     ///     let lock = MUTEX.lock();
143     ///     // do something with lock
144     ///     drop(lock);
145     /// }
146     /// ```
147     #[inline(always)]
new(value: T) -> Self148     pub const fn new(value: T) -> Self {
149         Self {
150             inner: InnerMutex::new(value),
151         }
152     }
153 
154     /// Consumes this [`Mutex`] and unwraps the underlying data.
155     ///
156     /// # Example
157     ///
158     /// ```
159     /// let lock = spin::Mutex::new(42);
160     /// assert_eq!(42, lock.into_inner());
161     /// ```
162     #[inline(always)]
into_inner(self) -> T163     pub fn into_inner(self) -> T {
164         self.inner.into_inner()
165     }
166 }
167 
168 impl<T: ?Sized, R: RelaxStrategy> Mutex<T, R> {
169     /// Locks the [`Mutex`] and returns a guard that permits access to the inner data.
170     ///
171     /// The returned value may be dereferenced for data access
172     /// and the lock will be dropped when the guard falls out of scope.
173     ///
174     /// ```
175     /// let lock = spin::Mutex::new(0);
176     /// {
177     ///     let mut data = lock.lock();
178     ///     // The lock is now locked and the data can be accessed
179     ///     *data += 1;
180     ///     // The lock is implicitly dropped at the end of the scope
181     /// }
182     /// ```
183     #[inline(always)]
lock(&self) -> MutexGuard<T>184     pub fn lock(&self) -> MutexGuard<T> {
185         MutexGuard {
186             inner: self.inner.lock(),
187         }
188     }
189 }
190 
191 impl<T: ?Sized, R> Mutex<T, R> {
192     /// Returns `true` if the lock is currently held.
193     ///
194     /// # Safety
195     ///
196     /// This function provides no synchronization guarantees and so its result should be considered 'out of date'
197     /// the instant it is called. Do not use it for synchronization purposes. However, it may be useful as a heuristic.
198     #[inline(always)]
is_locked(&self) -> bool199     pub fn is_locked(&self) -> bool {
200         self.inner.is_locked()
201     }
202 
203     /// Force unlock this [`Mutex`].
204     ///
205     /// # Safety
206     ///
207     /// This is *extremely* unsafe if the lock is not held by the current
208     /// thread. However, this can be useful in some instances for exposing the
209     /// lock to FFI that doesn't know how to deal with RAII.
210     #[inline(always)]
force_unlock(&self)211     pub unsafe fn force_unlock(&self) {
212         self.inner.force_unlock()
213     }
214 
215     /// Try to lock this [`Mutex`], returning a lock guard if successful.
216     ///
217     /// # Example
218     ///
219     /// ```
220     /// let lock = spin::Mutex::new(42);
221     ///
222     /// let maybe_guard = lock.try_lock();
223     /// assert!(maybe_guard.is_some());
224     ///
225     /// // `maybe_guard` is still held, so the second call fails
226     /// let maybe_guard2 = lock.try_lock();
227     /// assert!(maybe_guard2.is_none());
228     /// ```
229     #[inline(always)]
try_lock(&self) -> Option<MutexGuard<T>>230     pub fn try_lock(&self) -> Option<MutexGuard<T>> {
231         self.inner
232             .try_lock()
233             .map(|guard| MutexGuard { inner: guard })
234     }
235 
236     /// Returns a mutable reference to the underlying data.
237     ///
238     /// Since this call borrows the [`Mutex`] mutably, and a mutable reference is guaranteed to be exclusive in Rust,
239     /// no actual locking needs to take place -- the mutable borrow statically guarantees no locks exist. As such,
240     /// this is a 'zero-cost' operation.
241     ///
242     /// # Example
243     ///
244     /// ```
245     /// let mut lock = spin::Mutex::new(0);
246     /// *lock.get_mut() = 10;
247     /// assert_eq!(*lock.lock(), 10);
248     /// ```
249     #[inline(always)]
get_mut(&mut self) -> &mut T250     pub fn get_mut(&mut self) -> &mut T {
251         self.inner.get_mut()
252     }
253 }
254 
255 impl<T: ?Sized + fmt::Debug, R> fmt::Debug for Mutex<T, R> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result256     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
257         fmt::Debug::fmt(&self.inner, f)
258     }
259 }
260 
261 impl<T: ?Sized + Default, R> Default for Mutex<T, R> {
default() -> Self262     fn default() -> Self {
263         Self::new(Default::default())
264     }
265 }
266 
267 impl<T, R> From<T> for Mutex<T, R> {
from(data: T) -> Self268     fn from(data: T) -> Self {
269         Self::new(data)
270     }
271 }
272 
273 impl<'a, T: ?Sized> MutexGuard<'a, T> {
274     /// Leak the lock guard, yielding a mutable reference to the underlying data.
275     ///
276     /// Note that this function will permanently lock the original [`Mutex`].
277     ///
278     /// ```
279     /// let mylock = spin::Mutex::new(0);
280     ///
281     /// let data: &mut i32 = spin::MutexGuard::leak(mylock.lock());
282     ///
283     /// *data = 1;
284     /// assert_eq!(*data, 1);
285     /// ```
286     #[inline(always)]
leak(this: Self) -> &'a mut T287     pub fn leak(this: Self) -> &'a mut T {
288         InnerMutexGuard::leak(this.inner)
289     }
290 }
291 
292 impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'a, T> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result293     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
294         fmt::Debug::fmt(&**self, f)
295     }
296 }
297 
298 impl<'a, T: ?Sized + fmt::Display> fmt::Display for MutexGuard<'a, T> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result299     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
300         fmt::Display::fmt(&**self, f)
301     }
302 }
303 
304 impl<'a, T: ?Sized> Deref for MutexGuard<'a, T> {
305     type Target = T;
deref(&self) -> &T306     fn deref(&self) -> &T {
307         &*self.inner
308     }
309 }
310 
311 impl<'a, T: ?Sized> DerefMut for MutexGuard<'a, T> {
deref_mut(&mut self) -> &mut T312     fn deref_mut(&mut self) -> &mut T {
313         &mut *self.inner
314     }
315 }
316 
317 #[cfg(feature = "lock_api")]
318 unsafe impl<R: RelaxStrategy> lock_api_crate::RawMutex for Mutex<(), R> {
319     type GuardMarker = lock_api_crate::GuardSend;
320 
321     const INIT: Self = Self::new(());
322 
lock(&self)323     fn lock(&self) {
324         // Prevent guard destructor running
325         core::mem::forget(Self::lock(self));
326     }
327 
try_lock(&self) -> bool328     fn try_lock(&self) -> bool {
329         // Prevent guard destructor running
330         Self::try_lock(self).map(core::mem::forget).is_some()
331     }
332 
unlock(&self)333     unsafe fn unlock(&self) {
334         self.force_unlock();
335     }
336 
is_locked(&self) -> bool337     fn is_locked(&self) -> bool {
338         self.inner.is_locked()
339     }
340 }
341