@@ -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