1
- use crate :: cell:: UnsafeCell ;
2
1
use crate :: mem;
3
2
use crate :: mem:: MaybeUninit ;
4
3
use crate :: sync:: atomic:: { AtomicU32 , Ordering } ;
@@ -13,28 +12,25 @@ extern "C" {
13
12
static mut RDLOCKS_ACQUIRED : u32 = 0 ;
14
13
15
14
pub struct RWLock {
16
- lock : UnsafeCell < AtomicU32 > ,
15
+ lock : AtomicU32 ,
17
16
}
18
17
19
18
pub unsafe fn raw ( r : & RWLock ) -> * mut AtomicU32 {
20
- r. lock . get ( )
19
+ & r. lock as * const AtomicU32 as * mut AtomicU32
21
20
}
22
21
23
22
unsafe impl Send for RWLock { }
24
23
unsafe impl Sync for RWLock { }
25
24
26
- const NEW : RWLock = RWLock { lock : UnsafeCell :: new ( AtomicU32 :: new ( abi:: LOCK_UNLOCKED . 0 ) ) } ;
27
-
28
25
impl RWLock {
29
26
pub const fn new ( ) -> RWLock {
30
- NEW
27
+ RWLock { lock : AtomicU32 :: new ( abi :: LOCK_UNLOCKED . 0 ) }
31
28
}
32
29
33
30
pub unsafe fn try_read ( & self ) -> bool {
34
- let lock = self . lock . get ( ) ;
35
31
let mut old = abi:: LOCK_UNLOCKED . 0 ;
36
32
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 )
38
34
{
39
35
if ( cur & abi:: LOCK_WRLOCKED . 0 ) != 0 {
40
36
// Another thread already has a write lock.
@@ -61,12 +57,11 @@ impl RWLock {
61
57
pub unsafe fn read ( & self ) {
62
58
if !self . try_read ( ) {
63
59
// Call into the kernel to acquire a read lock.
64
- let lock = self . lock . get ( ) ;
65
60
let subscription = abi:: subscription {
66
61
type_ : abi:: eventtype:: LOCK_RDLOCK ,
67
62
union : abi:: subscription_union {
68
63
lock : abi:: subscription_lock {
69
- lock : lock as * mut abi:: lock ,
64
+ lock : & self . lock as * const AtomicU32 as * mut abi:: lock ,
70
65
lock_scope : abi:: scope:: PRIVATE ,
71
66
} ,
72
67
} ,
@@ -96,11 +91,10 @@ impl RWLock {
96
91
assert ! ( RDLOCKS_ACQUIRED > 0 , "Bad lock count" ) ;
97
92
let mut old = 1 ;
98
93
loop {
99
- let lock = self . lock . get ( ) ;
100
94
if old == 1 | abi:: LOCK_KERNEL_MANAGED . 0 {
101
95
// Last read lock while threads are waiting. Attempt to upgrade
102
96
// 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 (
104
98
old,
105
99
__pthread_thread_id. 0 | abi:: LOCK_WRLOCKED . 0 | abi:: LOCK_KERNEL_MANAGED . 0 ,
106
100
Ordering :: Acquire ,
@@ -109,7 +103,10 @@ impl RWLock {
109
103
old = cur;
110
104
} else {
111
105
// 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
+ ) ;
113
110
assert_eq ! ( ret, abi:: errno:: SUCCESS , "Failed to write unlock a rwlock" ) ;
114
111
break ;
115
112
}
@@ -122,7 +119,7 @@ impl RWLock {
122
119
0 ,
123
120
"Attempted to read-unlock a write-locked rwlock"
124
121
) ;
125
- if let Err ( cur) = ( * lock) . compare_exchange_weak (
122
+ if let Err ( cur) = self . lock . compare_exchange_weak (
126
123
old,
127
124
old - 1 ,
128
125
Ordering :: Acquire ,
@@ -140,8 +137,7 @@ impl RWLock {
140
137
141
138
pub unsafe fn try_write ( & self ) -> bool {
142
139
// 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 (
145
141
abi:: LOCK_UNLOCKED . 0 ,
146
142
__pthread_thread_id. 0 | abi:: LOCK_WRLOCKED . 0 ,
147
143
Ordering :: Acquire ,
@@ -163,12 +159,11 @@ impl RWLock {
163
159
pub unsafe fn write ( & self ) {
164
160
if !self . try_write ( ) {
165
161
// Call into the kernel to acquire a write lock.
166
- let lock = self . lock . get ( ) ;
167
162
let subscription = abi:: subscription {
168
163
type_ : abi:: eventtype:: LOCK_WRLOCK ,
169
164
union : abi:: subscription_union {
170
165
lock : abi:: subscription_lock {
171
- lock : lock as * mut abi:: lock ,
166
+ lock : & self . lock as * const AtomicU32 as * mut abi:: lock ,
172
167
lock_scope : abi:: scope:: PRIVATE ,
173
168
} ,
174
169
} ,
@@ -184,14 +179,14 @@ impl RWLock {
184
179
}
185
180
186
181
pub unsafe fn write_unlock ( & self ) {
187
- let lock = self . lock . get ( ) ;
188
182
assert_eq ! (
189
- ( * lock) . load( Ordering :: Relaxed ) & !abi:: LOCK_KERNEL_MANAGED . 0 ,
183
+ self . lock. load( Ordering :: Relaxed ) & !abi:: LOCK_KERNEL_MANAGED . 0 ,
190
184
__pthread_thread_id. 0 | abi:: LOCK_WRLOCKED . 0 ,
191
185
"This rwlock is not write-locked by this thread"
192
186
) ;
193
187
194
- if !( * lock)
188
+ if !self
189
+ . lock
195
190
. compare_exchange (
196
191
__pthread_thread_id. 0 | abi:: LOCK_WRLOCKED . 0 ,
197
192
abi:: LOCK_UNLOCKED . 0 ,
@@ -202,15 +197,17 @@ impl RWLock {
202
197
{
203
198
// Lock is managed by kernelspace. Call into the kernel
204
199
// 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
+ ) ;
206
204
assert_eq ! ( ret, abi:: errno:: SUCCESS , "Failed to write unlock a rwlock" ) ;
207
205
}
208
206
}
209
207
210
208
pub unsafe fn destroy ( & self ) {
211
- let lock = self . lock . get ( ) ;
212
209
assert_eq ! (
213
- ( * lock) . load( Ordering :: Relaxed ) ,
210
+ self . lock. load( Ordering :: Relaxed ) ,
214
211
abi:: LOCK_UNLOCKED . 0 ,
215
212
"Attempted to destroy locked rwlock"
216
213
) ;
0 commit comments