std: use id-based thread parking on SOLID
This commit is contained in:
parent
247e44e61d
commit
78245286dc
5 changed files with 40 additions and 179 deletions
37
library/std/src/sys/itron/thread_parking.rs
Normal file
37
library/std/src/sys/itron/thread_parking.rs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
use super::abi;
|
||||
use super::error::expect_success_aborting;
|
||||
use super::time::with_tmos;
|
||||
use crate::time::Duration;
|
||||
|
||||
pub type ThreadId = abi::ID;
|
||||
|
||||
pub use super::task::current_task_id_aborting as current;
|
||||
|
||||
pub fn park(_hint: usize) {
|
||||
match unsafe { abi::slp_tsk() } {
|
||||
abi::E_OK | abi::E_RLWAI => {}
|
||||
err => {
|
||||
expect_success_aborting(err, &"slp_tsk");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn park_timeout(dur: Duration, _hint: usize) {
|
||||
match with_tmos(dur, |tmo| unsafe { abi::tslp_tsk(tmo) }) {
|
||||
abi::E_OK | abi::E_RLWAI | abi::E_TMOUT => {}
|
||||
err => {
|
||||
expect_success_aborting(err, &"tslp_tsk");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unpark(id: ThreadId, _hint: usize) {
|
||||
match unsafe { abi::wup_tsk(id) } {
|
||||
// It is allowed to try to wake up a destroyed or unrelated task, so we ignore all
|
||||
// errors that could result from that situation.
|
||||
abi::E_OK | abi::E_NOEXS | abi::E_OBJ | abi::E_QOVR => {}
|
||||
err => {
|
||||
expect_success_aborting(err, &"wup_tsk");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
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.
|
||||
///
|
||||
/// Returns whether the flag was raised (`true`) or the operation timed out (`false`).
|
||||
pub fn wait_timeout(&self, dur: Duration) -> bool {
|
||||
let mut token = MaybeUninit::uninit();
|
||||
let res = with_tmos(dur, |tmout| unsafe {
|
||||
abi::twai_flg(self.flag, RAISED, abi::TWF_ORW, token.as_mut_ptr(), tmout)
|
||||
});
|
||||
|
||||
match res {
|
||||
abi::E_OK => true,
|
||||
abi::E_TMOUT => false,
|
||||
error => fail(error, &"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");
|
||||
}
|
||||
}
|
||||
|
|
@ -13,9 +13,9 @@ mod itron {
|
|||
pub(super) mod spin;
|
||||
pub(super) mod task;
|
||||
pub mod thread;
|
||||
pub mod thread_parking;
|
||||
pub(super) mod time;
|
||||
use super::unsupported;
|
||||
pub mod wait_flag;
|
||||
}
|
||||
|
||||
pub mod alloc;
|
||||
|
|
@ -43,8 +43,8 @@ pub use self::itron::thread;
|
|||
pub mod memchr;
|
||||
pub mod thread_local_dtor;
|
||||
pub mod thread_local_key;
|
||||
pub use self::itron::thread_parking;
|
||||
pub mod time;
|
||||
pub use self::itron::wait_flag;
|
||||
|
||||
mod rwlock;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue