diff options
| author | joboet <jonasboettiger@icloud.com> | 2022-05-18 12:18:51 +0200 |
|---|---|---|
| committer | joboet <jonasboettiger@icloud.com> | 2022-05-18 12:18:51 +0200 |
| commit | fd76552a4b41d132701dc0857a9fee9a3850088e (patch) | |
| tree | fcab07ddd9f277525a652f328443ac4ed6a5c29e /library/std/src/sys | |
| parent | 97d48bec2d2ac7e1aac807e1fe3e8341189db7da (diff) | |
| download | rust-fd76552a4b41d132701dc0857a9fee9a3850088e.tar.gz rust-fd76552a4b41d132701dc0857a9fee9a3850088e.zip | |
std: use an event flag based thread parker on SOLID
Diffstat (limited to 'library/std/src/sys')
| -rw-r--r-- | library/std/src/sys/itron/abi.rs | 48 | ||||
| -rw-r--r-- | library/std/src/sys/itron/wait_flag.rs | 67 | ||||
| -rw-r--r-- | library/std/src/sys/solid/mod.rs | 2 |
3 files changed, 114 insertions, 3 deletions
diff --git a/library/std/src/sys/itron/abi.rs b/library/std/src/sys/itron/abi.rs index f99ee4fa897..5eb14bb7e53 100644 --- a/library/std/src/sys/itron/abi.rs +++ b/library/std/src/sys/itron/abi.rs @@ -30,15 +30,32 @@ pub type ER = int_t; /// Error code type, `ID` on success pub type ER_ID = int_t; +/// Service call operational mode +pub type MODE = uint_t; + +/// OR waiting condition for an eventflag +pub const TWF_ORW: MODE = 0x01; + +/// Object attributes +pub type ATR = uint_t; + +/// FIFO wait order +pub const TA_FIFO: ATR = 0; +/// Only one task is allowed to be in the waiting state for the eventflag +pub const TA_WSGL: ATR = 0; +/// The eventflag’s bit pattern is cleared when a task is released from the +/// waiting state for that eventflag. +pub const TA_CLR: ATR = 0x04; + +/// Bit pattern of an eventflag +pub type FLGPTN = uint_t; + /// Task or interrupt priority pub type PRI = int_t; /// The special value of `PRI` representing the current task's priority. pub const TPRI_SELF: PRI = 0; -/// Object attributes -pub type ATR = uint_t; - /// Use the priority inheritance protocol #[cfg(target_os = "solid_asp3")] pub const TA_INHERIT: ATR = 0x02; @@ -92,6 +109,13 @@ pub struct T_CSEM { #[derive(Clone, Copy)] #[repr(C)] +pub struct T_CFLG { + pub flgatr: ATR, + pub iflgptn: FLGPTN, +} + +#[derive(Clone, Copy)] +#[repr(C)] pub struct T_CMTX { pub mtxatr: ATR, pub ceilpri: PRI, @@ -139,6 +163,24 @@ extern "C" { pub fn sns_dsp() -> bool_t; #[link_name = "__asp3_get_tim"] pub fn get_tim(p_systim: *mut SYSTIM) -> ER; + #[link_name = "__asp3_acre_flg"] + pub fn acre_flg(pk_cflg: *const T_CFLG) -> ER_ID; + #[link_name = "__asp3_del_flg"] + pub fn del_flg(flgid: ID) -> ER; + #[link_name = "__asp3_set_flg"] + pub fn set_flg(flgid: ID, setptn: FLGPTN) -> ER; + #[link_name = "__asp3_clr_flg"] + pub fn clr_flg(flgid: ID, clrptn: FLGPTN) -> ER; + #[link_name = "__asp3_wai_flg"] + pub fn wai_flg(flgid: ID, waiptn: FLGPTN, wfmode: MODE, p_flgptn: *mut FLGPTN) -> ER; + #[link_name = "__asp3_twai_flg"] + pub fn twai_flg( + flgid: ID, + waiptn: FLGPTN, + wfmode: MODE, + p_flgptn: *mut FLGPTN, + tmout: TMO, + ) -> ER; #[link_name = "__asp3_acre_mtx"] pub fn acre_mtx(pk_cmtx: *const T_CMTX) -> ER_ID; #[link_name = "__asp3_del_mtx"] diff --git a/library/std/src/sys/itron/wait_flag.rs b/library/std/src/sys/itron/wait_flag.rs new file mode 100644 index 00000000000..805f85a69b6 --- /dev/null +++ b/library/std/src/sys/itron/wait_flag.rs @@ -0,0 +1,67 @@ +use crate::mem::MaybeUninit; +use crate::time::Duration; + +use super::{ + abi, + error::{expect_success, fail}, + time::with_tmos, +}; + +const CLEAR: abi::FLGPTN = 0; +const RAISED: abi::FLGPTN = 1; + +/// A thread parking primitive that is not susceptible to race conditions, +/// but provides no atomic ordering guarantees and allows only one `raise` per wait. +pub struct WaitFlag { + flag: abi::ID, +} + +impl WaitFlag { + /// Creates a new wait flag. + pub fn new() -> WaitFlag { + let flag = expect_success( + unsafe { + abi::acre_flg(&abi::T_CFLG { + flgatr: abi::TA_FIFO | abi::TA_WSGL | abi::TA_CLR, + iflgptn: CLEAR, + }) + }, + &"acre_flg", + ); + + WaitFlag { flag } + } + + /// Wait for the wait flag to be raised. + pub fn wait(&self) { + let mut token = MaybeUninit::uninit(); + expect_success( + unsafe { abi::wai_flg(self.flag, RAISED, abi::TWF_ORW, token.as_mut_ptr()) }, + &"wai_flg", + ); + } + + /// Wait for the wait flag to be raised or the timeout to occur. + pub fn wait_timeout(&self, dur: Duration) { + let mut token = MaybeUninit::uninit(); + let er = with_tmos(dur, |tmout| unsafe { + abi::twai_flg(self.flag, RAISED, abi::TWF_ORW, token.as_mut_ptr(), tmout) + }); + if er != abi::E_OK && er != abi::E_TMOUT { + fail(er, &"twai_flg"); + } + } + + /// Raise the wait flag. + /// + /// Calls to this function should be balanced with the number of successful waits. + pub fn raise(&self) { + expect_success(unsafe { abi::set_flg(self.flag, RAISED) }, &"set_flg"); + } +} + +impl Drop for WaitFlag { + fn drop(&mut self) { + expect_success(unsafe { abi::del_flg(self.flag) }, &"del_flg"); + } +} diff --git a/library/std/src/sys/solid/mod.rs b/library/std/src/sys/solid/mod.rs index 5ffa381f2e5..2d21e4764fc 100644 --- a/library/std/src/sys/solid/mod.rs +++ b/library/std/src/sys/solid/mod.rs @@ -15,6 +15,7 @@ mod itron { pub mod thread; pub(super) mod time; use super::unsupported; + pub mod wait_flag; } pub mod alloc; @@ -43,6 +44,7 @@ pub mod memchr; pub mod thread_local_dtor; pub mod thread_local_key; pub mod time; +pub use self::itron::wait_flag; mod rwlock; |
