diff options
| author | joboet <jonasboettiger@icloud.com> | 2024-02-15 17:03:59 +0100 |
|---|---|---|
| committer | joboet <jonasboettiger@icloud.com> | 2024-02-16 12:10:07 +0100 |
| commit | 0cd21cc549229c1cd6bb544eb53e7eb98190168f (patch) | |
| tree | 07e5eaed21452b8679c3e11c9a337448ba2fb47b /library/std/src/sys/locks/mutex/itron.rs | |
| parent | 1be468815cb7c6932fcc7ed3ee81e6a14376c05e (diff) | |
| download | rust-0cd21cc549229c1cd6bb544eb53e7eb98190168f.tar.gz rust-0cd21cc549229c1cd6bb544eb53e7eb98190168f.zip | |
std: move locks to `sys` on µITRON
Diffstat (limited to 'library/std/src/sys/locks/mutex/itron.rs')
| -rw-r--r-- | library/std/src/sys/locks/mutex/itron.rs | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/library/std/src/sys/locks/mutex/itron.rs b/library/std/src/sys/locks/mutex/itron.rs new file mode 100644 index 00000000000..a134eb2d1be --- /dev/null +++ b/library/std/src/sys/locks/mutex/itron.rs @@ -0,0 +1,68 @@ +//! Mutex implementation backed by μITRON mutexes. Assumes `acre_mtx` and +//! `TA_INHERIT` are available. +use crate::sys::pal::itron::{ + abi, + error::{expect_success, expect_success_aborting, fail, ItronError}, + spin::SpinIdOnceCell, +}; + +pub struct Mutex { + /// The ID of the underlying mutex object + mtx: SpinIdOnceCell<()>, +} + +/// Create a mutex object. This function never panics. +fn new_mtx() -> Result<abi::ID, ItronError> { + ItronError::err_if_negative(unsafe { + abi::acre_mtx(&abi::T_CMTX { + // Priority inheritance mutex + mtxatr: abi::TA_INHERIT, + // Unused + ceilpri: 0, + }) + }) +} + +impl Mutex { + #[inline] + pub const fn new() -> Mutex { + Mutex { mtx: SpinIdOnceCell::new() } + } + + /// Get the inner mutex's ID, which is lazily created. + fn raw(&self) -> abi::ID { + match self.mtx.get_or_try_init(|| new_mtx().map(|id| (id, ()))) { + Ok((id, ())) => id, + Err(e) => fail(e, &"acre_mtx"), + } + } + + pub fn lock(&self) { + let mtx = self.raw(); + expect_success(unsafe { abi::loc_mtx(mtx) }, &"loc_mtx"); + } + + pub unsafe fn unlock(&self) { + let mtx = unsafe { self.mtx.get_unchecked().0 }; + expect_success_aborting(unsafe { abi::unl_mtx(mtx) }, &"unl_mtx"); + } + + pub fn try_lock(&self) -> bool { + let mtx = self.raw(); + match unsafe { abi::ploc_mtx(mtx) } { + abi::E_TMOUT => false, + er => { + expect_success(er, &"ploc_mtx"); + true + } + } + } +} + +impl Drop for Mutex { + fn drop(&mut self) { + if let Some(mtx) = self.mtx.get().map(|x| x.0) { + expect_success_aborting(unsafe { abi::del_mtx(mtx) }, &"del_mtx"); + } + } +} |
