Skip to content

Commit

Permalink
Tidy the code a bit
Browse files Browse the repository at this point in the history
  • Loading branch information
jannic committed Sep 9, 2024
1 parent 0fcc24a commit 985274e
Showing 1 changed file with 15 additions and 14 deletions.
29 changes: 15 additions & 14 deletions on-target-tests/tests/i2c_tests/test_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use core::{
future::Future,
pin::{self, Pin},
ptr::addr_of,
ptr,
sync::atomic::{AtomicBool, Ordering},
task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
};
Expand All @@ -19,33 +19,30 @@ use once_cell::sync::OnceCell;
static WOKE: AtomicBool = AtomicBool::new(false);
static POLLING: AtomicBool = AtomicBool::new(false);

static VTABLE: RawWakerVTable = RawWakerVTable::new(clone_fn, wake_fn, wake_fn, drop_fn);

fn wake_fn(_data: *const ()) {
if !POLLING.load(Ordering::Relaxed) {
defmt::info!("waker called while not polling");
}
WOKE.store(true, Ordering::Relaxed);
}

const fn clone_fn(data: *const ()) -> RawWaker {
RawWaker::new(data, raw_waker_vtable())
fn clone_fn(data: *const ()) -> RawWaker {
RawWaker::new(data, &VTABLE)
}

fn drop_fn(_data: *const ()) {}

const fn raw_waker_vtable() -> &'static RawWakerVTable {
const VTABLE: RawWakerVTable = RawWakerVTable::new(clone_fn, wake_fn, wake_fn, drop_fn);
&VTABLE
}

fn context() -> Context<'static> {
static DATA: () = ();

static WAKER: OnceCell<Waker> = OnceCell::new();
// Safety: The functions in the vtable of this executor only modify static atomics.
let waker = WAKER.get_or_init(|| unsafe { Waker::from_raw(clone_fn(addr_of!(DATA))) });
let waker =
WAKER.get_or_init(|| unsafe { Waker::from_raw(RawWaker::new(ptr::null(), &VTABLE)) });

// Starting from rust 1.82.0, this could be used:
// static WAKER: Waker = unsafe { Waker::from_raw(clone_fn(addr_of!(DATA))) };
// static WAKER: Waker = unsafe { Waker::from_raw(RawWaker::new(ptr::null(), &VTABLE)) };
// (stabilized by https://github.com/rust-lang/rust/pull/128228)

Context::from_waker(waker)
}
Expand All @@ -56,6 +53,9 @@ fn context() -> Context<'static> {
/// if the waker is properly triggered from an interrupt.
///
/// This won't work as expected of multiple calls to `execute` happen concurrently.
///
/// (Calling this function from multiple threads concurrently doesn't violate any
/// safety guarantees, but wakers may wake the wrong task, making futures stall.)
pub fn execute<T>(future: impl Future<Output = T>) -> T {
let mut pinned: Pin<&mut _> = pin::pin!(future);
if WOKE.load(Ordering::Relaxed) {
Expand All @@ -70,9 +70,10 @@ pub fn execute<T>(future: impl Future<Output = T>) -> T {
break result;
}
while !WOKE.load(Ordering::Relaxed) {
// In a real executor, there should be a WFI/WFE or similar here, to avoid
// busy looping.
// As this is only a test executor, we don't care.
core::hint::spin_loop();
// TODO WFI or similar?
// But probably not important for this test executor
}
}
}

0 comments on commit 985274e

Please sign in to comment.