diff --git a/src/arc-mutex/mutex-locking-and-unlocking.md b/src/arc-mutex/mutex-locking-and-unlocking.md new file mode 100644 index 0000000..b7e9db1 --- /dev/null +++ b/src/arc-mutex/mutex-locking-and-unlocking.md @@ -0,0 +1,37 @@ + + +# Locking and Unlocking +Locking and unlocking is simple with our layout; Make sure the mutex is in the correct state, then toggle it. + + use core::sync::fence; + + impl Mutex{ + pub fn lock(&self)->MutexGuard{ + while self.is_locked.compare_exchange( + false,//expecting it to not be locked + true ,//lock it if it is not already locked + Ordering::Acquire,//If we succeed, use acquire ordering to prevent + Ordering::Release//If we faill to acquire the lock, it does not matter which ordering we choose, so choose the fastest. + ).is_err(){}//If we fail to aquire the lock immediately try again. + + fence(Ordering::Acquire);//prevent writes to the data protected by the mutex from being reordered before the mutex is actually acquired. + //safety:The previous steps we took means that no one else has the lock + unsafe{return &mut self.value.get()} + } + + ///Safety:Make sure the caller has acquired the lock, and will not dereference the return mutable reference again. + pub unsafe fn unlock(&self){ + if self.is_locked.compare_exchange( + true,//The caller should ensure the mutex is locked + false,//Mark the lock as unlocked + Ordering::Release, + Ordering::Relaxed,//We are about to panic anyway, the ordering doesn't matter + ).is_err{ + panic!("Unlock called while the lock was not locked") + }; + } + } + + + +> Written with [StackEdit](https://stackedit.io/).