Skip to content

Commit 5028256

Browse files
authoredApr 1, 2020
Merge pull request #2 from Disasm/fix-races
Fix races
2 parents a008306 + 3d1ec33 commit 5028256

File tree

1 file changed

+15
-5
lines changed

1 file changed

+15
-5
lines changed
 

‎async-cortex-m/src/executor.rs

+15-5
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ static VTABLE: RawWakerVTable = {
3232
wake_by_ref(p)
3333
}
3434
unsafe fn wake_by_ref(p: *const ()) {
35-
(*(p as *const AtomicBool)).store(true, Ordering::Relaxed)
35+
(*(p as *const AtomicBool)).store(true, Ordering::Release)
3636
}
3737
unsafe fn drop(_: *const ()) {
3838
// no-op
@@ -66,9 +66,12 @@ impl Executor {
6666
let waker =
6767
unsafe { Waker::from_raw(RawWaker::new(&ready as *const _ as *const _, &VTABLE)) };
6868
let val = loop {
69+
let mut task_woken = false;
70+
6971
// advance the main task
70-
if ready.load(Ordering::Relaxed) {
71-
ready.store(false, Ordering::Relaxed);
72+
if ready.load(Ordering::Acquire) {
73+
task_woken = true;
74+
ready.store(false, Ordering::Release);
7275

7376
let mut cx = Context::from_waker(&waker);
7477
if let Poll::Ready(val) = f.as_mut().poll(&mut cx) {
@@ -87,9 +90,11 @@ impl Executor {
8790
// interrupt handlers (the only source of 'race conditions' (!= data races)) are
8891
// "oneshot": they'll issue a `wake` and then disable themselves to not run again
8992
// until the woken task has made more work
90-
if task.ready.load(Ordering::Relaxed) {
93+
if task.ready.load(Ordering::Acquire) {
94+
task_woken = true;
95+
9196
// we are about to service the task so switch the `ready` flag to `false`
92-
task.ready.store(false, Ordering::Relaxed);
97+
task.ready.store(false, Ordering::Release);
9398

9499
// NOTE we never deallocate tasks so `&ready` is always pointing to
95100
// allocated memory (`&'static AtomicBool`)
@@ -108,6 +113,11 @@ impl Executor {
108113
}
109114
}
110115

116+
if task_woken {
117+
// If at least one task was woken up, do not sleep, try again
118+
continue;
119+
}
120+
111121
// try to sleep; this will be a no-op if any of the previous tasks generated a SEV or an
112122
// interrupt ran (regardless of whether it generated a wake-up or not)
113123
asm::wfe();

0 commit comments

Comments
 (0)
Failed to load comments.