4
4
//! in the chip scheduler if the hardware doesn't support interrupts where
5
5
//! they are needed.
6
6
7
- use core:: cell:: UnsafeCell ;
8
7
use core:: convert:: Into ;
9
8
use core:: convert:: TryFrom ;
10
9
use core:: convert:: TryInto ;
11
- use core:: intrinsics;
12
10
use 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 ;
46
13
47
14
static DEFERRED_CALL : AtomicUsize = AtomicUsize :: new ( 0 ) ;
48
15
49
16
/// Are there any pending `DeferredCall`s?
50
17
pub fn has_tasks ( ) -> bool {
51
- DEFERRED_CALL . load_relaxed ( ) != 0
18
+ DEFERRED_CALL . load ( Ordering :: Relaxed ) != 0
52
19
}
53
20
54
21
/// Represents a way to generate an asynchronous call without a hardware
@@ -66,18 +33,21 @@ impl<T: Into<usize> + TryFrom<usize> + Copy> DeferredCall<T> {
66
33
67
34
/// Set the `DeferredCall` as pending
68
35
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 ) ;
70
40
}
71
41
72
42
/// Gets and clears the next pending `DeferredCall`
73
43
pub fn next_pending ( ) -> Option < T > {
74
- let val = DEFERRED_CALL . load_relaxed ( ) ;
44
+ let val = DEFERRED_CALL . load ( Ordering :: Relaxed ) ;
75
45
if val == 0 {
76
46
None
77
47
} else {
78
48
let bit = val. trailing_zeros ( ) as usize ;
79
49
let new_val = val & !( 1 << bit) ;
80
- DEFERRED_CALL . store_relaxed ( new_val) ;
50
+ DEFERRED_CALL . store ( new_val, Ordering :: Relaxed ) ;
81
51
bit. try_into ( ) . ok ( )
82
52
}
83
53
}
0 commit comments