use core::sync::atomic::Ordering;
use core::task::{RawWaker, RawWakerVTable, Waker};
use crate::no_alloc::executor::GLOBAL_QUEUES;
use crate::no_alloc::lifo::Worker;
use crate::no_alloc::task::{State, TaskHeader};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum WakePolicy {
PollOnly = 0b00, InterruptOnly = 0b01, Hybrid = 0b10, }
impl WakePolicy {
pub const WAKE_BIT: u8 = 0b1000_0000; const POLICY_MASK: u8 = 0b0000_0011;
#[inline(always)]
pub fn unpack(control: u8) -> (Self, bool) {
let policy = match control & Self::POLICY_MASK {
0b00 => Self::PollOnly,
0b01 => Self::InterruptOnly,
0b10 => Self::Hybrid,
_ => unreachable!("Invalid WakePolicy"),
};
let is_waked = (control & Self::WAKE_BIT) != 0;
(policy, is_waked)
}
#[inline(always)]
pub fn should_poll(self, is_waked: bool) -> bool {
match self {
Self::PollOnly => true,
Self::Hybrid => true,
Self::InterruptOnly => is_waked,
}
}
}
static VTABLE: RawWakerVTable = RawWakerVTable::new(
waker_clone,
waker_wake,
waker_wake_by_ref,
waker_drop,
);
unsafe fn waker_clone(ptr: *const ()) -> RawWaker {
RawWaker::new(ptr, &VTABLE)
}
unsafe fn waker_wake(ptr: *const ()) {
let task_ptr = ptr as *mut TaskHeader;
let header = &*task_ptr;
header.state.store(State::Ready.into(), Ordering::Release);
let core_id = header.control.load(Ordering::Relaxed) as usize;
let worker = Worker::new(&GLOBAL_QUEUES[core_id]);
let _ = worker.push(task_ptr);
}
unsafe fn waker_wake_by_ref(ptr: *const ()) {
waker_wake(ptr);
}
unsafe fn waker_drop(_ptr: *const ()) {
}