use core::mem::MaybeUninit;
use moa_cpumask::CpuId;
use moa_uapi::{
channel::ChanHandle,
error::{ERR_BUSY, ERR_FAULT, ERR_INVAL, ERR_NOT_FOUND, ERR_PERM},
sched::{SchedFlags, SchedHandle, SchedLoad, SchedStateInfo},
space::SpaceId,
sysnr::{
SYSNR_SCHED_GET_STATE, SYSNR_SCHED_GET_TASK_LOAD, SYSNR_SCHED_REGISTER, SYSNR_SCHED_RESUME,
SYSNR_SCHED_SET_CPU, SYSNR_SCHED_SET_MODE, SYSNR_SCHED_SUSPEND, SYSNR_SCHED_UNREGISTER,
},
};
pub type Result<T> = core::result::Result<T, SchedError>;
define_syscall_error! {
pub enum SchedError {
Perm = ERR_PERM,
NotFound = ERR_NOT_FOUND,
Inval = ERR_INVAL,
Fault = ERR_FAULT,
Busy = ERR_BUSY,
}
}
pub fn sched_register(spaceid: SpaceId, chan: ChanHandle, flags: SchedFlags) -> Result<()> {
let ret = unsafe {
super::arch::syscall3(
SYSNR_SCHED_REGISTER,
spaceid.raw(),
chan.raw() as usize,
flags.bits() as usize,
)
};
if ret < 0 { Err(SchedError::from_raw(ret)) } else { Ok(()) }
}
pub fn sched_unregister() -> Result<()> {
let ret = unsafe { super::arch::syscall0(SYSNR_SCHED_UNREGISTER) };
if ret < 0 { Err(SchedError::from_raw(ret)) } else { Ok(()) }
}
pub fn sched_set_mode(flags: SchedFlags) -> Result<()> {
let ret = unsafe { super::arch::syscall1(SYSNR_SCHED_SET_MODE, flags.bits() as usize) };
if ret < 0 { Err(SchedError::from_raw(ret)) } else { Ok(()) }
}
pub fn sched_resume(sched: SchedHandle) -> Result<()> {
let ret = unsafe { super::arch::syscall1(SYSNR_SCHED_RESUME, sched.raw() as usize) };
if ret < 0 { Err(SchedError::from_raw(ret)) } else { Ok(()) }
}
pub fn sched_suspend(sched: SchedHandle) -> Result<()> {
let ret = unsafe { super::arch::syscall1(SYSNR_SCHED_SUSPEND, sched.raw() as usize) };
if ret < 0 { Err(SchedError::from_raw(ret)) } else { Ok(()) }
}
pub fn sched_set_cpu(sched: SchedHandle, cpuid: CpuId) -> Result<()> {
let ret =
unsafe { super::arch::syscall2(SYSNR_SCHED_SET_CPU, sched.raw() as usize, cpuid.raw()) };
if ret < 0 { Err(SchedError::from_raw(ret)) } else { Ok(()) }
}
pub fn sched_get_state(sched: SchedHandle) -> Result<SchedStateInfo> {
let mut info = MaybeUninit::<SchedStateInfo>::uninit();
let ret = unsafe {
super::arch::syscall2(
SYSNR_SCHED_GET_STATE,
sched.raw() as usize,
info.as_mut_ptr() as usize,
)
};
if ret < 0 { Err(SchedError::from_raw(ret)) } else { Ok(unsafe { info.assume_init() }) }
}
pub fn sched_get_task_load(sched: SchedHandle) -> Result<SchedLoad> {
let mut load = MaybeUninit::<SchedLoad>::uninit();
let ret = unsafe {
super::arch::syscall2(
SYSNR_SCHED_GET_TASK_LOAD,
sched.raw() as usize,
load.as_mut_ptr() as usize,
)
};
if ret < 0 { Err(SchedError::from_raw(ret)) } else { Ok(unsafe { load.assume_init() }) }
}