@@ -11,33 +11,86 @@ mod imp {
1111
1212#[ cfg( any( target_arch = "arm" , target_arch = "mips" , target_arch = "powerpc" ) ) ]
1313mod imp {
14- use std:: sync:: atomic:: Ordering ;
15- use std:: sync:: Mutex ;
14+ use std:: cell:: UnsafeCell ;
15+ use std:: ops:: { Deref , DerefMut } ;
16+ use std:: sync:: atomic:: { AtomicBool , Ordering } ;
1617
17- #[ derive( Debug ) ]
18- pub ( crate ) struct AtomicU64 ( Mutex < u64 > ) ;
18+ use crossbeam_utils:: Backoff ;
19+
20+ pub ( crate ) struct AtomicU64 ( Spinlock < u64 > ) ;
1921
2022 impl AtomicU64 {
21- pub ( crate ) fn new ( val : u64 ) -> Self {
22- Self ( Mutex :: new ( val) )
23+ pub ( crate ) const fn new ( val : u64 ) -> Self {
24+ Self ( Spinlock :: new ( val) )
2325 }
2426
2527 pub ( crate ) fn load ( & self , _: Ordering ) -> u64 {
26- * self . 0 . lock ( ) . unwrap ( )
28+ * self . 0 . lock ( )
2729 }
2830
2931 pub ( crate ) fn fetch_add ( & self , val : u64 , _: Ordering ) -> u64 {
30- let mut lock = self . 0 . lock ( ) . unwrap ( ) ;
32+ let mut lock = self . 0 . lock ( ) ;
3133 let prev = * lock;
3234 * lock = prev + val;
3335 prev
3436 }
3537
3638 pub ( crate ) fn fetch_sub ( & self , val : u64 , _: Ordering ) -> u64 {
37- let mut lock = self . 0 . lock ( ) . unwrap ( ) ;
39+ let mut lock = self . 0 . lock ( ) ;
3840 let prev = * lock;
3941 * lock = prev - val;
4042 prev
4143 }
4244 }
45+
46+ /// A simple spinlock.
47+ struct Spinlock < T > {
48+ flag : AtomicBool ,
49+ value : UnsafeCell < T > ,
50+ }
51+
52+ unsafe impl < T : Send > Send for Spinlock < T > { }
53+ unsafe impl < T : Send > Sync for Spinlock < T > { }
54+
55+ impl < T > Spinlock < T > {
56+ /// Returns a new spinlock initialized with `value`.
57+ const fn new ( value : T ) -> Self {
58+ Self {
59+ flag : AtomicBool :: new ( false ) ,
60+ value : UnsafeCell :: new ( value) ,
61+ }
62+ }
63+
64+ /// Locks the spinlock.
65+ fn lock ( & self ) -> SpinlockGuard < ' _ , T > {
66+ let backoff = Backoff :: new ( ) ;
67+ while self . flag . swap ( true , Ordering :: Acquire ) {
68+ backoff. snooze ( ) ;
69+ }
70+ SpinlockGuard ( self )
71+ }
72+ }
73+
74+ /// A guard holding a spinlock locked.
75+ struct SpinlockGuard < ' a , T > ( & ' a Spinlock < T > ) ;
76+
77+ impl < T > Drop for SpinlockGuard < ' _ , T > {
78+ fn drop ( & mut self ) {
79+ self . 0 . flag . store ( false , Ordering :: Release ) ;
80+ }
81+ }
82+
83+ impl < T > Deref for SpinlockGuard < ' _ , T > {
84+ type Target = T ;
85+
86+ fn deref ( & self ) -> & T {
87+ unsafe { & * self . 0 . value . get ( ) }
88+ }
89+ }
90+
91+ impl < T > DerefMut for SpinlockGuard < ' _ , T > {
92+ fn deref_mut ( & mut self ) -> & mut T {
93+ unsafe { & mut * self . 0 . value . get ( ) }
94+ }
95+ }
4396}
0 commit comments