moana_std 0.1.2

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

use moa_uapi::{
    channel::ChanHandle,
    error::{ERR_INVAL, ERR_NO_RESOURCE, ERR_NOT_FOUND, ERR_PERM},
    sysnr::{
        SYSNR_TIMER_BIND, SYSNR_TIMER_CLOSE, SYSNR_TIMER_CREATE, SYSNR_TIMER_SET,
        SYSNR_TIMER_UNBIND,
    },
    timer::{ClockId, TimerFlags, TimerHandle},
};

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

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

/// 创建定时器
///
/// 创建后需 `timer_bind` 绑定 channel 才能接收到期通知。
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
pub fn timer_create(clock_id: ClockId) -> Result<TimerHandle> {
    let ret = unsafe { super::arch::syscall1(SYSNR_TIMER_CREATE, clock_id as usize) };
    if ret < 0 { Err(TimerError::from_raw(ret)) } else { Ok(TimerHandle::from_raw(ret as u32)) }
}

/// 绑定定时器到通道
///
/// 到期时内核向指定 channel 发送 pulse。
pub fn timer_bind(timer: TimerHandle, chan: ChanHandle) -> Result<()> {
    let ret = unsafe {
        super::arch::syscall2(SYSNR_TIMER_BIND, timer.raw() as usize, chan.raw() as usize)
    };
    if ret < 0 { Err(TimerError::from_raw(ret)) } else { Ok(()) }
}

/// 解绑定时器
///
/// 不销毁定时器,可重新 `timer_bind` 到其他 channel。
pub fn timer_unbind(timer: TimerHandle) -> Result<()> {
    let ret = unsafe { super::arch::syscall1(SYSNR_TIMER_UNBIND, timer.raw() as usize) };
    if ret < 0 { Err(TimerError::from_raw(ret)) } else { Ok(()) }
}

/// 设置定时器参数
///
/// `initial` 为首次到期时间(纳秒),0 表示停止定时器。
/// `interval` 为重复间隔(纳秒),0 表示单次触发。
#[allow(clippy::cast_possible_truncation)]
pub fn timer_set(timer: TimerHandle, flags: TimerFlags, initial: u64, interval: u64) -> Result<()> {
    let ret = unsafe {
        super::arch::syscall4(
            SYSNR_TIMER_SET,
            timer.raw() as usize,
            flags.bits() as usize,
            initial as usize,
            interval as usize,
        )
    };
    if ret < 0 { Err(TimerError::from_raw(ret)) } else { Ok(()) }
}

/// 销毁定时器(自动 unbind)
pub fn timer_close(timer: TimerHandle) -> Result<()> {
    let ret = unsafe { super::arch::syscall1(SYSNR_TIMER_CLOSE, timer.raw() as usize) };
    if ret < 0 { Err(TimerError::from_raw(ret)) } else { Ok(()) }
}