1- use crate :: cell:: UnsafeCell ;
21use crate :: mem;
32use crate :: mem:: MaybeUninit ;
43use crate :: sync:: atomic:: { AtomicU32 , Ordering } ;
@@ -13,28 +12,25 @@ extern "C" {
1312static mut RDLOCKS_ACQUIRED : u32 = 0 ;
1413
1514pub struct RWLock {
16- lock : UnsafeCell < AtomicU32 > ,
15+ lock : AtomicU32 ,
1716}
1817
1918pub unsafe fn raw ( r : & RWLock ) -> * mut AtomicU32 {
20- r. lock . get ( )
19+ & r. lock as * const AtomicU32 as * mut AtomicU32
2120}
2221
2322unsafe impl Send for RWLock { }
2423unsafe impl Sync for RWLock { }
2524
26- const NEW : RWLock = RWLock { lock : UnsafeCell :: new ( AtomicU32 :: new ( abi:: LOCK_UNLOCKED . 0 ) ) } ;
27-
2825impl RWLock {
2926 pub const fn new ( ) -> RWLock {
30- NEW
27+ RWLock { lock : AtomicU32 :: new ( abi :: LOCK_UNLOCKED . 0 ) }
3128 }
3229
3330 pub unsafe fn try_read ( & self ) -> bool {
34- let lock = self . lock . get ( ) ;
3531 let mut old = abi:: LOCK_UNLOCKED . 0 ;
3632 while let Err ( cur) =
37- ( * lock) . compare_exchange_weak ( old, old + 1 , Ordering :: Acquire , Ordering :: Relaxed )
33+ self . lock . compare_exchange_weak ( old, old + 1 , Ordering :: Acquire , Ordering :: Relaxed )
3834 {
3935 if ( cur & abi:: LOCK_WRLOCKED . 0 ) != 0 {
4036 // Another thread already has a write lock.
@@ -61,12 +57,11 @@ impl RWLock {
6157 pub unsafe fn read ( & self ) {
6258 if !self . try_read ( ) {
6359 // Call into the kernel to acquire a read lock.
64- let lock = self . lock . get ( ) ;
6560 let subscription = abi:: subscription {
6661 type_ : abi:: eventtype:: LOCK_RDLOCK ,
6762 union : abi:: subscription_union {
6863 lock : abi:: subscription_lock {
69- lock : lock as * mut abi:: lock ,
64+ lock : & self . lock as * const AtomicU32 as * mut abi:: lock ,
7065 lock_scope : abi:: scope:: PRIVATE ,
7166 } ,
7267 } ,
@@ -96,11 +91,10 @@ impl RWLock {
9691 assert ! ( RDLOCKS_ACQUIRED > 0 , "Bad lock count" ) ;
9792 let mut old = 1 ;
9893 loop {
99- let lock = self . lock . get ( ) ;
10094 if old == 1 | abi:: LOCK_KERNEL_MANAGED . 0 {
10195 // Last read lock while threads are waiting. Attempt to upgrade
10296 // to a write lock before calling into the kernel to unlock.
103- if let Err ( cur) = ( * lock) . compare_exchange_weak (
97+ if let Err ( cur) = self . lock . compare_exchange_weak (
10498 old,
10599 __pthread_thread_id. 0 | abi:: LOCK_WRLOCKED . 0 | abi:: LOCK_KERNEL_MANAGED . 0 ,
106100 Ordering :: Acquire ,
@@ -109,7 +103,10 @@ impl RWLock {
109103 old = cur;
110104 } else {
111105 // Call into the kernel to unlock.
112- let ret = abi:: lock_unlock ( lock as * mut abi:: lock , abi:: scope:: PRIVATE ) ;
106+ let ret = abi:: lock_unlock (
107+ & self . lock as * const AtomicU32 as * mut abi:: lock ,
108+ abi:: scope:: PRIVATE ,
109+ ) ;
113110 assert_eq ! ( ret, abi:: errno:: SUCCESS , "Failed to write unlock a rwlock" ) ;
114111 break ;
115112 }
@@ -122,7 +119,7 @@ impl RWLock {
122119 0 ,
123120 "Attempted to read-unlock a write-locked rwlock"
124121 ) ;
125- if let Err ( cur) = ( * lock) . compare_exchange_weak (
122+ if let Err ( cur) = self . lock . compare_exchange_weak (
126123 old,
127124 old - 1 ,
128125 Ordering :: Acquire ,
@@ -140,8 +137,7 @@ impl RWLock {
140137
141138 pub unsafe fn try_write ( & self ) -> bool {
142139 // Attempt to acquire the lock.
143- let lock = self . lock . get ( ) ;
144- if let Err ( old) = ( * lock) . compare_exchange (
140+ if let Err ( old) = self . lock . compare_exchange (
145141 abi:: LOCK_UNLOCKED . 0 ,
146142 __pthread_thread_id. 0 | abi:: LOCK_WRLOCKED . 0 ,
147143 Ordering :: Acquire ,
@@ -163,12 +159,11 @@ impl RWLock {
163159 pub unsafe fn write ( & self ) {
164160 if !self . try_write ( ) {
165161 // Call into the kernel to acquire a write lock.
166- let lock = self . lock . get ( ) ;
167162 let subscription = abi:: subscription {
168163 type_ : abi:: eventtype:: LOCK_WRLOCK ,
169164 union : abi:: subscription_union {
170165 lock : abi:: subscription_lock {
171- lock : lock as * mut abi:: lock ,
166+ lock : & self . lock as * const AtomicU32 as * mut abi:: lock ,
172167 lock_scope : abi:: scope:: PRIVATE ,
173168 } ,
174169 } ,
@@ -184,14 +179,14 @@ impl RWLock {
184179 }
185180
186181 pub unsafe fn write_unlock ( & self ) {
187- let lock = self . lock . get ( ) ;
188182 assert_eq ! (
189- ( * lock) . load( Ordering :: Relaxed ) & !abi:: LOCK_KERNEL_MANAGED . 0 ,
183+ self . lock. load( Ordering :: Relaxed ) & !abi:: LOCK_KERNEL_MANAGED . 0 ,
190184 __pthread_thread_id. 0 | abi:: LOCK_WRLOCKED . 0 ,
191185 "This rwlock is not write-locked by this thread"
192186 ) ;
193187
194- if !( * lock)
188+ if !self
189+ . lock
195190 . compare_exchange (
196191 __pthread_thread_id. 0 | abi:: LOCK_WRLOCKED . 0 ,
197192 abi:: LOCK_UNLOCKED . 0 ,
@@ -202,15 +197,17 @@ impl RWLock {
202197 {
203198 // Lock is managed by kernelspace. Call into the kernel
204199 // to unblock waiting threads.
205- let ret = abi:: lock_unlock ( lock as * mut abi:: lock , abi:: scope:: PRIVATE ) ;
200+ let ret = abi:: lock_unlock (
201+ & self . lock as * const AtomicU32 as * mut abi:: lock ,
202+ abi:: scope:: PRIVATE ,
203+ ) ;
206204 assert_eq ! ( ret, abi:: errno:: SUCCESS , "Failed to write unlock a rwlock" ) ;
207205 }
208206 }
209207
210208 pub unsafe fn destroy ( & self ) {
211- let lock = self . lock . get ( ) ;
212209 assert_eq ! (
213- ( * lock) . load( Ordering :: Relaxed ) ,
210+ self . lock. load( Ordering :: Relaxed ) ,
214211 abi:: LOCK_UNLOCKED . 0 ,
215212 "Attempted to destroy locked rwlock"
216213 ) ;
0 commit comments