From 0579fb14ef4be4f9ccbb621758ba1d2d7235a489 Mon Sep 17 00:00:00 2001 From: Christian Cunningham Date: Fri, 26 Aug 2022 17:24:34 -0700 Subject: Add Spinlock --- src/sync.rs | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'src/sync.rs') diff --git a/src/sync.rs b/src/sync.rs index 0e0ace2..38cffc8 100644 --- a/src/sync.rs +++ b/src/sync.rs @@ -81,3 +81,59 @@ impl interface::Mutex for NullLock { f(data) } } + +use core::sync::atomic::{AtomicBool, Ordering}; + +pub struct SpinLock +where + T: Sized, +{ + data: UnsafeCell, + lock: AtomicBool, +} + +unsafe impl Send for SpinLock where T: Sized + Send {} +unsafe impl Sync for SpinLock where T: Sized + Send {} + +impl SpinLock { + /// # New lock + pub const fn new(data: T) -> Self { + Self { + data: UnsafeCell::new(data), + lock: AtomicBool::new(false), + } + } +} + +impl SpinLock { + /// # Init + pub fn init(&self) { + use interface::Mutex; + self.lock(|init| { + init.init(); + }); + } +} + +impl interface::Mutex for SpinLock { + /// # Data type + type Data = T; + /// # Lock + fn lock<'a, R>(&'a self, f: impl FnOnce(&'a mut T) -> R) -> R { + loop { + // Loop until acquired the lock + if let Ok(false) = + self.lock + .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) + { + break; + } + } + let data = unsafe { &mut *self.data.get() }; + + let res = f(data); + // Release the lock after finished with the underlying data + self.lock.store(false, Ordering::Release); + res + } +} -- cgit v1.2.1