use core::{fmt, marker::PhantomData, mem::MaybeUninit};
use crate::{
abi,
error::{Error, ErrorCode, ErrorKind, Kind},
processor::Processor,
time::{Duration, Timeout},
};
define_error_kind! {
pub enum ActivateError {
#[cfg(not(feature = "none"))]
BadContext,
#[cfg(not(feature = "none"))]
BadId,
#[cfg(any())]
AccessDenied,
#[cfg(not(feature = "none"))]
QueueOverflow,
}
}
impl ErrorKind for ActivateError {
fn from_error_code(code: ErrorCode) -> Option<Self> {
match code.get() {
#[cfg(not(feature = "none"))]
abi::E_CTX => Some(Self::BadContext(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_ID | abi::E_NOEXS => Some(Self::BadId(Kind::from_error_code(code))),
#[cfg(any())]
abi::E_OACV => Some(Self::AccessDenied(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_QOVR => Some(Self::QueueOverflow(Kind::from_error_code(code))),
_ => None,
}
}
}
define_error_kind! {
pub enum ActivateOnError {
#[cfg(not(feature = "none"))]
BadContext,
#[cfg(not(feature = "none"))]
BadId,
#[cfg(all(feature = "rstr_task", any()))]
NotSupported,
#[cfg(any())]
AccessDenied,
#[cfg(not(feature = "none"))]
QueueOverflow,
#[cfg(any(feature = "fmp3", feature = "solid_fmp3"))]
BadParam,
}
}
impl ErrorKind for ActivateOnError {
fn from_error_code(code: ErrorCode) -> Option<Self> {
match code.get() {
#[cfg(not(feature = "none"))]
abi::E_CTX => Some(Self::BadContext(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_ID | abi::E_NOEXS => Some(Self::BadId(Kind::from_error_code(code))),
#[cfg(all(feature = "rstr_task", any()))]
abi::E_NOSPT => Some(Self::NotSupported(Kind::from_error_code(code))),
#[cfg(any())]
abi::E_OACV => Some(Self::AccessDenied(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_QOVR => Some(Self::QueueOverflow(Kind::from_error_code(code))),
#[cfg(any(feature = "fmp3", feature = "solid_fmp3"))]
abi::E_PAR => Some(Self::BadParam(Kind::from_error_code(code))),
_ => None,
}
}
}
define_error_kind! {
pub enum CancelActivateAllError {
#[cfg(not(feature = "none"))]
BadContext,
#[cfg(not(feature = "none"))]
BadId,
#[cfg(any())]
AccessDenied,
}
}
impl ErrorKind for CancelActivateAllError {
fn from_error_code(code: ErrorCode) -> Option<Self> {
match code.get() {
#[cfg(not(feature = "none"))]
abi::E_CTX => Some(Self::BadContext(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_ID | abi::E_NOEXS => Some(Self::BadId(Kind::from_error_code(code))),
#[cfg(any())]
abi::E_OACV => Some(Self::AccessDenied(Kind::from_error_code(code))),
_ => None,
}
}
}
define_error_kind! {
pub enum SetPriorityError {
#[cfg(not(feature = "none"))]
BadContext,
#[cfg(not(feature = "none"))]
BadId,
#[cfg(not(feature = "none"))]
BadState,
#[cfg(not(feature = "none"))]
BadParam,
#[cfg(any())]
AccessDenied,
}
}
impl ErrorKind for SetPriorityError {
fn from_error_code(code: ErrorCode) -> Option<Self> {
match code.get() {
#[cfg(not(feature = "none"))]
abi::E_CTX => Some(Self::BadContext(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_ID | abi::E_NOEXS => Some(Self::BadId(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_OBJ => Some(Self::BadState(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_PAR | abi::E_NOSPT | abi::E_ILUSE => {
Some(Self::BadParam(Kind::from_error_code(code)))
}
#[cfg(any())]
abi::E_OACV => Some(Self::AccessDenied(Kind::from_error_code(code))),
_ => None,
}
}
}
define_error_kind! {
pub enum PriorityError {
#[cfg(not(feature = "none"))]
BadContext,
#[cfg(not(feature = "none"))]
BadId,
#[cfg(not(feature = "none"))]
BadState,
#[cfg(any())]
AccessDenied,
}
}
impl ErrorKind for PriorityError {
fn from_error_code(code: ErrorCode) -> Option<Self> {
match code.get() {
#[cfg(not(feature = "none"))]
abi::E_CTX => Some(Self::BadContext(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_ID | abi::E_NOEXS => Some(Self::BadId(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_OBJ => Some(Self::BadState(Kind::from_error_code(code))),
#[cfg(any())]
abi::E_OACV => Some(Self::AccessDenied(Kind::from_error_code(code))),
_ => None,
}
}
}
define_error_kind! {
pub enum MigrateError {
#[cfg(any(feature = "fmp3", feature = "solid_fmp3"))]
BadContext,
#[cfg(any(feature = "fmp3", feature = "solid_fmp3"))]
BadId,
#[cfg(any(feature = "fmp3", feature = "solid_fmp3"))]
BadParam,
#[cfg(any())]
AccessDenied,
}
}
#[cfg(any(feature = "none", feature = "fmp3", feature = "solid_fmp3"))]
impl ErrorKind for MigrateError {
fn from_error_code(code: ErrorCode) -> Option<Self> {
match code.get() {
#[cfg(any(feature = "fmp3", feature = "solid_fmp3"))]
abi::E_CTX => Some(Self::BadContext(Kind::from_error_code(code))),
#[cfg(any(feature = "fmp3", feature = "solid_fmp3"))]
abi::E_ID | abi::E_NOEXS => Some(Self::BadId(Kind::from_error_code(code))),
#[cfg(any(feature = "fmp3", feature = "solid_fmp3"))]
abi::E_PAR | abi::E_NOSPT | abi::E_OBJ => {
Some(Self::BadParam(Kind::from_error_code(code)))
}
#[cfg(any())]
abi::E_OACV => Some(Self::AccessDenied(Kind::from_error_code(code))),
_ => None,
}
}
}
define_error_kind! {
#[cfg(feature = "dcre")]
#[cfg_attr(feature = "doc_cfg", doc(cfg(feature = "dcre")))]
pub enum DeleteError {
#[cfg(not(feature = "none"))]
BadContext,
#[cfg(not(feature = "none"))]
BadId,
#[cfg(any())]
AccessDenied,
#[cfg(not(feature = "none"))]
BadState,
}
}
#[cfg(feature = "dcre")]
impl ErrorKind for DeleteError {
fn from_error_code(code: ErrorCode) -> Option<Self> {
match code.get() {
#[cfg(not(feature = "none"))]
abi::E_CTX => Some(Self::BadContext(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_ID | abi::E_NOEXS => Some(Self::BadId(Kind::from_error_code(code))),
#[cfg(any())]
abi::E_OACV => Some(Self::AccessDenied(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_OBJ => Some(Self::BadState(Kind::from_error_code(code))),
_ => None,
}
}
}
define_error_kind! {
pub enum StateError {
#[cfg(not(feature = "none"))]
BadContext,
#[cfg(not(feature = "none"))]
BadId,
#[cfg(any())]
AccessDenied,
}
}
impl ErrorKind for StateError {
fn from_error_code(code: ErrorCode) -> Option<Self> {
match code.get() {
#[cfg(not(feature = "none"))]
abi::E_CTX => Some(Self::BadContext(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_ID | abi::E_NOEXS => Some(Self::BadId(Kind::from_error_code(code))),
#[cfg(any())]
abi::E_OACV => Some(Self::AccessDenied(Kind::from_error_code(code))),
_ => None,
}
}
}
define_error_kind! {
pub enum InfoError {
#[cfg(not(feature = "none"))]
BadContext,
#[cfg(not(feature = "none"))]
BadId,
#[cfg(any())]
AccessDenied,
}
}
impl ErrorKind for InfoError {
fn from_error_code(code: ErrorCode) -> Option<Self> {
match code.get() {
#[cfg(not(feature = "none"))]
abi::E_CTX => Some(Self::BadContext(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_ID | abi::E_NOEXS => Some(Self::BadId(Kind::from_error_code(code))),
#[cfg(any())]
abi::E_OACV => Some(Self::AccessDenied(Kind::from_error_code(code))),
_ => None,
}
}
}
define_error_kind! {
pub enum WakeError {
#[cfg(not(feature = "none"))]
BadContext,
#[cfg(not(feature = "none"))]
BadId,
#[cfg(all(not(feature = "none"), feature = "rstr_task"))]
NotSupported,
#[cfg(any())]
AccessDenied,
#[cfg(not(feature = "none"))]
BadState,
#[cfg(not(feature = "none"))]
QueueOverflow,
}
}
impl ErrorKind for WakeError {
fn from_error_code(code: ErrorCode) -> Option<Self> {
match code.get() {
#[cfg(not(feature = "none"))]
abi::E_CTX => Some(Self::BadContext(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_ID | abi::E_NOEXS => Some(Self::BadId(Kind::from_error_code(code))),
#[cfg(all(not(feature = "none"), feature = "rstr_task"))]
abi::E_NOSPT => Some(Self::NotSupported(Kind::from_error_code(code))),
#[cfg(any())]
abi::E_OACV => Some(Self::AccessDenied(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_OBJ => Some(Self::BadState(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_QOVR => Some(Self::QueueOverflow(Kind::from_error_code(code))),
_ => None,
}
}
}
define_error_kind! {
pub enum CancelWakeAllError {
#[cfg(not(feature = "none"))]
BadContext,
#[cfg(not(feature = "none"))]
BadId,
#[cfg(all(not(feature = "none"), feature = "rstr_task"))]
NotSupported,
#[cfg(any())]
AccessDenied,
#[cfg(not(feature = "none"))]
BadState,
}
}
impl ErrorKind for CancelWakeAllError {
fn from_error_code(code: ErrorCode) -> Option<Self> {
match code.get() {
#[cfg(not(feature = "none"))]
abi::E_CTX => Some(Self::BadContext(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_ID | abi::E_NOEXS => Some(Self::BadId(Kind::from_error_code(code))),
#[cfg(all(not(feature = "none"), feature = "rstr_task"))]
abi::E_NOSPT => Some(Self::NotSupported(Kind::from_error_code(code))),
#[cfg(any())]
abi::E_OACV => Some(Self::AccessDenied(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_OBJ => Some(Self::BadState(Kind::from_error_code(code))),
_ => None,
}
}
}
define_error_kind! {
pub enum ReleaseWaitError {
#[cfg(not(feature = "none"))]
BadContext,
#[cfg(not(feature = "none"))]
BadId,
#[cfg(all(not(feature = "none"), feature = "rstr_task"))]
NotSupported,
#[cfg(any())]
AccessDenied,
#[cfg(not(feature = "none"))]
BadState,
}
}
impl ErrorKind for ReleaseWaitError {
fn from_error_code(code: ErrorCode) -> Option<Self> {
match code.get() {
#[cfg(not(feature = "none"))]
abi::E_CTX => Some(Self::BadContext(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_ID | abi::E_NOEXS => Some(Self::BadId(Kind::from_error_code(code))),
#[cfg(all(not(feature = "none"), feature = "rstr_task"))]
abi::E_NOSPT => Some(Self::NotSupported(Kind::from_error_code(code))),
#[cfg(any())]
abi::E_OACV => Some(Self::AccessDenied(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_OBJ => Some(Self::BadState(Kind::from_error_code(code))),
_ => None,
}
}
}
define_error_kind! {
pub enum SuspendError {
#[cfg(not(feature = "none"))]
BadContext,
#[cfg(not(feature = "none"))]
BadId,
#[cfg(all(not(feature = "none"), feature = "rstr_task"))]
NotSupported,
#[cfg(any())]
AccessDenied,
#[cfg(not(feature = "none"))]
BadState,
#[cfg(not(feature = "none"))]
QueueOverflow,
}
}
impl ErrorKind for SuspendError {
fn from_error_code(code: ErrorCode) -> Option<Self> {
match code.get() {
#[cfg(not(feature = "none"))]
abi::E_CTX => Some(Self::BadContext(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_ID | abi::E_NOEXS => Some(Self::BadId(Kind::from_error_code(code))),
#[cfg(all(not(feature = "none"), feature = "rstr_task"))]
abi::E_NOSPT => Some(Self::NotSupported(Kind::from_error_code(code))),
#[cfg(any())]
abi::E_OACV => Some(Self::AccessDenied(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_OBJ | abi::E_RASTER => Some(Self::BadState(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_QOVR => Some(Self::QueueOverflow(Kind::from_error_code(code))),
_ => None,
}
}
}
define_error_kind! {
pub enum ResumeError {
#[cfg(not(feature = "none"))]
BadContext,
#[cfg(not(feature = "none"))]
BadId,
#[cfg(all(not(feature = "none"), feature = "rstr_task"))]
NotSupported,
#[cfg(any())]
AccessDenied,
#[cfg(not(feature = "none"))]
BadState,
}
}
impl ErrorKind for ResumeError {
fn from_error_code(code: ErrorCode) -> Option<Self> {
match code.get() {
#[cfg(not(feature = "none"))]
abi::E_CTX => Some(Self::BadContext(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_ID | abi::E_NOEXS => Some(Self::BadId(Kind::from_error_code(code))),
#[cfg(all(not(feature = "none"), feature = "rstr_task"))]
abi::E_NOSPT => Some(Self::NotSupported(Kind::from_error_code(code))),
#[cfg(any())]
abi::E_OACV => Some(Self::AccessDenied(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_OBJ => Some(Self::BadState(Kind::from_error_code(code))),
_ => None,
}
}
}
define_error_kind! {
pub enum TerminateError {
#[cfg(not(feature = "none"))]
BadContext,
#[cfg(not(feature = "none"))]
BadId,
#[cfg(any())]
AccessDenied,
#[cfg(not(feature = "none"))]
BadState,
#[cfg(not(feature = "none"))]
BadParam,
}
}
impl ErrorKind for TerminateError {
fn from_error_code(code: ErrorCode) -> Option<Self> {
match code.get() {
#[cfg(not(feature = "none"))]
abi::E_CTX => Some(Self::BadContext(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_ID | abi::E_NOEXS => Some(Self::BadId(Kind::from_error_code(code))),
#[cfg(any())]
abi::E_OACV => Some(Self::AccessDenied(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_OBJ => Some(Self::BadState(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_ILUSE => Some(Self::BadParam(Kind::from_error_code(code))),
_ => None,
}
}
}
define_error_kind! {
pub enum RaiseTerminationError {
#[cfg(not(feature = "none"))]
BadContext,
#[cfg(not(feature = "none"))]
BadId,
#[cfg(any())]
AccessDenied,
#[cfg(not(feature = "none"))]
BadState,
#[cfg(not(feature = "none"))]
BadParam,
}
}
impl ErrorKind for RaiseTerminationError {
fn from_error_code(code: ErrorCode) -> Option<Self> {
match code.get() {
#[cfg(not(feature = "none"))]
abi::E_CTX => Some(Self::BadContext(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_ID | abi::E_NOEXS => Some(Self::BadId(Kind::from_error_code(code))),
#[cfg(any())]
abi::E_OACV => Some(Self::AccessDenied(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_OBJ => Some(Self::BadState(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_ILUSE => Some(Self::BadParam(Kind::from_error_code(code))),
_ => None,
}
}
}
define_error_kind! {
pub enum SleepError {
#[cfg(not(feature = "none"))]
BadContext,
#[cfg(all(not(feature = "none"), feature = "rstr_task"))]
NotSupported,
#[cfg(not(feature = "none"))]
Released,
#[cfg(not(feature = "none"))]
TerminateRequest,
}
}
impl ErrorKind for SleepError {
fn from_error_code(code: ErrorCode) -> Option<Self> {
match code.get() {
#[cfg(not(feature = "none"))]
abi::E_CTX => Some(Self::BadContext(Kind::from_error_code(code))),
#[cfg(all(not(feature = "none"), feature = "rstr_task"))]
abi::E_NOSPT => Some(Self::NotSupported(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_RLWAI => Some(Self::Released(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_RASTER => Some(Self::TerminateRequest(Kind::from_error_code(code))),
_ => None,
}
}
}
define_error_kind! {
pub enum SleepTimeoutError {
#[cfg(not(feature = "none"))]
BadContext,
#[cfg(all(not(feature = "none"), feature = "rstr_task"))]
NotSupported,
#[cfg(not(feature = "none"))]
Timeout,
#[cfg(not(feature = "none"))]
Released,
#[cfg(not(feature = "none"))]
TerminateRequest,
}
}
impl ErrorKind for SleepTimeoutError {
fn from_error_code(code: ErrorCode) -> Option<Self> {
match code.get() {
#[cfg(not(feature = "none"))]
abi::E_CTX => Some(Self::BadContext(Kind::from_error_code(code))),
#[cfg(all(not(feature = "none"), feature = "rstr_task"))]
abi::E_NOSPT => Some(Self::NotSupported(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_TMOUT => Some(Self::Timeout(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_RLWAI => Some(Self::Released(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_RASTER => Some(Self::TerminateRequest(Kind::from_error_code(code))),
_ => None,
}
}
}
define_error_kind! {
pub enum DelayError {
#[cfg(not(feature = "none"))]
BadContext,
#[cfg(all(not(feature = "none"), feature = "rstr_task"))]
NotSupported,
#[cfg(not(feature = "none"))]
Released,
#[cfg(not(feature = "none"))]
TerminateRequest,
}
}
impl ErrorKind for DelayError {
fn from_error_code(code: ErrorCode) -> Option<Self> {
match code.get() {
#[cfg(not(feature = "none"))]
abi::E_CTX => Some(Self::BadContext(Kind::from_error_code(code))),
#[cfg(all(not(feature = "none"), feature = "rstr_task"))]
abi::E_NOSPT => Some(Self::NotSupported(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_RLWAI => Some(Self::Released(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_RASTER => Some(Self::TerminateRequest(Kind::from_error_code(code))),
_ => None,
}
}
}
define_error_kind! {
pub enum ExitError {
#[cfg(not(feature = "none"))]
BadContext,
}
}
impl ErrorKind for ExitError {
fn from_error_code(code: ErrorCode) -> Option<Self> {
match code.get() {
#[cfg(not(feature = "none"))]
abi::E_CTX => Some(Self::BadContext(Kind::from_error_code(code))),
_ => None,
}
}
}
define_error_kind! {
pub enum DisableTerminationError {
#[cfg(not(feature = "none"))]
BadContext,
#[cfg(any())]
AccessDenied,
}
}
impl ErrorKind for DisableTerminationError {
fn from_error_code(code: ErrorCode) -> Option<Self> {
match code.get() {
#[cfg(not(feature = "none"))]
abi::E_CTX => Some(Self::BadContext(Kind::from_error_code(code))),
#[cfg(any())]
abi::E_OACV => Some(Self::AccessDenied(Kind::from_error_code(code))),
_ => None,
}
}
}
pub type EnableTerminationError = DisableTerminationError;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct BadContextError(());
define_error_kind! {
pub enum CurrentIdError {
#[cfg(not(feature = "none"))]
BadContext,
}
}
impl ErrorKind for CurrentIdError {
fn from_error_code(code: ErrorCode) -> Option<Self> {
match code.get() {
#[cfg(not(feature = "none"))]
abi::E_CTX => Some(Self::BadContext(Kind::from_error_code(code))),
_ => None,
}
}
}
define_error_kind! {
#[cfg(feature = "dcre")]
#[cfg_attr(feature = "doc_cfg", doc(cfg(feature = "dcre")))]
pub enum BuildError {
#[cfg(not(feature = "none"))]
BadContext,
#[cfg(any())]
AccessDenied,
#[cfg(not(feature = "none"))]
OutOfMemory,
#[cfg(not(feature = "none"))]
BadParam,
}
}
#[cfg(feature = "dcre")]
impl ErrorKind for BuildError {
fn from_error_code(code: ErrorCode) -> Option<Self> {
match code.get() {
#[cfg(not(feature = "none"))]
abi::E_CTX => Some(Self::BadContext(Kind::from_error_code(code))),
#[cfg(any())]
abi::E_OACV => Some(Self::AccessDenied(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_NOID | abi::E_NOMEM => Some(Self::OutOfMemory(Kind::from_error_code(code))),
#[cfg(not(feature = "none"))]
abi::E_PAR => Some(Self::BadParam(Kind::from_error_code(code))),
#[cfg(any())]
abi::E_OBJ => Some(Self::BadParam(Kind::from_error_code(code))),
_ => None,
}
}
}
pub type Priority = abi::PRI;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u8)]
pub enum State {
Running = abi::TTS_RUN as u8,
Ready = abi::TTS_RDY as u8,
Waiting = abi::TTS_WAI as u8,
Suspended = abi::TTS_SUS as u8,
WaitingSuspended = abi::TTS_WAS as u8,
Dormant = abi::TTS_DMT as u8,
}
impl State {
#[inline]
unsafe fn from_abi_unchecked(x: abi::STAT) -> Self {
unsafe { core::mem::transmute(x as u8) }
}
}
#[derive(Debug, Clone, Copy)]
pub struct Info {
#[cfg(not(feature = "none"))]
raw: abi::T_RTSK,
}
impl Info {
#[inline]
pub fn state(&self) -> State {
match () {
#[cfg(not(feature = "none"))]
() => unsafe { State::from_abi_unchecked(self.raw.tskstat) },
#[cfg(feature = "none")]
() => unimplemented!(),
}
}
#[inline]
pub fn current_priority(&self) -> Priority {
match () {
#[cfg(not(feature = "none"))]
() => self.raw.tskpri,
#[cfg(feature = "none")]
() => unimplemented!(),
}
}
#[inline]
pub fn base_priority(&self) -> Priority {
match () {
#[cfg(not(feature = "none"))]
() => self.raw.tskbpri,
#[cfg(feature = "none")]
() => unimplemented!(),
}
}
}
#[inline]
#[doc(alias = "slp_tsk")]
#[doc(alias = "park")]
pub fn sleep() -> Result<(), Error<SleepError>> {
match () {
#[cfg(not(feature = "none"))]
() => unsafe {
Error::err_if_negative(abi::slp_tsk())?;
Ok(())
},
#[cfg(feature = "none")]
() => unimplemented!(),
}
}
#[inline]
#[doc(alias = "tslp_tsk")]
#[doc(alias = "park_timeout")]
pub fn sleep_timeout(tmo: Timeout) -> Result<(), Error<SleepTimeoutError>> {
match () {
#[cfg(not(feature = "none"))]
() => unsafe {
Error::err_if_negative(abi::tslp_tsk(tmo.as_raw()))?;
Ok(())
},
#[cfg(feature = "none")]
() => unimplemented!(),
}
}
#[inline]
#[doc(alias = "dly_tsk")]
pub fn delay(dur: Duration) -> Result<(), Error<DelayError>> {
match () {
#[cfg(not(feature = "none"))]
() => unsafe {
Error::err_if_negative(abi::dly_tsk(dur.as_raw()))?;
Ok(())
},
#[cfg(feature = "none")]
() => unimplemented!(),
}
}
#[inline]
#[doc(alias = "ext_tsk")]
pub unsafe fn exit() -> Error<ExitError> {
match () {
#[cfg(not(feature = "none"))]
() => unsafe { Error::new_unchecked(ErrorCode::new_unchecked(abi::ext_tsk())) },
#[cfg(feature = "none")]
() => unimplemented!(),
}
}
#[inline]
#[doc(alias = "dis_ter")]
pub fn disable_termination() -> Result<(), Error<DisableTerminationError>> {
match () {
#[cfg(not(feature = "none"))]
() => unsafe {
Error::err_if_negative(abi::dis_ter())?;
Ok(())
},
#[cfg(feature = "none")]
() => unimplemented!(),
}
}
#[inline]
#[doc(alias = "ena_ter")]
pub fn enable_termination() -> Result<(), Error<EnableTerminationError>> {
match () {
#[cfg(not(feature = "none"))]
() => unsafe {
Error::err_if_negative(abi::ena_ter())?;
Ok(())
},
#[cfg(feature = "none")]
() => unimplemented!(),
}
}
#[inline]
#[doc(alias = "sns_ter")]
pub fn is_termination_disabled() -> bool {
match () {
#[cfg(not(feature = "none"))]
() => unsafe { abi::sns_ter() != 0 },
#[cfg(feature = "none")]
() => unimplemented!(),
}
}
#[inline]
#[doc(alias = "get_tid")]
pub fn current_id() -> Result<Option<abi::NonNullID>, Error<CurrentIdError>> {
match () {
#[cfg(not(feature = "none"))]
() => unsafe {
let mut out = MaybeUninit::uninit();
Error::err_if_negative(abi::get_tid(out.as_mut_ptr()))?;
Ok(abi::NonNullID::new(out.assume_init()))
},
#[cfg(feature = "none")]
() => unimplemented!(),
}
}
#[derive(PartialEq, Eq, Clone, Copy)]
pub struct TaskRef<'a> {
id: abi::NonNullID,
_phantom: PhantomData<&'a ()>,
}
impl fmt::Debug for TaskRef<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Task({})", self.id)
}
}
impl TaskRef<'_> {
#[inline]
pub const unsafe fn from_raw_nonnull(id: abi::NonNullID) -> Self {
Self {
id,
_phantom: PhantomData,
}
}
#[inline]
pub const fn as_raw(self) -> abi::ID {
self.id.get()
}
#[inline]
pub const fn as_raw_nonnull(self) -> abi::NonNullID {
self.id
}
}
impl TaskRef<'_> {
#[inline]
#[doc(alias = "act_tsk")]
pub fn activate(self) -> Result<(), Error<ActivateError>> {
match () {
#[cfg(not(feature = "none"))]
() => unsafe {
Error::err_if_negative(abi::act_tsk(self.as_raw()))?;
Ok(())
},
#[cfg(feature = "none")]
() => unimplemented!(),
}
}
#[inline]
#[doc(alias = "mact_tsk")]
pub fn activate_on(self, processor: Processor) -> Result<(), Error<ActivateOnError>> {
match () {
#[cfg(any(feature = "fmp3", feature = "solid_fmp3"))]
() => unsafe {
Error::err_if_negative(abi::mact_tsk(self.as_raw(), processor.as_raw()))?;
Ok(())
},
#[cfg(not(any(feature = "none", feature = "fmp3", feature = "solid_fmp3")))]
() => {
let Processor::UNIPROCESSOR = processor;
self.activate()
.map_err(|e| unsafe { Error::new_unchecked(e.code()) })
}
#[cfg(feature = "none")]
() => unimplemented!(),
}
}
#[inline]
#[doc(alias = "can_act")]
pub fn cancel_activate_all(self) -> Result<usize, Error<CancelActivateAllError>> {
match () {
#[cfg(not(feature = "none"))]
() => unsafe {
let count = Error::err_if_negative(abi::can_act(self.as_raw()))?;
Ok(count as usize)
},
#[cfg(feature = "none")]
() => unimplemented!(),
}
}
#[inline]
#[doc(alias = "chg_pri")]
pub fn set_priority(self, new_priority: Priority) -> Result<(), Error<SetPriorityError>> {
match () {
#[cfg(not(feature = "none"))]
() => unsafe {
Error::err_if_negative(abi::chg_pri(self.as_raw(), new_priority))?;
Ok(())
},
#[cfg(feature = "none")]
() => unimplemented!(),
}
}
#[inline]
#[doc(alias = "get_pri")]
pub fn priority(self) -> Result<Priority, Error<PriorityError>> {
match () {
#[cfg(not(feature = "none"))]
() => unsafe {
let mut pri = MaybeUninit::uninit();
Error::err_if_negative(abi::get_pri(self.as_raw(), pri.as_mut_ptr()))?;
Ok(pri.assume_init())
},
#[cfg(feature = "none")]
() => unimplemented!(),
}
}
#[inline]
#[doc(alias = "mig_tsk")]
pub fn migrate(self, processor: Processor) -> Result<(), Error<MigrateError>> {
match () {
#[cfg(any(feature = "fmp3", feature = "solid_fmp3"))]
() => unsafe {
Error::err_if_negative(abi::mig_tsk(self.as_raw(), processor.as_raw()))?;
Ok(())
},
#[cfg(not(any(feature = "none", feature = "fmp3", feature = "solid_fmp3")))]
() => {
let Processor::UNIPROCESSOR = processor;
Ok(())
}
#[cfg(feature = "none")]
() => unimplemented!(),
}
}
#[inline]
#[doc(alias = "del_tsk")]
#[cfg(feature = "dcre")]
#[cfg_attr(feature = "doc_cfg", doc(cfg(feature = "dcre")))]
pub unsafe fn delete(self) -> Result<(), Error<DeleteError>> {
match () {
#[cfg(not(feature = "none"))]
() => unsafe {
Error::err_if_negative(abi::del_tsk(self.as_raw()))?;
Ok(())
},
#[cfg(feature = "none")]
() => unimplemented!(),
}
}
#[inline]
#[doc(alias = "get_tst")]
pub fn state(self) -> Result<State, Error<StateError>> {
match () {
#[cfg(not(feature = "none"))]
() => unsafe {
let mut pri = MaybeUninit::uninit();
Error::err_if_negative(abi::get_tst(self.as_raw(), pri.as_mut_ptr()))?;
Ok(State::from_abi_unchecked(pri.assume_init()))
},
#[cfg(feature = "none")]
() => unimplemented!(),
}
}
#[inline]
#[doc(alias = "ref_tsk")]
pub fn info(self) -> Result<Info, Error<InfoError>> {
match () {
#[cfg(not(feature = "none"))]
() => unsafe {
let mut pri = MaybeUninit::uninit();
Error::err_if_negative(abi::ref_tsk(self.as_raw(), pri.as_mut_ptr()))?;
Ok(Info {
raw: pri.assume_init(),
})
},
#[cfg(feature = "none")]
() => unimplemented!(),
}
}
}
impl TaskRef<'_> {
#[inline]
#[doc(alias = "wup_tsk")]
#[doc(alias = "unpark")]
pub fn wake(self) -> Result<(), Error<WakeError>> {
match () {
#[cfg(not(feature = "none"))]
() => unsafe {
Error::err_if_negative(abi::wup_tsk(self.as_raw()))?;
Ok(())
},
#[cfg(feature = "none")]
() => unimplemented!(),
}
}
#[inline]
#[doc(alias = "can_wup")]
pub fn cancel_wake_all(self) -> Result<usize, Error<CancelWakeAllError>> {
match () {
#[cfg(not(feature = "none"))]
() => unsafe {
let count = Error::err_if_negative(abi::can_wup(self.as_raw()))?;
Ok(count as usize)
},
#[cfg(feature = "none")]
() => unimplemented!(),
}
}
#[inline]
#[doc(alias = "rel_wai")]
pub fn release_wait(self) -> Result<(), Error<ReleaseWaitError>> {
match () {
#[cfg(not(feature = "none"))]
() => unsafe {
Error::err_if_negative(abi::rel_wai(self.as_raw()))?;
Ok(())
},
#[cfg(feature = "none")]
() => unimplemented!(),
}
}
#[inline]
#[doc(alias = "sus_tsk")]
pub fn suspend(self) -> Result<(), Error<SuspendError>> {
match () {
#[cfg(not(feature = "none"))]
() => unsafe {
Error::err_if_negative(abi::sus_tsk(self.as_raw()))?;
Ok(())
},
#[cfg(feature = "none")]
() => unimplemented!(),
}
}
#[inline]
#[doc(alias = "rsm_tsk")]
pub fn resume(self) -> Result<(), Error<ResumeError>> {
match () {
#[cfg(not(feature = "none"))]
() => unsafe {
Error::err_if_negative(abi::rsm_tsk(self.as_raw()))?;
Ok(())
},
#[cfg(feature = "none")]
() => unimplemented!(),
}
}
}
impl TaskRef<'_> {
#[inline]
#[doc(alias = "ter_tsk")]
pub unsafe fn terminate(self) -> Result<(), Error<TerminateError>> {
match () {
#[cfg(not(feature = "none"))]
() => unsafe {
Error::err_if_negative(abi::ter_tsk(self.as_raw()))?;
Ok(())
},
#[cfg(feature = "none")]
() => unimplemented!(),
}
}
#[inline]
#[doc(alias = "ras_ter")]
pub unsafe fn raise_termination(self) -> Result<(), Error<RaiseTerminationError>> {
match () {
#[cfg(not(feature = "none"))]
() => unsafe {
Error::err_if_negative(abi::ras_ter(self.as_raw()))?;
Ok(())
},
#[cfg(feature = "none")]
() => unimplemented!(),
}
}
}
pub fn current() -> Result<Current, BadContextError> {
if super::kernel::is_task_context() {
match current_id() {
Ok(id) => Ok(Current {
inner: unsafe { TaskRef::from_raw_nonnull(id.unwrap()) },
_no_send: PhantomData,
}),
Err(e) => match e.kind() {
CurrentIdError::BadContext(_) => Err(BadContextError(())),
},
}
} else {
Err(BadContextError(()))
}
}
#[derive(Debug, Clone, Copy)]
pub struct Current {
inner: TaskRef<'static>,
_no_send: PhantomData<*mut ()>,
}
impl Current {
#[inline]
pub const fn as_raw(&self) -> abi::ID {
self.inner.as_raw()
}
#[inline]
pub const fn as_raw_nonnull(&self) -> abi::NonNullID {
self.inner.as_raw_nonnull()
}
#[inline]
pub const fn as_ref(&self) -> TaskRef<'_> {
self.inner
}
}
#[cfg(feature = "dcre")]
pub use self::owned::*;
#[cfg(feature = "dcre")]
#[cfg_attr(feature = "doc_cfg", doc(cfg(feature = "dcre")))]
mod owned {
use super::*;
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
pub struct AllProcessors;
pub use self::processor_set::*;
#[cfg(feature = "solid_fmp3")]
mod processor_set {
use super::*;
use core::convert::TryFrom;
#[cfg_attr(feature = "doc_cfg", doc(cfg(feature = "dcre")))]
pub trait IntoProcessorSet: private::Sealed + Sized {
#[doc(hidden)]
fn into_uint_t(self) -> abi::uint_t;
}
impl<T: IntoIterator<Item = Processor>> IntoProcessorSet for T {
#[doc(hidden)]
#[inline]
fn into_uint_t(self) -> abi::uint_t {
self.into_iter()
.fold(0, |st, processor| st | processor.into_uint_t())
}
}
impl IntoProcessorSet for Processor {
#[allow(clippy::unnecessary_cast)] #[doc(hidden)]
#[inline]
fn into_uint_t(self) -> abi::uint_t {
u32::try_from(self.as_raw() - 1)
.ok()
.and_then(|i| (1 as abi::uint_t).checked_shl(i))
.expect("invalid processor ID")
}
}
impl IntoProcessorSet for AllProcessors {
#[doc(hidden)]
#[inline]
fn into_uint_t(self) -> abi::uint_t {
abi::uint_t::MAX
}
}
}
#[cfg(not(feature = "solid_fmp3"))]
mod processor_set {
use super::*;
#[cfg_attr(feature = "doc_cfg", doc(cfg(feature = "dcre")))]
pub trait IntoProcessorSet: private::Sealed + Sized {
#[doc(hidden)]
fn assert_non_empty(self);
}
impl<T: IntoIterator<Item = Processor>> IntoProcessorSet for T {
#[doc(hidden)]
#[inline]
fn assert_non_empty(self) {
assert!(
self.into_iter().next().is_some(),
"affinity processor set is empty"
);
}
}
impl IntoProcessorSet for Processor {
#[doc(hidden)]
#[inline]
fn assert_non_empty(self) {}
}
impl IntoProcessorSet for AllProcessors {
#[doc(hidden)]
#[inline]
fn assert_non_empty(self) {}
}
}
mod private {
use super::*;
pub trait Sealed {}
impl<T: IntoIterator<Item = Processor>> Sealed for T {}
impl Sealed for Processor {}
impl Sealed for AllProcessors {}
}
#[cfg_attr(feature = "doc_cfg", doc(cfg(feature = "dcre")))]
#[must_use = "`Builder` creates nothing unless you call `.finish()`"]
pub struct Builder<Start, Stack, InitialPriority> {
start: Start,
stack: Stack,
initial_priority: InitialPriority,
assign_to_current_procesor: bool,
#[cfg(not(feature = "none"))]
raw: abi::T_CTSK,
}
#[allow(non_camel_case_types)]
#[doc(hidden)]
pub mod builder_hole {
pub struct __start_is_not_specified__;
pub struct __stack_is_not_specified__;
pub struct __initial_priority_is_not_specified__;
}
impl Task {
#[inline]
#[doc(alias = "acre_tsk")]
pub fn build() -> Builder<
builder_hole::__start_is_not_specified__,
builder_hole::__stack_is_not_specified__,
builder_hole::__initial_priority_is_not_specified__,
> {
Builder {
start: builder_hole::__start_is_not_specified__,
stack: builder_hole::__stack_is_not_specified__,
initial_priority: builder_hole::__initial_priority_is_not_specified__,
assign_to_current_procesor: true,
#[cfg(any(feature = "asp3", feature = "solid_asp3"))]
raw: abi::T_CTSK {
tskatr: abi::TA_NULL,
exinf: abi::EXINF::uninit(),
task: None,
itskpri: 0,
stksz: 0,
stk: core::ptr::null_mut(),
},
#[cfg(feature = "solid_fmp3")]
raw: abi::T_CTSK {
tskatr: abi::TA_NULL,
exinf: abi::EXINF::uninit(),
task: None,
itskpri: 0,
stksz: 0,
stk: core::ptr::null_mut(),
affinity: abi::uint_t::MAX,
iprcid: 0,
},
}
}
}
impl<Start, Stack, InitialPriority> Builder<Start, Stack, InitialPriority> {
#[inline]
pub fn start(
self,
value: impl crate::closure::IntoClosure + Send,
) -> Builder<(), Stack, InitialPriority> {
let (task, exinf) = value.into_closure();
Builder {
start: (),
stack: self.stack,
initial_priority: self.initial_priority,
assign_to_current_procesor: self.assign_to_current_procesor,
#[cfg(not(feature = "none"))]
raw: abi::T_CTSK {
task: Some(task),
exinf,
..self.raw
},
}
}
#[inline]
pub fn stack_size(self, size: usize) -> Builder<Start, (), InitialPriority> {
Builder {
start: self.start,
stack: (),
initial_priority: self.initial_priority,
assign_to_current_procesor: self.assign_to_current_procesor,
#[cfg(not(feature = "none"))]
raw: abi::T_CTSK {
stksz: size,
stk: core::ptr::null_mut(),
..self.raw
},
}
}
#[inline]
pub fn initial_priority(self, value: Priority) -> Builder<Start, Stack, ()> {
Builder {
start: self.start,
stack: self.stack,
initial_priority: (),
assign_to_current_procesor: self.assign_to_current_procesor,
#[cfg(not(feature = "none"))]
raw: abi::T_CTSK {
itskpri: value,
..self.raw
},
}
}
#[inline]
pub fn initial_processor(self, value: Processor) -> Self {
#[cfg(not(feature = "solid_fmp3"))]
let Processor::UNIPROCESSOR = value;
Builder {
assign_to_current_procesor: false,
#[cfg(feature = "solid_fmp3")]
raw: abi::T_CTSK {
iprcid: value.as_raw(),
..self.raw
},
..self
}
}
#[inline]
pub fn processor_affinity(self, value: impl IntoProcessorSet) -> Self {
#[cfg(not(feature = "solid_fmp3"))]
value.assert_non_empty();
Builder {
#[cfg(feature = "solid_fmp3")]
raw: abi::T_CTSK {
affinity: value.into_uint_t(),
..self.raw
},
..self
}
}
}
impl Builder<(), (), ()> {
#[allow(unused_mut)]
pub fn finish(mut self) -> Result<Task, Error<BuildError>> {
#[cfg(feature = "solid_fmp3")]
if self.assign_to_current_procesor {
unsafe { Error::err_if_negative(abi::get_pid(&mut self.raw.iprcid))? };
}
match () {
#[cfg(not(feature = "none"))]
() => unsafe {
let id = Error::err_if_negative(abi::acre_tsk(&self.raw))?;
Ok(Task::from_raw_nonnull(abi::NonNullID::new_unchecked(id)))
},
#[cfg(feature = "none")]
() => unimplemented!(),
}
}
#[allow(unused_mut)]
#[doc(alias = "TA_ACT")]
pub fn finish_and_activate(mut self) -> Result<Task, Error<BuildError>> {
#[cfg(not(feature = "none"))]
{
self.raw.tskatr |= abi::TA_ACT;
}
self.finish()
}
}
#[derive(PartialEq, Eq)]
#[cfg_attr(feature = "doc_cfg", doc(cfg(feature = "dcre")))]
pub struct Task(TaskRef<'static>);
impl fmt::Debug for Task {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
impl Drop for Task {
#[inline]
fn drop(&mut self) {
unsafe { self.0.delete().unwrap() };
}
}
impl Task {
#[inline]
pub const unsafe fn from_raw_nonnull(id: abi::NonNullID) -> Self {
Self(unsafe { TaskRef::from_raw_nonnull(id) })
}
#[inline]
pub const fn leak<'a>(self) -> TaskRef<'a> {
let out = self.0;
core::mem::forget(self);
out
}
#[inline]
pub const fn as_raw(&self) -> abi::ID {
self.0.as_raw()
}
#[inline]
pub const fn as_raw_nonnull(&self) -> abi::NonNullID {
self.0.as_raw_nonnull()
}
#[inline]
pub const fn as_ref(&self) -> TaskRef<'_> {
self.0
}
}
}