81 lines
1.6 KiB
Rust
81 lines
1.6 KiB
Rust
use core::cell::UnsafeCell;
|
|
use core::ops::Deref;
|
|
use core::ops::DerefMut;
|
|
|
|
use crate::{cap::Capability, syscall, zion::ZError};
|
|
|
|
pub struct Semaphore {
|
|
cap: Capability,
|
|
}
|
|
|
|
impl Semaphore {
|
|
pub fn new() -> Result<Self, ZError> {
|
|
syscall::semaphore_create().map(|cap| Self { cap })
|
|
}
|
|
|
|
pub fn wait(&self) -> Result<(), ZError> {
|
|
syscall::semaphone_wait(&self.cap)
|
|
}
|
|
|
|
pub fn signal(&self) -> Result<(), ZError> {
|
|
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<'a, T> Mutex<T> {
|
|
pub fn new(data: T) -> Mutex<T> {
|
|
Mutex {
|
|
cap: syscall::mutex_create().unwrap(),
|
|
data: UnsafeCell::new(data),
|
|
}
|
|
}
|
|
|
|
pub fn lock(&'a self) -> MutexGuard<'a, 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();
|
|
}
|
|
}
|
|
|
|
impl<T> Default for Mutex<T>
|
|
where
|
|
T: Default,
|
|
{
|
|
fn default() -> Self {
|
|
Self::new(T::default())
|
|
}
|
|
}
|