11use crate :: sync:: atomic:: {
2- AtomicI32 ,
2+ AtomicU32 ,
33 Ordering :: { Acquire , Relaxed , Release } ,
44} ;
55use crate :: sys:: futex:: { futex_wait, futex_wake, futex_wake_all} ;
@@ -14,36 +14,36 @@ pub struct RwLock {
1414 // 0x3FFF_FFFF: Write locked
1515 // Bit 30: Readers are waiting on this futex.
1616 // Bit 31: Writers are waiting on the writer_notify futex.
17- state : AtomicI32 ,
17+ state : AtomicU32 ,
1818 // The 'condition variable' to notify writers through.
1919 // Incremented on every signal.
20- writer_notify : AtomicI32 ,
20+ writer_notify : AtomicU32 ,
2121}
2222
23- const READ_LOCKED : i32 = 1 ;
24- const MASK : i32 = ( 1 << 30 ) - 1 ;
25- const WRITE_LOCKED : i32 = MASK ;
26- const MAX_READERS : i32 = MASK - 1 ;
27- const READERS_WAITING : i32 = 1 << 30 ;
28- const WRITERS_WAITING : i32 = 1 << 31 ;
23+ const READ_LOCKED : u32 = 1 ;
24+ const MASK : u32 = ( 1 << 30 ) - 1 ;
25+ const WRITE_LOCKED : u32 = MASK ;
26+ const MAX_READERS : u32 = MASK - 1 ;
27+ const READERS_WAITING : u32 = 1 << 30 ;
28+ const WRITERS_WAITING : u32 = 1 << 31 ;
2929
30- fn is_unlocked ( state : i32 ) -> bool {
30+ fn is_unlocked ( state : u32 ) -> bool {
3131 state & MASK == 0
3232}
3333
34- fn is_write_locked ( state : i32 ) -> bool {
34+ fn is_write_locked ( state : u32 ) -> bool {
3535 state & MASK == WRITE_LOCKED
3636}
3737
38- fn has_readers_waiting ( state : i32 ) -> bool {
38+ fn has_readers_waiting ( state : u32 ) -> bool {
3939 state & READERS_WAITING != 0
4040}
4141
42- fn has_writers_waiting ( state : i32 ) -> bool {
42+ fn has_writers_waiting ( state : u32 ) -> bool {
4343 state & WRITERS_WAITING != 0
4444}
4545
46- fn is_read_lockable ( state : i32 ) -> bool {
46+ fn is_read_lockable ( state : u32 ) -> bool {
4747 // This also returns false if the counter could overflow if we tried to read lock it.
4848 //
4949 // We don't allow read-locking if there's readers waiting, even if the lock is unlocked
@@ -53,14 +53,14 @@ fn is_read_lockable(state: i32) -> bool {
5353 state & MASK < MAX_READERS && !has_readers_waiting ( state) && !has_writers_waiting ( state)
5454}
5555
56- fn has_reached_max_readers ( state : i32 ) -> bool {
56+ fn has_reached_max_readers ( state : u32 ) -> bool {
5757 state & MASK == MAX_READERS
5858}
5959
6060impl RwLock {
6161 #[ inline]
6262 pub const fn new ( ) -> Self {
63- Self { state : AtomicI32 :: new ( 0 ) , writer_notify : AtomicI32 :: new ( 0 ) }
63+ Self { state : AtomicU32 :: new ( 0 ) , writer_notify : AtomicU32 :: new ( 0 ) }
6464 }
6565
6666 #[ inline]
@@ -227,7 +227,7 @@ impl RwLock {
227227 /// If both are waiting, this will wake up only one writer, but will fall
228228 /// back to waking up readers if there was no writer to wake up.
229229 #[ cold]
230- fn wake_writer_or_readers ( & self , mut state : i32 ) {
230+ fn wake_writer_or_readers ( & self , mut state : u32 ) {
231231 assert ! ( is_unlocked( state) ) ;
232232
233233 // The readers waiting bit might be turned on at any point now,
@@ -287,7 +287,7 @@ impl RwLock {
287287 }
288288
289289 /// Spin for a while, but stop directly at the given condition.
290- fn spin_until ( & self , f : impl Fn ( i32 ) -> bool ) -> i32 {
290+ fn spin_until ( & self , f : impl Fn ( u32 ) -> bool ) -> u32 {
291291 let mut spin = 100 ; // Chosen by fair dice roll.
292292 loop {
293293 let state = self . state . load ( Relaxed ) ;
@@ -299,12 +299,12 @@ impl RwLock {
299299 }
300300 }
301301
302- fn spin_write ( & self ) -> i32 {
302+ fn spin_write ( & self ) -> u32 {
303303 // Stop spinning when it's unlocked or when there's waiting writers, to keep things somewhat fair.
304304 self . spin_until ( |state| is_unlocked ( state) || has_writers_waiting ( state) )
305305 }
306306
307- fn spin_read ( & self ) -> i32 {
307+ fn spin_read ( & self ) -> u32 {
308308 // Stop spinning when it's unlocked or read locked, or when there's waiting threads.
309309 self . spin_until ( |state| {
310310 !is_write_locked ( state) || has_readers_waiting ( state) || has_writers_waiting ( state)
0 commit comments