use core::cmp::{self, PartialOrd};
use core::sync::atomic::{AtomicU32, AtomicU8, Ordering};
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq)]
enum TaskState {
Ready = 0,
Sleep = 1,
Suspend = 2,
}
impl From<u8> for TaskState {
fn from(v: u8) -> Self {
match v {
0 => TaskState::Ready,
1 => TaskState::Sleep,
2 => TaskState::Suspend,
_ => panic!("Invalid task state"),
}
}
}
#[derive(Debug)]
pub struct Task {
pub id: usize,
pub priority: u8,
pub stack_ptr: AtomicU32,
wake_tick: AtomicU32,
state: AtomicU8,
}
impl Task {
pub const fn new(id: usize, priority: u8) -> Self {
Task {
id: id,
priority: priority,
stack_ptr: AtomicU32::new(0),
state: AtomicU8::new(TaskState::Ready as u8),
wake_tick: AtomicU32::new(0),
}
}
pub fn ready(&self) {
self.state.store(TaskState::Ready as u8, Ordering::Relaxed);
}
pub fn is_ready(&self) -> bool {
TaskState::from(self.state.load(Ordering::Relaxed)) == TaskState::Ready
}
pub fn sleep(&self, wake_tick: u32) {
self.wake_tick.store(wake_tick, Ordering::Relaxed);
self.state.store(TaskState::Sleep as u8, Ordering::Relaxed);
}
pub fn is_sleep(&self) -> bool {
TaskState::from(self.state.load(Ordering::Relaxed)) == TaskState::Sleep
}
pub fn suspend(&self) {
self.state
.store(TaskState::Suspend as u8, Ordering::Relaxed);
}
pub fn is_suspended(&self) -> bool {
TaskState::from(self.state.load(Ordering::Relaxed)) == TaskState::Suspend
}
pub fn wake_tick(&self) -> u32 {
self.wake_tick.load(Ordering::Relaxed)
}
}
impl PartialEq for Task {
fn eq(&self, other: &Self) -> bool {
self.priority == other.priority
}
}
impl PartialOrd for Task {
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
Some(self.priority.cmp(&other.priority))
}
}