Skip to content

Commit 7f20daa

Browse files
committed
kernel: common: use built in AtomicUsize
Since rust-lang/rust#51953 was merged, there is now support for atomic load and store with cortex-m0 in rust by default.
1 parent 3c00c39 commit 7f20daa

File tree

1 file changed

+9
-39
lines changed

1 file changed

+9
-39
lines changed

kernel/src/common/deferred_call.rs

Lines changed: 9 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,51 +4,18 @@
44
//! in the chip scheduler if the hardware doesn't support interrupts where
55
//! they are needed.
66
7-
use core::cell::UnsafeCell;
87
use core::convert::Into;
98
use core::convert::TryFrom;
109
use core::convert::TryInto;
11-
use core::intrinsics;
1210
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;
4613

4714
static DEFERRED_CALL: AtomicUsize = AtomicUsize::new(0);
4815

4916
/// Are there any pending `DeferredCall`s?
5017
pub 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

Comments
 (0)