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 { 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 { cap: Capability, data: UnsafeCell, } unsafe impl Sync for Mutex where T: Send {} pub struct MutexGuard<'a, T> { mutex: &'a Mutex, } unsafe impl Send for MutexGuard<'_, T> where T: Send {} unsafe impl Sync for MutexGuard<'_, T> where T: Sync {} impl Deref for MutexGuard<'_, T> { type Target = T; fn deref(&self) -> &Self::Target { unsafe { &*self.mutex.data.get() } } } impl DerefMut for MutexGuard<'_, T> { fn deref_mut(&mut self) -> &mut Self::Target { unsafe { &mut *self.mutex.data.get() } } } impl<'a, T> Mutex { pub fn new(data: T) -> Mutex { 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 Drop for MutexGuard<'_, T> { fn drop(&mut self) { syscall::mutex_release(&self.mutex.cap).unwrap(); } } impl Default for Mutex where T: Default, { fn default() -> Self { Self::new(T::default()) } }