66
77use std:: cell:: UnsafeCell ;
88use std:: mem;
9- use std:: sync:: atomic:: { AtomicU64 , AtomicUsize , Ordering } ;
9+ use std:: sync:: atomic:: { AtomicU64 , AtomicUsize , Ordering , Ordering :: SeqCst } ;
1010use std:: sync:: Arc ;
1111
1212use fortanix_sgx_abi:: { FifoDescriptor , WithId } ;
@@ -152,7 +152,7 @@ impl<T: Transmittable> Fifo<T> {
152152 pub ( crate ) fn try_send_impl ( & self , val : Identified < T > ) -> Result < /*wake up reader:*/ bool , TrySendError > {
153153 let ( new, was_empty) = loop {
154154 // 1. Load the current offsets.
155- let current = Offsets :: new ( self . offsets . load ( Ordering :: SeqCst ) , self . data . len ( ) as u32 ) ;
155+ let current = Offsets :: new ( self . offsets . load ( SeqCst ) , self . data . len ( ) as u32 ) ;
156156 let was_empty = current. is_empty ( ) ;
157157
158158 // 2. If the queue is full, wait, then go to step 1.
@@ -164,24 +164,23 @@ impl<T: Transmittable> Fifo<T> {
164164 // with the current offsets. If the CAS was not succesful, go to step 1.
165165 let new = current. increment_write_offset ( ) ;
166166 let current = current. as_usize ( ) ;
167- let prev = self . offsets . compare_and_swap ( current, new. as_usize ( ) , Ordering :: SeqCst ) ;
168- if prev == current {
167+ if self . offsets . compare_exchange ( current, new. as_usize ( ) , SeqCst , SeqCst ) . is_ok ( ) {
169168 break ( new, was_empty) ;
170169 }
171170 } ;
172171
173172 // 4. Write the data, then the `id`.
174173 let slot = unsafe { & mut * self . data [ new. write_offset ( ) ] . get ( ) } ;
175174 slot. data = val. data ;
176- slot. id . store ( val. id , Ordering :: SeqCst ) ;
175+ slot. id . store ( val. id , SeqCst ) ;
177176
178177 // 5. If the queue was empty in step 1, signal the reader to wake up.
179178 Ok ( was_empty)
180179 }
181180
182181 pub ( crate ) fn try_recv_impl ( & self ) -> Result < ( Identified < T > , /*wake up writer:*/ bool ) , TryRecvError > {
183182 // 1. Load the current offsets.
184- let current = Offsets :: new ( self . offsets . load ( Ordering :: SeqCst ) , self . data . len ( ) as u32 ) ;
183+ let current = Offsets :: new ( self . offsets . load ( SeqCst ) , self . data . len ( ) as u32 ) ;
185184
186185 // 2. If the queue is empty, wait, then go to step 1.
187186 if current. is_empty ( ) {
@@ -194,7 +193,7 @@ impl<T: Transmittable> Fifo<T> {
194193 let ( slot, id) = loop {
195194 // 4. Read the `id` at the new read offset.
196195 let slot = unsafe { & mut * self . data [ new. read_offset ( ) ] . get ( ) } ;
197- let id = slot. id . load ( Ordering :: SeqCst ) ;
196+ let id = slot. id . load ( SeqCst ) ;
198197
199198 // 5. If `id` is `0`, go to step 4 (spin). Spinning is OK because data is
200199 // expected to be written imminently.
@@ -205,13 +204,13 @@ impl<T: Transmittable> Fifo<T> {
205204
206205 // 6. Read the data, then store `0` in the `id`.
207206 let val = Identified { id, data : slot. data } ;
208- slot. id . store ( 0 , Ordering :: SeqCst ) ;
207+ slot. id . store ( 0 , SeqCst ) ;
209208
210209 // 7. Store the new read offset, retrieving the old offsets.
211210 let before = fetch_adjust (
212211 self . offsets ,
213212 new. read as isize - current. read as isize ,
214- Ordering :: SeqCst ,
213+ SeqCst ,
215214 ) ;
216215
217216 // 8. If the queue was full before step 7, signal the writer to wake up.
@@ -288,7 +287,6 @@ impl Offsets {
288287mod tests {
289288 use super :: * ;
290289 use crate :: test_support:: { NoopSynchronizer , TestValue } ;
291- use std:: sync:: atomic:: { AtomicUsize , Ordering } ;
292290 use std:: sync:: mpsc;
293291 use std:: thread;
294292
@@ -367,10 +365,10 @@ mod tests {
367365 #[ test]
368366 fn fetch_adjust_correctness ( ) {
369367 let x = AtomicUsize :: new ( 0 ) ;
370- fetch_adjust ( & x, 5 , Ordering :: SeqCst ) ;
371- assert_eq ! ( x. load( Ordering :: SeqCst ) , 5 ) ;
372- fetch_adjust ( & x, -3 , Ordering :: SeqCst ) ;
373- assert_eq ! ( x. load( Ordering :: SeqCst ) , 2 ) ;
368+ fetch_adjust ( & x, 5 , SeqCst ) ;
369+ assert_eq ! ( x. load( SeqCst ) , 5 ) ;
370+ fetch_adjust ( & x, -3 , SeqCst ) ;
371+ assert_eq ! ( x. load( SeqCst ) , 2 ) ;
374372 }
375373
376374 #[ test]
0 commit comments