1- use crate :: cell:: UnsafeCell ;
1+ use crate :: cell:: Cell ;
22use crate :: mem;
33use crate :: mem:: MaybeUninit ;
44use crate :: sync:: atomic:: { AtomicU32 , Ordering } ;
@@ -50,28 +50,23 @@ impl Mutex {
5050}
5151
5252pub struct ReentrantMutex {
53- lock : UnsafeCell < MaybeUninit < AtomicU32 > > ,
54- recursion : UnsafeCell < MaybeUninit < u32 > > ,
53+ lock : AtomicU32 ,
54+ recursion : Cell < u32 > ,
5555}
5656
57+ unsafe impl Send for ReentrantMutex { }
58+ unsafe impl Sync for ReentrantMutex { }
59+
5760impl ReentrantMutex {
5861 pub const unsafe fn uninitialized ( ) -> ReentrantMutex {
59- ReentrantMutex {
60- lock : UnsafeCell :: new ( MaybeUninit :: uninit ( ) ) ,
61- recursion : UnsafeCell :: new ( MaybeUninit :: uninit ( ) ) ,
62- }
62+ ReentrantMutex { lock : AtomicU32 :: new ( abi:: LOCK_UNLOCKED . 0 ) , recursion : Cell :: new ( 0 ) }
6363 }
6464
65- pub unsafe fn init ( & self ) {
66- * self . lock . get ( ) = MaybeUninit :: new ( AtomicU32 :: new ( abi:: LOCK_UNLOCKED . 0 ) ) ;
67- * self . recursion . get ( ) = MaybeUninit :: new ( 0 ) ;
68- }
65+ pub unsafe fn init ( & self ) { }
6966
7067 pub unsafe fn try_lock ( & self ) -> bool {
7168 // Attempt to acquire the lock.
72- let lock = ( * self . lock . get ( ) ) . as_mut_ptr ( ) ;
73- let recursion = ( * self . recursion . get ( ) ) . as_mut_ptr ( ) ;
74- if let Err ( old) = ( * lock) . compare_exchange (
69+ if let Err ( old) = self . lock . compare_exchange (
7570 abi:: LOCK_UNLOCKED . 0 ,
7671 __pthread_thread_id. 0 | abi:: LOCK_WRLOCKED . 0 ,
7772 Ordering :: Acquire ,
@@ -80,22 +75,22 @@ impl ReentrantMutex {
8075 // If we fail to acquire the lock, it may be the case
8176 // that we've already acquired it and may need to recurse.
8277 if old & !abi:: LOCK_KERNEL_MANAGED . 0 == __pthread_thread_id. 0 | abi:: LOCK_WRLOCKED . 0 {
83- * recursion += 1 ;
78+ self . recursion . set ( self . recursion . get ( ) + 1 ) ;
8479 true
8580 } else {
8681 false
8782 }
8883 } else {
8984 // Success.
90- assert_eq ! ( * recursion, 0 , "Mutex has invalid recursion count" ) ;
85+ assert_eq ! ( self . recursion. get ( ) , 0 , "Mutex has invalid recursion count" ) ;
9186 true
9287 }
9388 }
9489
9590 pub unsafe fn lock ( & self ) {
9691 if !self . try_lock ( ) {
9792 // Call into the kernel to acquire a write lock.
98- let lock = self . lock . get ( ) ;
93+ let lock = & self . lock as * const AtomicU32 ;
9994 let subscription = abi:: subscription {
10095 type_ : abi:: eventtype:: LOCK_WRLOCK ,
10196 union : abi:: subscription_union {
@@ -116,17 +111,17 @@ impl ReentrantMutex {
116111 }
117112
118113 pub unsafe fn unlock ( & self ) {
119- let lock = ( * self . lock . get ( ) ) . as_mut_ptr ( ) ;
120- let recursion = ( * self . recursion . get ( ) ) . as_mut_ptr ( ) ;
121114 assert_eq ! (
122- ( * lock) . load( Ordering :: Relaxed ) & !abi:: LOCK_KERNEL_MANAGED . 0 ,
115+ self . lock. load( Ordering :: Relaxed ) & !abi:: LOCK_KERNEL_MANAGED . 0 ,
123116 __pthread_thread_id. 0 | abi:: LOCK_WRLOCKED . 0 ,
124117 "This mutex is locked by a different thread"
125118 ) ;
126119
127- if * recursion > 0 {
128- * recursion -= 1 ;
129- } else if !( * lock)
120+ let r = self . recursion . get ( ) ;
121+ if r > 0 {
122+ self . recursion . set ( r - 1 ) ;
123+ } else if !self
124+ . lock
130125 . compare_exchange (
131126 __pthread_thread_id. 0 | abi:: LOCK_WRLOCKED . 0 ,
132127 abi:: LOCK_UNLOCKED . 0 ,
@@ -137,19 +132,20 @@ impl ReentrantMutex {
137132 {
138133 // Lock is managed by kernelspace. Call into the kernel
139134 // to unblock waiting threads.
140- let ret = abi:: lock_unlock ( lock as * mut abi:: lock , abi:: scope:: PRIVATE ) ;
135+ let ret = abi:: lock_unlock (
136+ & self . lock as * const AtomicU32 as * mut abi:: lock ,
137+ abi:: scope:: PRIVATE ,
138+ ) ;
141139 assert_eq ! ( ret, abi:: errno:: SUCCESS , "Failed to unlock a mutex" ) ;
142140 }
143141 }
144142
145143 pub unsafe fn destroy ( & self ) {
146- let lock = ( * self . lock . get ( ) ) . as_mut_ptr ( ) ;
147- let recursion = ( * self . recursion . get ( ) ) . as_mut_ptr ( ) ;
148144 assert_eq ! (
149- ( * lock) . load( Ordering :: Relaxed ) ,
145+ self . lock. load( Ordering :: Relaxed ) ,
150146 abi:: LOCK_UNLOCKED . 0 ,
151147 "Attempted to destroy locked mutex"
152148 ) ;
153- assert_eq ! ( * recursion, 0 , "Recursion counter invalid" ) ;
149+ assert_eq ! ( self . recursion. get ( ) , 0 , "Recursion counter invalid" ) ;
154150 }
155151}
0 commit comments