moana_std 0.1.4

moana 用户标准库
Documentation
//! task 系列 syscall 用户态接口

use core::mem::MaybeUninit;

use moa_uapi::{
    error::{ERR_FAULT, ERR_INVAL, ERR_NO_RESOURCE, ERR_NOT_FOUND, ERR_PERM},
    sched::SchedParam,
    sysnr::{
        SYSNR_TASK_CLOSE, SYSNR_TASK_CREATE, SYSNR_TASK_GET_REGS, SYSNR_TASK_GET_STATUS,
        SYSNR_TASK_SET_POLICY, SYSNR_TASK_SET_REGS, SYSNR_TASK_START,
    },
    task::{RegMask, TaskCreateArgs, TaskHandle, TaskRegs, TaskStatus},
};

/// task 系列 syscall 返回类型
pub type Result<T> = core::result::Result<T, TaskError>;

define_syscall_error! {
    /// task 系列 syscall 错误
    pub enum TaskError {
        /// 权限不足
        Perm = ERR_PERM,
        /// 句柄不存在
        NotFound = ERR_NOT_FOUND,
        /// 无效参数
        Inval = ERR_INVAL,
        /// 资源配额耗尽
        NoResource = ERR_NO_RESOURCE,
        /// 无效指针
        Fault = ERR_FAULT,
    }
}

/// 创建任务,绑定地址空间和异常通知通道
///
/// `space = SpaceHandle::SELF` 时在调用者地址空间创建线程,
/// 否则在指定地址空间创建进程的首个线程。
/// 任务初始状态为 NEW,需 `task_set_regs` 设置寄存器后 `task_start` 启动。
pub fn task_create(args: &TaskCreateArgs) -> Result<TaskHandle> {
    let ret =
        unsafe { super::arch::syscall1(SYSNR_TASK_CREATE, args as *const TaskCreateArgs as usize) };
    if ret < 0 {
        Err(TaskError::from_raw(ret))
    } else {
        // ret >= 0 且 handle 值在 u32 范围内,截断安全
        Ok(TaskHandle::from_raw(ret as u32))
    }
}

/// 终止并释放任务
///
/// 移出调度器、清理等待队列,并通过 exception channel 通知创建者。
/// 不释放地址空间和句柄表(属于 `AddressSpace`)。
pub fn task_close(task: TaskHandle) -> Result<()> {
    let ret = unsafe { super::arch::syscall1(SYSNR_TASK_CLOSE, task.raw() as usize) };
    if ret < 0 { Err(TaskError::from_raw(ret)) } else { Ok(()) }
}

/// 首次启动任务(NEW → RUNNING)
///
/// 启动前需先通过 `task_set_regs` 设置好寄存器。
pub fn task_start(task: TaskHandle) -> Result<()> {
    let ret = unsafe { super::arch::syscall1(SYSNR_TASK_START, task.raw() as usize) };
    if ret < 0 { Err(TaskError::from_raw(ret)) } else { Ok(()) }
}

/// 设置任务寄存器(pc/sp/tls/a0-a7)
///
/// `mask` 指定要设置的寄存器,未标记的寄存器保持不变。
/// 首次设置时使用 `RegMask::all()` 设置全部。
pub fn task_set_regs(task: TaskHandle, mask: RegMask, regs: &TaskRegs) -> Result<()> {
    let ret = unsafe {
        super::arch::syscall3(
            SYSNR_TASK_SET_REGS,
            task.raw() as usize,
            mask.bits() as usize,
            regs as *const TaskRegs as usize,
        )
    };
    if ret < 0 { Err(TaskError::from_raw(ret)) } else { Ok(()) }
}

/// 读取任务寄存器
pub fn task_get_regs(task: TaskHandle) -> Result<TaskRegs> {
    let mut regs = MaybeUninit::<TaskRegs>::uninit();
    let ret = unsafe {
        super::arch::syscall2(SYSNR_TASK_GET_REGS, task.raw() as usize, regs.as_mut_ptr() as usize)
    };
    if ret < 0 { Err(TaskError::from_raw(ret)) } else { Ok(unsafe { regs.assume_init() }) }
}

/// 查询任务状态(所属地址空间、是否存活、退出码)
pub fn task_get_status(task: TaskHandle) -> Result<TaskStatus> {
    let mut status = MaybeUninit::<TaskStatus>::uninit();
    let ret = unsafe {
        super::arch::syscall2(
            SYSNR_TASK_GET_STATUS,
            task.raw() as usize,
            status.as_mut_ptr() as usize,
        )
    };
    if ret < 0 { Err(TaskError::from_raw(ret)) } else { Ok(unsafe { status.assume_init() }) }
}

/// 设置任务调度策略
///
/// 可在任务运行中动态修改。
pub fn task_set_policy(task: TaskHandle, param: &SchedParam) -> Result<()> {
    let ret = unsafe {
        super::arch::syscall2(
            SYSNR_TASK_SET_POLICY,
            task.raw() as usize,
            param as *const SchedParam as usize,
        )
    };
    if ret < 0 { Err(TaskError::from_raw(ret)) } else { Ok(()) }
}