From d1b5720abd83dbb1f0e771400db0078036cabd01 Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Sat, 25 Jan 2025 23:17:45 -0800 Subject: [PATCH] Add a Mutex implementation. --- rust/lib/mammoth/src/sync.rs | 53 +++++++++++++++++++++++++++++++++ rust/lib/mammoth/src/syscall.rs | 30 +++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/rust/lib/mammoth/src/sync.rs b/rust/lib/mammoth/src/sync.rs index 8d80f17..0ee5fea 100644 --- a/rust/lib/mammoth/src/sync.rs +++ b/rust/lib/mammoth/src/sync.rs @@ -1,3 +1,7 @@ +use core::cell::UnsafeCell; +use core::ops::Deref; +use core::ops::DerefMut; + use crate::{cap::Capability, syscall, zion::ZError}; pub struct Semaphore { @@ -17,3 +21,52 @@ impl Semaphore { 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 Mutex { + pub fn new(data: T) -> Mutex { + Mutex { + cap: syscall::mutex_create().unwrap(), + data: UnsafeCell::new(data), + } + } + + pub fn lock(&self) -> MutexGuard { + 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(); + } +} diff --git a/rust/lib/mammoth/src/syscall.rs b/rust/lib/mammoth/src/syscall.rs index 565a2c1..31acd94 100644 --- a/rust/lib/mammoth/src/syscall.rs +++ b/rust/lib/mammoth/src/syscall.rs @@ -412,6 +412,36 @@ pub fn reply_port_recv( Ok((num_bytes, num_caps)) } +pub fn mutex_create() -> Result { + 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 { let mut sem_cap: z_cap_t = 0; syscall(