1
1
use crate :: cell:: UnsafeCell ;
2
2
use crate :: mem;
3
+ use crate :: mem:: MaybeUninit ;
3
4
use crate :: sync:: atomic:: { AtomicU32 , Ordering } ;
4
5
use crate :: sys:: cloudabi:: abi;
5
6
use crate :: sys:: rwlock:: { self , RWLock } ;
@@ -47,25 +48,28 @@ impl Mutex {
47
48
}
48
49
49
50
pub struct ReentrantMutex {
50
- lock : UnsafeCell < AtomicU32 > ,
51
- recursion : UnsafeCell < u32 > ,
51
+ lock : UnsafeCell < MaybeUninit < AtomicU32 > > ,
52
+ recursion : UnsafeCell < MaybeUninit < u32 > > ,
52
53
}
53
54
54
55
impl ReentrantMutex {
55
56
pub unsafe fn uninitialized ( ) -> ReentrantMutex {
56
- mem:: uninitialized ( )
57
+ ReentrantMutex {
58
+ lock : UnsafeCell :: new ( MaybeUninit :: uninit ( ) ) ,
59
+ recursion : UnsafeCell :: new ( MaybeUninit :: uninit ( ) )
60
+ }
57
61
}
58
62
59
63
pub unsafe fn init ( & mut self ) {
60
- self . lock = UnsafeCell :: new ( AtomicU32 :: new ( abi:: LOCK_UNLOCKED . 0 ) ) ;
61
- self . recursion = UnsafeCell :: new ( 0 ) ;
64
+ self . lock = UnsafeCell :: new ( MaybeUninit :: new ( AtomicU32 :: new ( abi:: LOCK_UNLOCKED . 0 ) ) ) ;
65
+ self . recursion = UnsafeCell :: new ( MaybeUninit :: new ( 0 ) ) ;
62
66
}
63
67
64
68
pub unsafe fn try_lock ( & self ) -> bool {
65
69
// Attempt to acquire the lock.
66
70
let lock = self . lock . get ( ) ;
67
71
let recursion = self . recursion . get ( ) ;
68
- if let Err ( old) = ( * lock) . compare_exchange (
72
+ if let Err ( old) = ( * ( * lock) . as_mut_ptr ( ) ) . compare_exchange (
69
73
abi:: LOCK_UNLOCKED . 0 ,
70
74
__pthread_thread_id. 0 | abi:: LOCK_WRLOCKED . 0 ,
71
75
Ordering :: Acquire ,
@@ -74,14 +78,14 @@ impl ReentrantMutex {
74
78
// If we fail to acquire the lock, it may be the case
75
79
// that we've already acquired it and may need to recurse.
76
80
if old & !abi:: LOCK_KERNEL_MANAGED . 0 == __pthread_thread_id. 0 | abi:: LOCK_WRLOCKED . 0 {
77
- * recursion += 1 ;
81
+ * ( * recursion) . as_mut_ptr ( ) += 1 ;
78
82
true
79
83
} else {
80
84
false
81
85
}
82
86
} else {
83
87
// Success.
84
- assert_eq ! ( * recursion, 0 , "Mutex has invalid recursion count" ) ;
88
+ assert_eq ! ( * ( * recursion) . as_mut_ptr ( ) , 0 , "Mutex has invalid recursion count" ) ;
85
89
true
86
90
}
87
91
}
@@ -112,14 +116,14 @@ impl ReentrantMutex {
112
116
let lock = self . lock . get ( ) ;
113
117
let recursion = self . recursion . get ( ) ;
114
118
assert_eq ! (
115
- ( * lock) . load( Ordering :: Relaxed ) & !abi:: LOCK_KERNEL_MANAGED . 0 ,
119
+ ( * ( * lock) . as_mut_ptr ( ) ) . load( Ordering :: Relaxed ) & !abi:: LOCK_KERNEL_MANAGED . 0 ,
116
120
__pthread_thread_id. 0 | abi:: LOCK_WRLOCKED . 0 ,
117
121
"This mutex is locked by a different thread"
118
122
) ;
119
123
120
- if * recursion > 0 {
121
- * recursion -= 1 ;
122
- } else if !( * lock)
124
+ if * ( * recursion) . as_mut_ptr ( ) > 0 {
125
+ * ( * recursion) . as_mut_ptr ( ) -= 1 ;
126
+ } else if !( * ( * lock) . as_mut_ptr ( ) )
123
127
. compare_exchange (
124
128
__pthread_thread_id. 0 | abi:: LOCK_WRLOCKED . 0 ,
125
129
abi:: LOCK_UNLOCKED . 0 ,
@@ -139,10 +143,10 @@ impl ReentrantMutex {
139
143
let lock = self . lock . get ( ) ;
140
144
let recursion = self . recursion . get ( ) ;
141
145
assert_eq ! (
142
- ( * lock) . load( Ordering :: Relaxed ) ,
146
+ ( * ( * lock) . as_mut_ptr ( ) ) . load( Ordering :: Relaxed ) ,
143
147
abi:: LOCK_UNLOCKED . 0 ,
144
148
"Attempted to destroy locked mutex"
145
149
) ;
146
- assert_eq ! ( * recursion, 0 , "Recursion counter invalid" ) ;
150
+ assert_eq ! ( * ( * recursion) . as_mut_ptr ( ) , 0 , "Recursion counter invalid" ) ;
147
151
}
148
152
}
0 commit comments