From 6e0b5539fd440208edd9ec995ca35a93413843ba Mon Sep 17 00:00:00 2001 From: Determinant Date: Wed, 18 Oct 2017 14:36:19 -0400 Subject: add mutex impl --- src/mutex.rs | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 src/mutex.rs 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 { + res: UnsafeCell, + locked: u8 +} + +pub struct MutexGuard<'a, T: 'a> { + lock: &'a Mutex +} + +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 Mutex { + pub fn new(t: T) -> Mutex { + Mutex{res: UnsafeCell::new(t), locked: 0} + } + pub fn lock(&self) -> MutexGuard { + 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} + } +} -- cgit v1.2.3