Add a Mutex implementation.
This commit is contained in:
parent
71c6003905
commit
d1b5720abd
|
@ -1,3 +1,7 @@
|
||||||
|
use core::cell::UnsafeCell;
|
||||||
|
use core::ops::Deref;
|
||||||
|
use core::ops::DerefMut;
|
||||||
|
|
||||||
use crate::{cap::Capability, syscall, zion::ZError};
|
use crate::{cap::Capability, syscall, zion::ZError};
|
||||||
|
|
||||||
pub struct Semaphore {
|
pub struct Semaphore {
|
||||||
|
@ -17,3 +21,52 @@ impl Semaphore {
|
||||||
syscall::semaphone_signal(&self.cap)
|
syscall::semaphone_signal(&self.cap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Mutex<T> {
|
||||||
|
cap: Capability,
|
||||||
|
data: UnsafeCell<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<T> Sync for Mutex<T> where T: Send {}
|
||||||
|
|
||||||
|
pub struct MutexGuard<'a, T> {
|
||||||
|
mutex: &'a Mutex<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<T> Send for MutexGuard<'_, T> where T: Send {}
|
||||||
|
unsafe impl<T> Sync for MutexGuard<'_, T> where T: Sync {}
|
||||||
|
|
||||||
|
impl<T> Deref for MutexGuard<'_, T> {
|
||||||
|
type Target = T;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
unsafe { &*self.mutex.data.get() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> DerefMut for MutexGuard<'_, T> {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
unsafe { &mut *self.mutex.data.get() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Mutex<T> {
|
||||||
|
pub fn new(data: T) -> Mutex<T> {
|
||||||
|
Mutex {
|
||||||
|
cap: syscall::mutex_create().unwrap(),
|
||||||
|
data: UnsafeCell::new(data),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn lock(&self) -> MutexGuard<T> {
|
||||||
|
syscall::mutex_lock(&self.cap).unwrap();
|
||||||
|
|
||||||
|
MutexGuard { mutex: self }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Drop for MutexGuard<'_, T> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
syscall::mutex_release(&self.mutex.cap).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -412,6 +412,36 @@ pub fn reply_port_recv(
|
||||||
Ok((num_bytes, num_caps))
|
Ok((num_bytes, num_caps))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn mutex_create() -> Result<Capability, ZError> {
|
||||||
|
let mut mutex_cap: z_cap_t = 0;
|
||||||
|
syscall(
|
||||||
|
zion::kZionMutexCreate,
|
||||||
|
&zion::ZMutexCreateReq {
|
||||||
|
mutex_cap: &mut mutex_cap,
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(Capability::take(mutex_cap))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mutex_lock(mutex_cap: &Capability) -> Result<(), ZError> {
|
||||||
|
syscall(
|
||||||
|
zion::kZionMutexLock,
|
||||||
|
&zion::ZMutexLockReq {
|
||||||
|
mutex_cap: mutex_cap.raw(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mutex_release(mutex_cap: &Capability) -> Result<(), ZError> {
|
||||||
|
syscall(
|
||||||
|
zion::kZionMutexRelease,
|
||||||
|
&zion::ZMutexReleaseReq {
|
||||||
|
mutex_cap: mutex_cap.raw(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn semaphore_create() -> Result<Capability, ZError> {
|
pub fn semaphore_create() -> Result<Capability, ZError> {
|
||||||
let mut sem_cap: z_cap_t = 0;
|
let mut sem_cap: z_cap_t = 0;
|
||||||
syscall(
|
syscall(
|
||||||
|
|
Loading…
Reference in New Issue