44//! in the chip scheduler if the hardware doesn't support interrupts where
55//! they are needed.
66
7- use core:: cell:: UnsafeCell ;
87use core:: convert:: Into ;
98use core:: convert:: TryFrom ;
109use core:: convert:: TryInto ;
11- use core:: intrinsics;
1210use core:: marker:: Copy ;
13- use core:: marker:: Sync ;
14-
15- /// AtomicUsize with no CAS operations that works on targets that have "no atomic
16- /// support" according to their specification. This makes it work on thumbv6
17- /// platforms.
18- ///
19- /// Borrowed from https://github.com/japaric/heapless/blob/master/src/ring_buffer/mod.rs
20- /// See: https://github.com/japaric/heapless/commit/37c8b5b63780ed8811173dc1ec8859cd99efa9ad
21- struct AtomicUsize {
22- v : UnsafeCell < usize > ,
23- }
24-
25- impl AtomicUsize {
26- crate const fn new ( v : usize ) -> AtomicUsize {
27- AtomicUsize {
28- v : UnsafeCell :: new ( v) ,
29- }
30- }
31-
32- crate fn load_relaxed ( & self ) -> usize {
33- unsafe { intrinsics:: atomic_load_relaxed ( self . v . get ( ) ) }
34- }
35-
36- crate fn store_relaxed ( & self , val : usize ) {
37- unsafe { intrinsics:: atomic_store_relaxed ( self . v . get ( ) , val) }
38- }
39-
40- crate fn fetch_or_relaxed ( & self , val : usize ) {
41- unsafe { intrinsics:: atomic_store_relaxed ( self . v . get ( ) , self . load_relaxed ( ) | val) }
42- }
43- }
44-
45- unsafe impl Sync for AtomicUsize { }
11+ use core:: sync:: atomic:: AtomicUsize ;
12+ use core:: sync:: atomic:: Ordering ;
4613
4714static DEFERRED_CALL : AtomicUsize = AtomicUsize :: new ( 0 ) ;
4815
4916/// Are there any pending `DeferredCall`s?
5017pub fn has_tasks ( ) -> bool {
51- DEFERRED_CALL . load_relaxed ( ) != 0
18+ DEFERRED_CALL . load ( Ordering :: Relaxed ) != 0
5219}
5320
5421/// Represents a way to generate an asynchronous call without a hardware
@@ -66,18 +33,21 @@ impl<T: Into<usize> + TryFrom<usize> + Copy> DeferredCall<T> {
6633
6734 /// Set the `DeferredCall` as pending
6835 pub fn set ( & self ) {
69- DEFERRED_CALL . fetch_or_relaxed ( 1 << self . 0 . into ( ) as usize ) ;
36+ // DEFERRED_CALL.fetch_or(1 << self.0.into() as usize, Ordering::Relaxed);
37+ let val = DEFERRED_CALL . load ( Ordering :: Relaxed ) ;
38+ let new_val = val | ( 1 << self . 0 . into ( ) ) ;
39+ DEFERRED_CALL . store ( new_val, Ordering :: Relaxed ) ;
7040 }
7141
7242 /// Gets and clears the next pending `DeferredCall`
7343 pub fn next_pending ( ) -> Option < T > {
74- let val = DEFERRED_CALL . load_relaxed ( ) ;
44+ let val = DEFERRED_CALL . load ( Ordering :: Relaxed ) ;
7545 if val == 0 {
7646 None
7747 } else {
7848 let bit = val. trailing_zeros ( ) as usize ;
7949 let new_val = val & !( 1 << bit) ;
80- DEFERRED_CALL . store_relaxed ( new_val) ;
50+ DEFERRED_CALL . store ( new_val, Ordering :: Relaxed ) ;
8151 bit. try_into ( ) . ok ( )
8252 }
8353 }
0 commit comments