mikros: Implement synchronization primitives
This commit is contained in:
parent
9a9205b8c1
commit
68a58e1dae
@ -222,3 +222,23 @@ pub fn set_tls_key(key: u64, val: u64) {
|
||||
pub fn get_tls_key(key: u64) -> u64 {
|
||||
syscall1(31, key)
|
||||
}
|
||||
|
||||
pub fn new_mutex() -> u64 {
|
||||
syscall0(32)
|
||||
}
|
||||
|
||||
pub fn lock_mutex(mutex: u64) {
|
||||
syscall1(33, mutex);
|
||||
}
|
||||
|
||||
pub fn try_lock_mutex(mutex: u64) -> bool {
|
||||
syscall1(34, mutex) != 0
|
||||
}
|
||||
|
||||
pub fn unlock_mutex(mutex: u64) {
|
||||
syscall1(35, mutex);
|
||||
}
|
||||
|
||||
pub fn drop_mutex(mutex: u64) {
|
||||
syscall1(36, mutex);
|
||||
}
|
||||
|
53
library/std/src/sys/sync/condvar/mikros.rs
Normal file
53
library/std/src/sys/sync/condvar/mikros.rs
Normal file
@ -0,0 +1,53 @@
|
||||
use crate::sys::sync::Mutex as RawMutex;
|
||||
use crate::time::Duration;
|
||||
use crate::sync::{Arc, Mutex};
|
||||
|
||||
pub struct Condvar {
|
||||
wait_mutexes: Mutex<Vec<Arc<RawMutex>>>,
|
||||
}
|
||||
|
||||
impl Condvar {
|
||||
#[inline]
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_locks", since = "1.63.0"))]
|
||||
pub const fn new() -> Condvar {
|
||||
Condvar {
|
||||
wait_mutexes: Mutex::new(Vec::new())
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn notify_one(&self) {
|
||||
let Some(wait_mutex) = self.wait_mutexes.lock().unwrap().pop() else {
|
||||
return;
|
||||
};
|
||||
unsafe { wait_mutex.unlock() };
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn notify_all(&self) {
|
||||
let mut wait_mutexes = self.wait_mutexes.lock().unwrap();
|
||||
for wait_mutex in wait_mutexes.drain(..) {
|
||||
unsafe { wait_mutex.unlock() };
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn wait(&self, mutex: &RawMutex) {
|
||||
unsafe { mutex.unlock(); }
|
||||
|
||||
let wait_mutex = Arc::new(RawMutex::new());
|
||||
wait_mutex.lock();
|
||||
|
||||
self.wait_mutexes.lock().unwrap().push(wait_mutex.clone());
|
||||
|
||||
wait_mutex.lock();
|
||||
wait_mutex.unlock();
|
||||
|
||||
mutex.lock();
|
||||
}
|
||||
|
||||
pub unsafe fn wait_timeout(&self, mutex: &RawMutex, _dur: Duration) -> bool {
|
||||
//panic!("condvar wait_timeout not supported");
|
||||
unsafe { self.wait(mutex) };
|
||||
true
|
||||
}
|
||||
}
|
@ -30,6 +30,9 @@ cfg_if::cfg_if! {
|
||||
} else if #[cfg(target_os = "xous")] {
|
||||
mod xous;
|
||||
pub use xous::Condvar;
|
||||
} else if #[cfg(target_os = "mikros")] {
|
||||
mod mikros;
|
||||
pub use mikros::Condvar;
|
||||
} else {
|
||||
mod no_threads;
|
||||
pub use no_threads::Condvar;
|
||||
|
44
library/std/src/sys/sync/mutex/mikros.rs
Normal file
44
library/std/src/sys/sync/mutex/mikros.rs
Normal file
@ -0,0 +1,44 @@
|
||||
use crate::sync::OnceLock;
|
||||
use crate::sys::syscalls::{new_mutex, lock_mutex, try_lock_mutex, unlock_mutex, drop_mutex};
|
||||
|
||||
pub struct Mutex {
|
||||
mutex: OnceLock<u64>,
|
||||
}
|
||||
|
||||
unsafe impl Send for Mutex {}
|
||||
unsafe impl Sync for Mutex {} // no threads on this platform
|
||||
|
||||
impl Mutex {
|
||||
#[inline]
|
||||
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_locks", since = "1.63.0"))]
|
||||
pub const fn new() -> Mutex {
|
||||
Mutex { mutex: OnceLock::new() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn lock(&self) {
|
||||
lock_mutex(self.get_mutex_id())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn unlock(&self) {
|
||||
unlock_mutex(self.get_mutex_id())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn try_lock(&self) -> bool {
|
||||
try_lock_mutex(self.get_mutex_id())
|
||||
}
|
||||
|
||||
fn get_mutex_id(&self) -> u64 {
|
||||
*self.mutex.get_or_init(|| new_mutex())
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Mutex {
|
||||
fn drop(&mut self) {
|
||||
if let Some(&id) = self.mutex.get() {
|
||||
drop_mutex(id);
|
||||
}
|
||||
}
|
||||
}
|
@ -32,6 +32,9 @@ cfg_if::cfg_if! {
|
||||
} else if #[cfg(target_os = "xous")] {
|
||||
mod xous;
|
||||
pub use xous::Mutex;
|
||||
} else if #[cfg(target_os = "mikros")] {
|
||||
mod mikros;
|
||||
pub use mikros::Mutex;
|
||||
} else {
|
||||
mod no_threads;
|
||||
pub use no_threads::Mutex;
|
||||
|
@ -27,6 +27,7 @@ cfg_if::cfg_if! {
|
||||
all(target_vendor = "fortanix", target_env = "sgx"),
|
||||
target_os = "solid_asp3",
|
||||
target_os = "xous",
|
||||
target_os = "mikros",
|
||||
))] {
|
||||
mod queue;
|
||||
pub use queue::{Once, OnceState};
|
||||
|
@ -17,6 +17,7 @@ cfg_if::cfg_if! {
|
||||
all(target_os = "windows", target_vendor = "win7"),
|
||||
all(target_vendor = "fortanix", target_env = "sgx"),
|
||||
target_os = "xous",
|
||||
target_os = "mikros",
|
||||
))] {
|
||||
mod queue;
|
||||
pub use queue::RwLock;
|
||||
|
Loading…
x
Reference in New Issue
Block a user