1 //! A lock that provides data access to either one writer or many readers.
2 
3 use crate::{
4     atomic::{AtomicUsize, Ordering},
5     RelaxStrategy, Spin,
6 };
7 use core::{
8     cell::UnsafeCell,
9     fmt,
10     marker::PhantomData,
11     mem,
12     mem::ManuallyDrop,
13     ops::{Deref, DerefMut},
14 };
15 
16 /// A lock that provides data access to either one writer or many readers.
17 ///
18 /// This lock behaves in a similar manner to its namesake `std::sync::RwLock` but uses
19 /// spinning for synchronisation instead. Unlike its namespace, this lock does not
20 /// track lock poisoning.
21 ///
22 /// This type of lock allows a number of readers or at most one writer at any
23 /// point in time. The write portion of this lock typically allows modification
24 /// of the underlying data (exclusive access) and the read portion of this lock
25 /// typically allows for read-only access (shared access).
26 ///
27 /// The type parameter `T` represents the data that this lock protects. It is
28 /// required that `T` satisfies `Send` to be shared across tasks and `Sync` to
29 /// allow concurrent access through readers. The RAII guards returned from the
30 /// locking methods implement `Deref` (and `DerefMut` for the `write` methods)
31 /// to allow access to the contained of the lock.
32 ///
33 /// An [`RwLockUpgradableGuard`](RwLockUpgradableGuard) can be upgraded to a
34 /// writable guard through the [`RwLockUpgradableGuard::upgrade`](RwLockUpgradableGuard::upgrade)
35 /// [`RwLockUpgradableGuard::try_upgrade`](RwLockUpgradableGuard::try_upgrade) functions.
36 /// Writable or upgradeable guards can be downgraded through their respective `downgrade`
37 /// functions.
38 ///
39 /// Based on Facebook's
40 /// [`folly/RWSpinLock.h`](https://github.com/facebook/folly/blob/a0394d84f2d5c3e50ebfd0566f9d3acb52cfab5a/folly/synchronization/RWSpinLock.h).
41 /// This implementation is unfair to writers - if the lock always has readers, then no writers will
42 /// ever get a chance. Using an upgradeable lock guard can *somewhat* alleviate this issue as no
43 /// new readers are allowed when an upgradeable guard is held, but upgradeable guards can be taken
44 /// when there are existing readers. However if the lock is that highly contended and writes are
45 /// crucial then this implementation may be a poor choice.
46 ///
47 /// # Examples
48 ///
49 /// ```
50 /// use spin;
51 ///
52 /// let lock = spin::RwLock::new(5);
53 ///
54 /// // many reader locks can be held at once
55 /// {
56 ///     let r1 = lock.read();
57 ///     let r2 = lock.read();
58 ///     assert_eq!(*r1, 5);
59 ///     assert_eq!(*r2, 5);
60 /// } // read locks are dropped at this point
61 ///
62 /// // only one write lock may be held, however
63 /// {
64 ///     let mut w = lock.write();
65 ///     *w += 1;
66 ///     assert_eq!(*w, 6);
67 /// } // write lock is dropped here
68 /// ```
69 pub struct RwLock<T: ?Sized, R = Spin> {
70     phantom: PhantomData<R>,
71     lock: AtomicUsize,
72     data: UnsafeCell<T>,
73 }
74 
75 const READER: usize = 1 << 2;
76 const UPGRADED: usize = 1 << 1;
77 const WRITER: usize = 1;
78 
79 /// A guard that provides immutable data access.
80 ///
81 /// When the guard falls out of scope it will decrement the read count,
82 /// potentially releasing the lock.
83 pub struct RwLockReadGuard<'a, T: 'a + ?Sized> {
84     lock: &'a AtomicUsize,
85     data: *const T,
86 }
87 
88 /// A guard that provides mutable data access.
89 ///
90 /// When the guard falls out of scope it will release the lock.
91 pub struct RwLockWriteGuard<'a, T: 'a + ?Sized, R = Spin> {
92     phantom: PhantomData<R>,
93     inner: &'a RwLock<T, R>,
94     data: *mut T,
95 }
96 
97 /// A guard that provides immutable data access but can be upgraded to [`RwLockWriteGuard`].
98 ///
99 /// No writers or other upgradeable guards can exist while this is in scope. New reader
100 /// creation is prevented (to alleviate writer starvation) but there may be existing readers
101 /// when the lock is acquired.
102 ///
103 /// When the guard falls out of scope it will release the lock.
104 pub struct RwLockUpgradableGuard<'a, T: 'a + ?Sized, R = Spin> {
105     phantom: PhantomData<R>,
106     inner: &'a RwLock<T, R>,
107     data: *const T,
108 }
109 
110 // Same unsafe impls as `std::sync::RwLock`
111 unsafe impl<T: ?Sized + Send, R> Send for RwLock<T, R> {}
112 unsafe impl<T: ?Sized + Send + Sync, R> Sync for RwLock<T, R> {}
113 
114 unsafe impl<T: ?Sized + Send + Sync, R> Send for RwLockWriteGuard<'_, T, R> {}
115 unsafe impl<T: ?Sized + Send + Sync, R> Sync for RwLockWriteGuard<'_, T, R> {}
116 
117 unsafe impl<T: ?Sized + Sync> Send for RwLockReadGuard<'_, T> {}
118 unsafe impl<T: ?Sized + Sync> Sync for RwLockReadGuard<'_, T> {}
119 
120 unsafe impl<T: ?Sized + Send + Sync, R> Send for RwLockUpgradableGuard<'_, T, R> {}
121 unsafe impl<T: ?Sized + Send + Sync, R> Sync for RwLockUpgradableGuard<'_, T, R> {}
122 
123 impl<T, R> RwLock<T, R> {
124     /// Creates a new spinlock wrapping the supplied data.
125     ///
126     /// May be used statically:
127     ///
128     /// ```
129     /// use spin;
130     ///
131     /// static RW_LOCK: spin::RwLock<()> = spin::RwLock::new(());
132     ///
133     /// fn demo() {
134     ///     let lock = RW_LOCK.read();
135     ///     // do something with lock
136     ///     drop(lock);
137     /// }
138     /// ```
139     #[inline]
new(data: T) -> Self140     pub const fn new(data: T) -> Self {
141         RwLock {
142             phantom: PhantomData,
143             lock: AtomicUsize::new(0),
144             data: UnsafeCell::new(data),
145         }
146     }
147 
148     /// Consumes this `RwLock`, returning the underlying data.
149     #[inline]
into_inner(self) -> T150     pub fn into_inner(self) -> T {
151         // We know statically that there are no outstanding references to
152         // `self` so there's no need to lock.
153         let RwLock { data, .. } = self;
154         data.into_inner()
155     }
156     /// Returns a mutable pointer to the underying data.
157     ///
158     /// This is mostly meant to be used for applications which require manual unlocking, but where
159     /// storing both the lock and the pointer to the inner data gets inefficient.
160     ///
161     /// While this is safe, writing to the data is undefined behavior unless the current thread has
162     /// acquired a write lock, and reading requires either a read or write lock.
163     ///
164     /// # Example
165     /// ```
166     /// let lock = spin::RwLock::new(42);
167     ///
168     /// unsafe {
169     ///     core::mem::forget(lock.write());
170     ///
171     ///     assert_eq!(lock.as_mut_ptr().read(), 42);
172     ///     lock.as_mut_ptr().write(58);
173     ///
174     ///     lock.force_write_unlock();
175     /// }
176     ///
177     /// assert_eq!(*lock.read(), 58);
178     ///
179     /// ```
180     #[inline(always)]
as_mut_ptr(&self) -> *mut T181     pub fn as_mut_ptr(&self) -> *mut T {
182         self.data.get()
183     }
184 }
185 
186 impl<T: ?Sized, R: RelaxStrategy> RwLock<T, R> {
187     /// Locks this rwlock with shared read access, blocking the current thread
188     /// until it can be acquired.
189     ///
190     /// The calling thread will be blocked until there are no more writers which
191     /// hold the lock. There may be other readers currently inside the lock when
192     /// this method returns. This method does not provide any guarantees with
193     /// respect to the ordering of whether contentious readers or writers will
194     /// acquire the lock first.
195     ///
196     /// Returns an RAII guard which will release this thread's shared access
197     /// once it is dropped.
198     ///
199     /// ```
200     /// let mylock = spin::RwLock::new(0);
201     /// {
202     ///     let mut data = mylock.read();
203     ///     // The lock is now locked and the data can be read
204     ///     println!("{}", *data);
205     ///     // The lock is dropped
206     /// }
207     /// ```
208     #[inline]
read(&self) -> RwLockReadGuard<T>209     pub fn read(&self) -> RwLockReadGuard<T> {
210         loop {
211             match self.try_read() {
212                 Some(guard) => return guard,
213                 None => R::relax(),
214             }
215         }
216     }
217 
218     /// Lock this rwlock with exclusive write access, blocking the current
219     /// thread until it can be acquired.
220     ///
221     /// This function will not return while other writers or other readers
222     /// currently have access to the lock.
223     ///
224     /// Returns an RAII guard which will drop the write access of this rwlock
225     /// when dropped.
226     ///
227     /// ```
228     /// let mylock = spin::RwLock::new(0);
229     /// {
230     ///     let mut data = mylock.write();
231     ///     // The lock is now locked and the data can be written
232     ///     *data += 1;
233     ///     // The lock is dropped
234     /// }
235     /// ```
236     #[inline]
write(&self) -> RwLockWriteGuard<T, R>237     pub fn write(&self) -> RwLockWriteGuard<T, R> {
238         loop {
239             match self.try_write_internal(false) {
240                 Some(guard) => return guard,
241                 None => R::relax(),
242             }
243         }
244     }
245 
246     /// Obtain a readable lock guard that can later be upgraded to a writable lock guard.
247     /// Upgrades can be done through the [`RwLockUpgradableGuard::upgrade`](RwLockUpgradableGuard::upgrade) method.
248     #[inline]
upgradeable_read(&self) -> RwLockUpgradableGuard<T, R>249     pub fn upgradeable_read(&self) -> RwLockUpgradableGuard<T, R> {
250         loop {
251             match self.try_upgradeable_read() {
252                 Some(guard) => return guard,
253                 None => R::relax(),
254             }
255         }
256     }
257 }
258 
259 impl<T: ?Sized, R> RwLock<T, R> {
260     // Acquire a read lock, returning the new lock value.
acquire_reader(&self) -> usize261     fn acquire_reader(&self) -> usize {
262         // An arbitrary cap that allows us to catch overflows long before they happen
263         const MAX_READERS: usize = core::usize::MAX / READER / 2;
264 
265         let value = self.lock.fetch_add(READER, Ordering::Acquire);
266 
267         if value > MAX_READERS * READER {
268             self.lock.fetch_sub(READER, Ordering::Relaxed);
269             panic!("Too many lock readers, cannot safely proceed");
270         } else {
271             value
272         }
273     }
274 
275     /// Attempt to acquire this lock with shared read access.
276     ///
277     /// This function will never block and will return immediately if `read`
278     /// would otherwise succeed. Returns `Some` of an RAII guard which will
279     /// release the shared access of this thread when dropped, or `None` if the
280     /// access could not be granted. This method does not provide any
281     /// guarantees with respect to the ordering of whether contentious readers
282     /// or writers will acquire the lock first.
283     ///
284     /// ```
285     /// let mylock = spin::RwLock::new(0);
286     /// {
287     ///     match mylock.try_read() {
288     ///         Some(data) => {
289     ///             // The lock is now locked and the data can be read
290     ///             println!("{}", *data);
291     ///             // The lock is dropped
292     ///         },
293     ///         None => (), // no cigar
294     ///     };
295     /// }
296     /// ```
297     #[inline]
try_read(&self) -> Option<RwLockReadGuard<T>>298     pub fn try_read(&self) -> Option<RwLockReadGuard<T>> {
299         let value = self.acquire_reader();
300 
301         // We check the UPGRADED bit here so that new readers are prevented when an UPGRADED lock is held.
302         // This helps reduce writer starvation.
303         if value & (WRITER | UPGRADED) != 0 {
304             // Lock is taken, undo.
305             self.lock.fetch_sub(READER, Ordering::Release);
306             None
307         } else {
308             Some(RwLockReadGuard {
309                 lock: &self.lock,
310                 data: unsafe { &*self.data.get() },
311             })
312         }
313     }
314 
315     /// Return the number of readers that currently hold the lock (including upgradable readers).
316     ///
317     /// # Safety
318     ///
319     /// This function provides no synchronization guarantees and so its result should be considered 'out of date'
320     /// the instant it is called. Do not use it for synchronization purposes. However, it may be useful as a heuristic.
reader_count(&self) -> usize321     pub fn reader_count(&self) -> usize {
322         let state = self.lock.load(Ordering::Relaxed);
323         state / READER + (state & UPGRADED) / UPGRADED
324     }
325 
326     /// Return the number of writers that currently hold the lock.
327     ///
328     /// Because [`RwLock`] guarantees exclusive mutable access, this function may only return either `0` or `1`.
329     ///
330     /// # Safety
331     ///
332     /// This function provides no synchronization guarantees and so its result should be considered 'out of date'
333     /// the instant it is called. Do not use it for synchronization purposes. However, it may be useful as a heuristic.
writer_count(&self) -> usize334     pub fn writer_count(&self) -> usize {
335         (self.lock.load(Ordering::Relaxed) & WRITER) / WRITER
336     }
337 
338     /// Force decrement the reader count.
339     ///
340     /// # Safety
341     ///
342     /// This is *extremely* unsafe if there are outstanding `RwLockReadGuard`s
343     /// live, or if called more times than `read` has been called, but can be
344     /// useful in FFI contexts where the caller doesn't know how to deal with
345     /// RAII. The underlying atomic operation uses `Ordering::Release`.
346     #[inline]
force_read_decrement(&self)347     pub unsafe fn force_read_decrement(&self) {
348         debug_assert!(self.lock.load(Ordering::Relaxed) & !WRITER > 0);
349         self.lock.fetch_sub(READER, Ordering::Release);
350     }
351 
352     /// Force unlock exclusive write access.
353     ///
354     /// # Safety
355     ///
356     /// This is *extremely* unsafe if there are outstanding `RwLockWriteGuard`s
357     /// live, or if called when there are current readers, but can be useful in
358     /// FFI contexts where the caller doesn't know how to deal with RAII. The
359     /// underlying atomic operation uses `Ordering::Release`.
360     #[inline]
force_write_unlock(&self)361     pub unsafe fn force_write_unlock(&self) {
362         debug_assert_eq!(self.lock.load(Ordering::Relaxed) & !(WRITER | UPGRADED), 0);
363         self.lock.fetch_and(!(WRITER | UPGRADED), Ordering::Release);
364     }
365 
366     #[inline(always)]
try_write_internal(&self, strong: bool) -> Option<RwLockWriteGuard<T, R>>367     fn try_write_internal(&self, strong: bool) -> Option<RwLockWriteGuard<T, R>> {
368         if compare_exchange(
369             &self.lock,
370             0,
371             WRITER,
372             Ordering::Acquire,
373             Ordering::Relaxed,
374             strong,
375         )
376         .is_ok()
377         {
378             Some(RwLockWriteGuard {
379                 phantom: PhantomData,
380                 inner: self,
381                 data: unsafe { &mut *self.data.get() },
382             })
383         } else {
384             None
385         }
386     }
387 
388     /// Attempt to lock this rwlock with exclusive write access.
389     ///
390     /// This function does not ever block, and it will return `None` if a call
391     /// to `write` would otherwise block. If successful, an RAII guard is
392     /// returned.
393     ///
394     /// ```
395     /// let mylock = spin::RwLock::new(0);
396     /// {
397     ///     match mylock.try_write() {
398     ///         Some(mut data) => {
399     ///             // The lock is now locked and the data can be written
400     ///             *data += 1;
401     ///             // The lock is implicitly dropped
402     ///         },
403     ///         None => (), // no cigar
404     ///     };
405     /// }
406     /// ```
407     #[inline]
try_write(&self) -> Option<RwLockWriteGuard<T, R>>408     pub fn try_write(&self) -> Option<RwLockWriteGuard<T, R>> {
409         self.try_write_internal(true)
410     }
411 
412     /// Tries to obtain an upgradeable lock guard.
413     #[inline]
try_upgradeable_read(&self) -> Option<RwLockUpgradableGuard<T, R>>414     pub fn try_upgradeable_read(&self) -> Option<RwLockUpgradableGuard<T, R>> {
415         if self.lock.fetch_or(UPGRADED, Ordering::Acquire) & (WRITER | UPGRADED) == 0 {
416             Some(RwLockUpgradableGuard {
417                 phantom: PhantomData,
418                 inner: self,
419                 data: unsafe { &*self.data.get() },
420             })
421         } else {
422             // We can't unflip the UPGRADED bit back just yet as there is another upgradeable or write lock.
423             // When they unlock, they will clear the bit.
424             None
425         }
426     }
427 
428     /// Returns a mutable reference to the underlying data.
429     ///
430     /// Since this call borrows the `RwLock` mutably, no actual locking needs to
431     /// take place -- the mutable borrow statically guarantees no locks exist.
432     ///
433     /// # Examples
434     ///
435     /// ```
436     /// let mut lock = spin::RwLock::new(0);
437     /// *lock.get_mut() = 10;
438     /// assert_eq!(*lock.read(), 10);
439     /// ```
get_mut(&mut self) -> &mut T440     pub fn get_mut(&mut self) -> &mut T {
441         // We know statically that there are no other references to `self`, so
442         // there's no need to lock the inner lock.
443         unsafe { &mut *self.data.get() }
444     }
445 }
446 
447 impl<T: ?Sized + fmt::Debug, R> fmt::Debug for RwLock<T, R> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result448     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
449         match self.try_read() {
450             Some(guard) => write!(f, "RwLock {{ data: ")
451                 .and_then(|()| (&*guard).fmt(f))
452                 .and_then(|()| write!(f, "}}")),
453             None => write!(f, "RwLock {{ <locked> }}"),
454         }
455     }
456 }
457 
458 impl<T: ?Sized + Default, R> Default for RwLock<T, R> {
default() -> Self459     fn default() -> Self {
460         Self::new(Default::default())
461     }
462 }
463 
464 impl<T, R> From<T> for RwLock<T, R> {
from(data: T) -> Self465     fn from(data: T) -> Self {
466         Self::new(data)
467     }
468 }
469 
470 impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> {
471     /// Leak the lock guard, yielding a reference to the underlying data.
472     ///
473     /// Note that this function will permanently lock the original lock for all but reading locks.
474     ///
475     /// ```
476     /// let mylock = spin::RwLock::new(0);
477     ///
478     /// let data: &i32 = spin::RwLockReadGuard::leak(mylock.read());
479     ///
480     /// assert_eq!(*data, 0);
481     /// ```
482     #[inline]
leak(this: Self) -> &'rwlock T483     pub fn leak(this: Self) -> &'rwlock T {
484         let this = ManuallyDrop::new(this);
485         // Safety: We know statically that only we are referencing data
486         unsafe { &*this.data }
487     }
488 }
489 
490 impl<'rwlock, T: ?Sized + fmt::Debug> fmt::Debug for RwLockReadGuard<'rwlock, T> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result491     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
492         fmt::Debug::fmt(&**self, f)
493     }
494 }
495 
496 impl<'rwlock, T: ?Sized + fmt::Display> fmt::Display for RwLockReadGuard<'rwlock, T> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result497     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
498         fmt::Display::fmt(&**self, f)
499     }
500 }
501 
502 impl<'rwlock, T: ?Sized, R: RelaxStrategy> RwLockUpgradableGuard<'rwlock, T, R> {
503     /// Upgrades an upgradeable lock guard to a writable lock guard.
504     ///
505     /// ```
506     /// let mylock = spin::RwLock::new(0);
507     ///
508     /// let upgradeable = mylock.upgradeable_read(); // Readable, but not yet writable
509     /// let writable = upgradeable.upgrade();
510     /// ```
511     #[inline]
upgrade(mut self) -> RwLockWriteGuard<'rwlock, T, R>512     pub fn upgrade(mut self) -> RwLockWriteGuard<'rwlock, T, R> {
513         loop {
514             self = match self.try_upgrade_internal(false) {
515                 Ok(guard) => return guard,
516                 Err(e) => e,
517             };
518 
519             R::relax();
520         }
521     }
522 }
523 
524 impl<'rwlock, T: ?Sized, R> RwLockUpgradableGuard<'rwlock, T, R> {
525     #[inline(always)]
try_upgrade_internal(self, strong: bool) -> Result<RwLockWriteGuard<'rwlock, T, R>, Self>526     fn try_upgrade_internal(self, strong: bool) -> Result<RwLockWriteGuard<'rwlock, T, R>, Self> {
527         if compare_exchange(
528             &self.inner.lock,
529             UPGRADED,
530             WRITER,
531             Ordering::Acquire,
532             Ordering::Relaxed,
533             strong,
534         )
535         .is_ok()
536         {
537             let inner = self.inner;
538 
539             // Forget the old guard so its destructor doesn't run (before mutably aliasing data below)
540             mem::forget(self);
541 
542             // Upgrade successful
543             Ok(RwLockWriteGuard {
544                 phantom: PhantomData,
545                 inner,
546                 data: unsafe { &mut *inner.data.get() },
547             })
548         } else {
549             Err(self)
550         }
551     }
552 
553     /// Tries to upgrade an upgradeable lock guard to a writable lock guard.
554     ///
555     /// ```
556     /// let mylock = spin::RwLock::new(0);
557     /// let upgradeable = mylock.upgradeable_read(); // Readable, but not yet writable
558     ///
559     /// match upgradeable.try_upgrade() {
560     ///     Ok(writable) => /* upgrade successful - use writable lock guard */ (),
561     ///     Err(upgradeable) => /* upgrade unsuccessful */ (),
562     /// };
563     /// ```
564     #[inline]
try_upgrade(self) -> Result<RwLockWriteGuard<'rwlock, T, R>, Self>565     pub fn try_upgrade(self) -> Result<RwLockWriteGuard<'rwlock, T, R>, Self> {
566         self.try_upgrade_internal(true)
567     }
568 
569     #[inline]
570     /// Downgrades the upgradeable lock guard to a readable, shared lock guard. Cannot fail and is guaranteed not to spin.
571     ///
572     /// ```
573     /// let mylock = spin::RwLock::new(1);
574     ///
575     /// let upgradeable = mylock.upgradeable_read();
576     /// assert!(mylock.try_read().is_none());
577     /// assert_eq!(*upgradeable, 1);
578     ///
579     /// let readable = upgradeable.downgrade(); // This is guaranteed not to spin
580     /// assert!(mylock.try_read().is_some());
581     /// assert_eq!(*readable, 1);
582     /// ```
downgrade(self) -> RwLockReadGuard<'rwlock, T>583     pub fn downgrade(self) -> RwLockReadGuard<'rwlock, T> {
584         // Reserve the read guard for ourselves
585         self.inner.acquire_reader();
586 
587         let inner = self.inner;
588 
589         // Dropping self removes the UPGRADED bit
590         mem::drop(self);
591 
592         RwLockReadGuard {
593             lock: &inner.lock,
594             data: unsafe { &*inner.data.get() },
595         }
596     }
597 
598     /// Leak the lock guard, yielding a reference to the underlying data.
599     ///
600     /// Note that this function will permanently lock the original lock.
601     ///
602     /// ```
603     /// let mylock = spin::RwLock::new(0);
604     ///
605     /// let data: &i32 = spin::RwLockUpgradableGuard::leak(mylock.upgradeable_read());
606     ///
607     /// assert_eq!(*data, 0);
608     /// ```
609     #[inline]
leak(this: Self) -> &'rwlock T610     pub fn leak(this: Self) -> &'rwlock T {
611         let this = ManuallyDrop::new(this);
612         // Safety: We know statically that only we are referencing data
613         unsafe { &*this.data }
614     }
615 }
616 
617 impl<'rwlock, T: ?Sized + fmt::Debug, R> fmt::Debug for RwLockUpgradableGuard<'rwlock, T, R> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result618     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
619         fmt::Debug::fmt(&**self, f)
620     }
621 }
622 
623 impl<'rwlock, T: ?Sized + fmt::Display, R> fmt::Display for RwLockUpgradableGuard<'rwlock, T, R> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result624     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
625         fmt::Display::fmt(&**self, f)
626     }
627 }
628 
629 impl<'rwlock, T: ?Sized, R> RwLockWriteGuard<'rwlock, T, R> {
630     /// Downgrades the writable lock guard to a readable, shared lock guard. Cannot fail and is guaranteed not to spin.
631     ///
632     /// ```
633     /// let mylock = spin::RwLock::new(0);
634     ///
635     /// let mut writable = mylock.write();
636     /// *writable = 1;
637     ///
638     /// let readable = writable.downgrade(); // This is guaranteed not to spin
639     /// # let readable_2 = mylock.try_read().unwrap();
640     /// assert_eq!(*readable, 1);
641     /// ```
642     #[inline]
downgrade(self) -> RwLockReadGuard<'rwlock, T>643     pub fn downgrade(self) -> RwLockReadGuard<'rwlock, T> {
644         // Reserve the read guard for ourselves
645         self.inner.acquire_reader();
646 
647         let inner = self.inner;
648 
649         // Dropping self removes the UPGRADED bit
650         mem::drop(self);
651 
652         RwLockReadGuard {
653             lock: &inner.lock,
654             data: unsafe { &*inner.data.get() },
655         }
656     }
657 
658     /// Downgrades the writable lock guard to an upgradable, shared lock guard. Cannot fail and is guaranteed not to spin.
659     ///
660     /// ```
661     /// let mylock = spin::RwLock::new(0);
662     ///
663     /// let mut writable = mylock.write();
664     /// *writable = 1;
665     ///
666     /// let readable = writable.downgrade_to_upgradeable(); // This is guaranteed not to spin
667     /// assert_eq!(*readable, 1);
668     /// ```
669     #[inline]
downgrade_to_upgradeable(self) -> RwLockUpgradableGuard<'rwlock, T, R>670     pub fn downgrade_to_upgradeable(self) -> RwLockUpgradableGuard<'rwlock, T, R> {
671         debug_assert_eq!(
672             self.inner.lock.load(Ordering::Acquire) & (WRITER | UPGRADED),
673             WRITER
674         );
675 
676         // Reserve the read guard for ourselves
677         self.inner.lock.store(UPGRADED, Ordering::Release);
678 
679         let inner = self.inner;
680 
681         // Dropping self removes the UPGRADED bit
682         mem::forget(self);
683 
684         RwLockUpgradableGuard {
685             phantom: PhantomData,
686             inner,
687             data: unsafe { &*inner.data.get() },
688         }
689     }
690 
691     /// Leak the lock guard, yielding a mutable reference to the underlying data.
692     ///
693     /// Note that this function will permanently lock the original lock.
694     ///
695     /// ```
696     /// let mylock = spin::RwLock::new(0);
697     ///
698     /// let data: &mut i32 = spin::RwLockWriteGuard::leak(mylock.write());
699     ///
700     /// *data = 1;
701     /// assert_eq!(*data, 1);
702     /// ```
703     #[inline]
leak(this: Self) -> &'rwlock mut T704     pub fn leak(this: Self) -> &'rwlock mut T {
705         let mut this = ManuallyDrop::new(this);
706         // Safety: We know statically that only we are referencing data
707         unsafe { &mut *this.data }
708     }
709 }
710 
711 impl<'rwlock, T: ?Sized + fmt::Debug, R> fmt::Debug for RwLockWriteGuard<'rwlock, T, R> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result712     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
713         fmt::Debug::fmt(&**self, f)
714     }
715 }
716 
717 impl<'rwlock, T: ?Sized + fmt::Display, R> fmt::Display for RwLockWriteGuard<'rwlock, T, R> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result718     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
719         fmt::Display::fmt(&**self, f)
720     }
721 }
722 
723 impl<'rwlock, T: ?Sized> Deref for RwLockReadGuard<'rwlock, T> {
724     type Target = T;
725 
deref(&self) -> &T726     fn deref(&self) -> &T {
727         // Safety: We know statically that only we are referencing data
728         unsafe { &*self.data }
729     }
730 }
731 
732 impl<'rwlock, T: ?Sized, R> Deref for RwLockUpgradableGuard<'rwlock, T, R> {
733     type Target = T;
734 
deref(&self) -> &T735     fn deref(&self) -> &T {
736         // Safety: We know statically that only we are referencing data
737         unsafe { &*self.data }
738     }
739 }
740 
741 impl<'rwlock, T: ?Sized, R> Deref for RwLockWriteGuard<'rwlock, T, R> {
742     type Target = T;
743 
deref(&self) -> &T744     fn deref(&self) -> &T {
745         // Safety: We know statically that only we are referencing data
746         unsafe { &*self.data }
747     }
748 }
749 
750 impl<'rwlock, T: ?Sized, R> DerefMut for RwLockWriteGuard<'rwlock, T, R> {
deref_mut(&mut self) -> &mut T751     fn deref_mut(&mut self) -> &mut T {
752         // Safety: We know statically that only we are referencing data
753         unsafe { &mut *self.data }
754     }
755 }
756 
757 impl<'rwlock, T: ?Sized> Drop for RwLockReadGuard<'rwlock, T> {
drop(&mut self)758     fn drop(&mut self) {
759         debug_assert!(self.lock.load(Ordering::Relaxed) & !(WRITER | UPGRADED) > 0);
760         self.lock.fetch_sub(READER, Ordering::Release);
761     }
762 }
763 
764 impl<'rwlock, T: ?Sized, R> Drop for RwLockUpgradableGuard<'rwlock, T, R> {
drop(&mut self)765     fn drop(&mut self) {
766         debug_assert_eq!(
767             self.inner.lock.load(Ordering::Relaxed) & (WRITER | UPGRADED),
768             UPGRADED
769         );
770         self.inner.lock.fetch_sub(UPGRADED, Ordering::AcqRel);
771     }
772 }
773 
774 impl<'rwlock, T: ?Sized, R> Drop for RwLockWriteGuard<'rwlock, T, R> {
drop(&mut self)775     fn drop(&mut self) {
776         debug_assert_eq!(self.inner.lock.load(Ordering::Relaxed) & WRITER, WRITER);
777 
778         // Writer is responsible for clearing both WRITER and UPGRADED bits.
779         // The UPGRADED bit may be set if an upgradeable lock attempts an upgrade while this lock is held.
780         self.inner
781             .lock
782             .fetch_and(!(WRITER | UPGRADED), Ordering::Release);
783     }
784 }
785 
786 #[inline(always)]
compare_exchange( atomic: &AtomicUsize, current: usize, new: usize, success: Ordering, failure: Ordering, strong: bool, ) -> Result<usize, usize>787 fn compare_exchange(
788     atomic: &AtomicUsize,
789     current: usize,
790     new: usize,
791     success: Ordering,
792     failure: Ordering,
793     strong: bool,
794 ) -> Result<usize, usize> {
795     if strong {
796         atomic.compare_exchange(current, new, success, failure)
797     } else {
798         atomic.compare_exchange_weak(current, new, success, failure)
799     }
800 }
801 
802 #[cfg(feature = "lock_api")]
803 unsafe impl<R: RelaxStrategy> lock_api_crate::RawRwLock for RwLock<(), R> {
804     type GuardMarker = lock_api_crate::GuardSend;
805 
806     const INIT: Self = Self::new(());
807 
808     #[inline(always)]
lock_exclusive(&self)809     fn lock_exclusive(&self) {
810         // Prevent guard destructor running
811         core::mem::forget(self.write());
812     }
813 
814     #[inline(always)]
try_lock_exclusive(&self) -> bool815     fn try_lock_exclusive(&self) -> bool {
816         // Prevent guard destructor running
817         self.try_write().map(|g| core::mem::forget(g)).is_some()
818     }
819 
820     #[inline(always)]
unlock_exclusive(&self)821     unsafe fn unlock_exclusive(&self) {
822         drop(RwLockWriteGuard {
823             inner: self,
824             data: &mut (),
825             phantom: PhantomData,
826         });
827     }
828 
829     #[inline(always)]
lock_shared(&self)830     fn lock_shared(&self) {
831         // Prevent guard destructor running
832         core::mem::forget(self.read());
833     }
834 
835     #[inline(always)]
try_lock_shared(&self) -> bool836     fn try_lock_shared(&self) -> bool {
837         // Prevent guard destructor running
838         self.try_read().map(|g| core::mem::forget(g)).is_some()
839     }
840 
841     #[inline(always)]
unlock_shared(&self)842     unsafe fn unlock_shared(&self) {
843         drop(RwLockReadGuard {
844             lock: &self.lock,
845             data: &(),
846         });
847     }
848 
849     #[inline(always)]
is_locked(&self) -> bool850     fn is_locked(&self) -> bool {
851         self.lock.load(Ordering::Relaxed) != 0
852     }
853 }
854 
855 #[cfg(feature = "lock_api")]
856 unsafe impl<R: RelaxStrategy> lock_api_crate::RawRwLockUpgrade for RwLock<(), R> {
857     #[inline(always)]
lock_upgradable(&self)858     fn lock_upgradable(&self) {
859         // Prevent guard destructor running
860         core::mem::forget(self.upgradeable_read());
861     }
862 
863     #[inline(always)]
try_lock_upgradable(&self) -> bool864     fn try_lock_upgradable(&self) -> bool {
865         // Prevent guard destructor running
866         self.try_upgradeable_read()
867             .map(|g| core::mem::forget(g))
868             .is_some()
869     }
870 
871     #[inline(always)]
unlock_upgradable(&self)872     unsafe fn unlock_upgradable(&self) {
873         drop(RwLockUpgradableGuard {
874             inner: self,
875             data: &(),
876             phantom: PhantomData,
877         });
878     }
879 
880     #[inline(always)]
upgrade(&self)881     unsafe fn upgrade(&self) {
882         let tmp_guard = RwLockUpgradableGuard {
883             inner: self,
884             data: &(),
885             phantom: PhantomData,
886         };
887         core::mem::forget(tmp_guard.upgrade());
888     }
889 
890     #[inline(always)]
try_upgrade(&self) -> bool891     unsafe fn try_upgrade(&self) -> bool {
892         let tmp_guard = RwLockUpgradableGuard {
893             inner: self,
894             data: &(),
895             phantom: PhantomData,
896         };
897         tmp_guard
898             .try_upgrade()
899             .map(|g| core::mem::forget(g))
900             .is_ok()
901     }
902 }
903 
904 #[cfg(feature = "lock_api")]
905 unsafe impl<R: RelaxStrategy> lock_api_crate::RawRwLockDowngrade for RwLock<(), R> {
downgrade(&self)906     unsafe fn downgrade(&self) {
907         let tmp_guard = RwLockWriteGuard {
908             inner: self,
909             data: &mut (),
910             phantom: PhantomData,
911         };
912         core::mem::forget(tmp_guard.downgrade());
913     }
914 }
915 
916 #[cfg(feature = "lock_api1")]
917 unsafe impl lock_api::RawRwLockUpgradeDowngrade for RwLock<()> {
downgrade_upgradable(&self)918     unsafe fn downgrade_upgradable(&self) {
919         let tmp_guard = RwLockUpgradableGuard {
920             inner: self,
921             data: &(),
922             phantom: PhantomData,
923         };
924         core::mem::forget(tmp_guard.downgrade());
925     }
926 
downgrade_to_upgradable(&self)927     unsafe fn downgrade_to_upgradable(&self) {
928         let tmp_guard = RwLockWriteGuard {
929             inner: self,
930             data: &mut (),
931             phantom: PhantomData,
932         };
933         core::mem::forget(tmp_guard.downgrade_to_upgradeable());
934     }
935 }
936 
937 #[cfg(test)]
938 mod tests {
939     use std::prelude::v1::*;
940 
941     use std::sync::atomic::{AtomicUsize, Ordering};
942     use std::sync::mpsc::channel;
943     use std::sync::Arc;
944     use std::thread;
945 
946     type RwLock<T> = super::RwLock<T>;
947 
948     #[derive(Eq, PartialEq, Debug)]
949     struct NonCopy(i32);
950 
951     #[test]
smoke()952     fn smoke() {
953         let l = RwLock::new(());
954         drop(l.read());
955         drop(l.write());
956         drop((l.read(), l.read()));
957         drop(l.write());
958     }
959 
960     // TODO: needs RNG
961     //#[test]
962     //fn frob() {
963     //    static R: RwLock = RwLock::new();
964     //    const N: usize = 10;
965     //    const M: usize = 1000;
966     //
967     //    let (tx, rx) = channel::<()>();
968     //    for _ in 0..N {
969     //        let tx = tx.clone();
970     //        thread::spawn(move|| {
971     //            let mut rng = rand::thread_rng();
972     //            for _ in 0..M {
973     //                if rng.gen_weighted_bool(N) {
974     //                    drop(R.write());
975     //                } else {
976     //                    drop(R.read());
977     //                }
978     //            }
979     //            drop(tx);
980     //        });
981     //    }
982     //    drop(tx);
983     //    let _ = rx.recv();
984     //    unsafe { R.destroy(); }
985     //}
986 
987     #[test]
test_rw_arc()988     fn test_rw_arc() {
989         let arc = Arc::new(RwLock::new(0));
990         let arc2 = arc.clone();
991         let (tx, rx) = channel();
992 
993         let t = thread::spawn(move || {
994             let mut lock = arc2.write();
995             for _ in 0..10 {
996                 let tmp = *lock;
997                 *lock = -1;
998                 thread::yield_now();
999                 *lock = tmp + 1;
1000             }
1001             tx.send(()).unwrap();
1002         });
1003 
1004         // Readers try to catch the writer in the act
1005         let mut children = Vec::new();
1006         for _ in 0..5 {
1007             let arc3 = arc.clone();
1008             children.push(thread::spawn(move || {
1009                 let lock = arc3.read();
1010                 assert!(*lock >= 0);
1011             }));
1012         }
1013 
1014         // Wait for children to pass their asserts
1015         for r in children {
1016             assert!(r.join().is_ok());
1017         }
1018 
1019         // Wait for writer to finish
1020         rx.recv().unwrap();
1021         let lock = arc.read();
1022         assert_eq!(*lock, 10);
1023 
1024         assert!(t.join().is_ok());
1025     }
1026 
1027     #[test]
1028     #[ignore = "Android uses panic_abort"]
test_rw_access_in_unwind()1029     fn test_rw_access_in_unwind() {
1030         let arc = Arc::new(RwLock::new(1));
1031         let arc2 = arc.clone();
1032         let _ = thread::spawn(move || -> () {
1033             struct Unwinder {
1034                 i: Arc<RwLock<isize>>,
1035             }
1036             impl Drop for Unwinder {
1037                 fn drop(&mut self) {
1038                     let mut lock = self.i.write();
1039                     *lock += 1;
1040                 }
1041             }
1042             let _u = Unwinder { i: arc2 };
1043             panic!();
1044         })
1045         .join();
1046         let lock = arc.read();
1047         assert_eq!(*lock, 2);
1048     }
1049 
1050     #[test]
test_rwlock_unsized()1051     fn test_rwlock_unsized() {
1052         let rw: &RwLock<[i32]> = &RwLock::new([1, 2, 3]);
1053         {
1054             let b = &mut *rw.write();
1055             b[0] = 4;
1056             b[2] = 5;
1057         }
1058         let comp: &[i32] = &[4, 2, 5];
1059         assert_eq!(&*rw.read(), comp);
1060     }
1061 
1062     #[test]
test_rwlock_try_write()1063     fn test_rwlock_try_write() {
1064         use std::mem::drop;
1065 
1066         let lock = RwLock::new(0isize);
1067         let read_guard = lock.read();
1068 
1069         let write_result = lock.try_write();
1070         match write_result {
1071             None => (),
1072             Some(_) => assert!(
1073                 false,
1074                 "try_write should not succeed while read_guard is in scope"
1075             ),
1076         }
1077 
1078         drop(read_guard);
1079     }
1080 
1081     #[test]
test_rw_try_read()1082     fn test_rw_try_read() {
1083         let m = RwLock::new(0);
1084         ::std::mem::forget(m.write());
1085         assert!(m.try_read().is_none());
1086     }
1087 
1088     #[test]
test_into_inner()1089     fn test_into_inner() {
1090         let m = RwLock::new(NonCopy(10));
1091         assert_eq!(m.into_inner(), NonCopy(10));
1092     }
1093 
1094     #[test]
test_into_inner_drop()1095     fn test_into_inner_drop() {
1096         struct Foo(Arc<AtomicUsize>);
1097         impl Drop for Foo {
1098             fn drop(&mut self) {
1099                 self.0.fetch_add(1, Ordering::SeqCst);
1100             }
1101         }
1102         let num_drops = Arc::new(AtomicUsize::new(0));
1103         let m = RwLock::new(Foo(num_drops.clone()));
1104         assert_eq!(num_drops.load(Ordering::SeqCst), 0);
1105         {
1106             let _inner = m.into_inner();
1107             assert_eq!(num_drops.load(Ordering::SeqCst), 0);
1108         }
1109         assert_eq!(num_drops.load(Ordering::SeqCst), 1);
1110     }
1111 
1112     #[test]
test_force_read_decrement()1113     fn test_force_read_decrement() {
1114         let m = RwLock::new(());
1115         ::std::mem::forget(m.read());
1116         ::std::mem::forget(m.read());
1117         ::std::mem::forget(m.read());
1118         assert!(m.try_write().is_none());
1119         unsafe {
1120             m.force_read_decrement();
1121             m.force_read_decrement();
1122         }
1123         assert!(m.try_write().is_none());
1124         unsafe {
1125             m.force_read_decrement();
1126         }
1127         assert!(m.try_write().is_some());
1128     }
1129 
1130     #[test]
test_force_write_unlock()1131     fn test_force_write_unlock() {
1132         let m = RwLock::new(());
1133         ::std::mem::forget(m.write());
1134         assert!(m.try_read().is_none());
1135         unsafe {
1136             m.force_write_unlock();
1137         }
1138         assert!(m.try_read().is_some());
1139     }
1140 
1141     #[test]
test_upgrade_downgrade()1142     fn test_upgrade_downgrade() {
1143         let m = RwLock::new(());
1144         {
1145             let _r = m.read();
1146             let upg = m.try_upgradeable_read().unwrap();
1147             assert!(m.try_read().is_none());
1148             assert!(m.try_write().is_none());
1149             assert!(upg.try_upgrade().is_err());
1150         }
1151         {
1152             let w = m.write();
1153             assert!(m.try_upgradeable_read().is_none());
1154             let _r = w.downgrade();
1155             assert!(m.try_upgradeable_read().is_some());
1156             assert!(m.try_read().is_some());
1157             assert!(m.try_write().is_none());
1158         }
1159         {
1160             let _u = m.upgradeable_read();
1161             assert!(m.try_upgradeable_read().is_none());
1162         }
1163 
1164         assert!(m.try_upgradeable_read().unwrap().try_upgrade().is_ok());
1165     }
1166 }
1167