extern crate alloc;
use alloc::boxed::Box;
use core::{
sync::atomic::{AtomicPtr, Ordering},
task::{Context, Poll},
};
pub type PollFn<'a> = dyn FnMut(&mut Context<'_>) -> Poll<()> + 'a;
pub type SendPollFn = dyn FnMut(&mut Context<'_>) -> Poll<()> + Send;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct TimedOut;
pub trait WifiRuntime: Send + Sync + 'static {
fn now_nanos(&self) -> u64;
fn sleep_ms(&self, ms: u64);
fn yield_now(&self);
fn spawn_poll_task(&self, name: &str, poll: Box<SendPollFn>);
fn block_until(&self, timeout_ms: Option<u64>, poll: &mut PollFn<'_>) -> Result<(), TimedOut>;
}
static RUNTIME: AtomicPtr<&'static dyn WifiRuntime> = AtomicPtr::new(core::ptr::null_mut());
pub fn set_runtime(rt: &'static dyn WifiRuntime) {
let boxed = Box::new(rt);
let ptr = Box::into_raw(boxed);
let old = RUNTIME.swap(ptr, Ordering::AcqRel);
if !old.is_null() {
unsafe { drop(Box::from_raw(old)) };
}
}
pub(crate) fn runtime() -> &'static dyn WifiRuntime {
let ptr = RUNTIME.load(Ordering::Acquire);
assert!(
!ptr.is_null(),
"aic8800: WifiRuntime not installed; call aic8800::set_runtime() during init"
);
unsafe { *ptr }
}