diff options
author | Determinant <[email protected]> | 2017-10-18 14:36:19 -0400 |
---|---|---|
committer | Determinant <[email protected]> | 2017-10-18 14:36:19 -0400 |
commit | 6e0b5539fd440208edd9ec995ca35a93413843ba (patch) | |
tree | 2ba887948eda3853ee2248cd8baa4ef6f5f76fba | |
parent | 177667b7034ec09bb0d7146077bb3c0b7ba28336 (diff) |
add mutex impl
-rw-r--r-- | src/mutex.rs | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/src/mutex.rs b/src/mutex.rs new file mode 100644 index 0000000..1da3890 --- /dev/null +++ b/src/mutex.rs @@ -0,0 +1,61 @@ +use core::ops::{Deref, DerefMut}; +use core::cell::UnsafeCell; + +pub struct Mutex<T> { + res: UnsafeCell<T>, + locked: u8 +} + +pub struct MutexGuard<'a, T: 'a> { + lock: &'a Mutex<T> +} + +impl<'a, T> Drop for MutexGuard<'a, T> { + fn drop(&mut self) { + unsafe { + asm!("ldr r2, $0 + mov r1, $1 + dmb + str r1, [r2]" + : + : "m"(&self.lock.locked), "i"(0)); + } + } +} + +impl<'a, T> Deref for MutexGuard<'a, T> { + type Target = T; + fn deref(&self) -> &Self::Target { + unsafe { &*self.lock.res.get() } + } +} + +impl<'a, T> DerefMut for MutexGuard<'a, T> { + fn deref_mut(&mut self) -> &mut Self::Target { + unsafe { &mut *self.lock.res.get() } + } +} + +impl<T> Mutex<T> { + pub fn new(t: T) -> Mutex<T> { + Mutex{res: UnsafeCell::new(t), locked: 0} + } + pub fn lock(&self) -> MutexGuard<T> { + unsafe { + asm!("ldr r2, $0 + mov r1, $1 + spin_lock: + ldrex r0, [r2] + cmp r0, $1 + itt ne + strexbne r0, r1, [r2] + cmpne r0, #1 + beq spin_lock + dmb" + : + : "m"(&self.locked), "i"(1) + : "r2", "r1", "r0"); + } + MutexGuard{lock: self} + } +} |