From 114cfdd86b19640ca109488fb960020de673ec57 Mon Sep 17 00:00:00 2001 From: Alix ANNERAUD Date: Fri, 28 Feb 2025 16:22:16 +0100 Subject: [PATCH] Add `RawRwLock` trait and `RawRwLockImpl` struct implementation * Implement `RawRwLock` trait with methods for read and write locking * Implement `RawRwLockImpl` struct with atomic state and waker * Implement `RawRwLockImpl::lock_read`, `RawRwLockImpl::try_lock_read`, and `RawRwLockImpl::unlock_read` methods * Implement `RawRwLockImpl::lock_write`, `RawRwLockImpl::try_lock_write`, and `RawRwLockImpl::unlock_write` methods --- embassy-sync/src/blocking_mutex/raw_rwlock.rs | 86 +++++++++++++++++++ embassy-sync/src/raw_rwlock.rs | 86 ------------------- 2 files changed, 86 insertions(+), 86 deletions(-) create mode 100644 embassy-sync/src/blocking_mutex/raw_rwlock.rs diff --git a/embassy-sync/src/blocking_mutex/raw_rwlock.rs b/embassy-sync/src/blocking_mutex/raw_rwlock.rs new file mode 100644 index 000000000..de4bd1dc5 --- /dev/null +++ b/embassy-sync/src/blocking_mutex/raw_rwlock.rs @@ -0,0 +1,86 @@ +use core::sync::atomic::{AtomicUsize, Ordering}; +use core::task::Waker; +use core::cell::UnsafeCell; + +pub trait RawRwLock { + fn lock_read(&self); + fn try_lock_read(&self) -> bool; + fn unlock_read(&self); + fn lock_write(&self); + fn try_lock_write(&self) -> bool; + fn unlock_write(&self); +} + +pub struct RawRwLockImpl { + state: AtomicUsize, + waker: UnsafeCell>, +} + +impl RawRwLockImpl { + pub const fn new() -> Self { + Self { + state: AtomicUsize::new(0), + waker: UnsafeCell::new(None), + } + } +} + +unsafe impl Send for RawRwLockImpl {} +unsafe impl Sync for RawRwLockImpl {} + +impl RawRwLock for RawRwLockImpl { + fn lock_read(&self) { + loop { + let state = self.state.load(Ordering::Acquire); + if state & 1 == 0 { + if self.state.compare_and_swap(state, state + 2, Ordering::AcqRel) == state { + break; + } + } + } + } + + fn try_lock_read(&self) -> bool { + let state = self.state.load(Ordering::Acquire); + if state & 1 == 0 { + if self.state.compare_and_swap(state, state + 2, Ordering::AcqRel) == state { + return true; + } + } + false + } + + fn unlock_read(&self) { + self.state.fetch_sub(2, Ordering::Release); + if self.state.load(Ordering::Acquire) == 0 { + if let Some(waker) = unsafe { &*self.waker.get() } { + waker.wake_by_ref(); + } + } + } + + fn lock_write(&self) { + loop { + let state = self.state.load(Ordering::Acquire); + if state == 0 { + if self.state.compare_and_swap(0, 1, Ordering::AcqRel) == 0 { + break; + } + } + } + } + + fn try_lock_write(&self) -> bool { + if self.state.compare_and_swap(0, 1, Ordering::AcqRel) == 0 { + return true; + } + false + } + + fn unlock_write(&self) { + self.state.store(0, Ordering::Release); + if let Some(waker) = unsafe { &*self.waker.get() } { + waker.wake_by_ref(); + } + } +} diff --git a/embassy-sync/src/raw_rwlock.rs b/embassy-sync/src/raw_rwlock.rs index de4bd1dc5..e69de29bb 100644 --- a/embassy-sync/src/raw_rwlock.rs +++ b/embassy-sync/src/raw_rwlock.rs @@ -1,86 +0,0 @@ -use core::sync::atomic::{AtomicUsize, Ordering}; -use core::task::Waker; -use core::cell::UnsafeCell; - -pub trait RawRwLock { - fn lock_read(&self); - fn try_lock_read(&self) -> bool; - fn unlock_read(&self); - fn lock_write(&self); - fn try_lock_write(&self) -> bool; - fn unlock_write(&self); -} - -pub struct RawRwLockImpl { - state: AtomicUsize, - waker: UnsafeCell>, -} - -impl RawRwLockImpl { - pub const fn new() -> Self { - Self { - state: AtomicUsize::new(0), - waker: UnsafeCell::new(None), - } - } -} - -unsafe impl Send for RawRwLockImpl {} -unsafe impl Sync for RawRwLockImpl {} - -impl RawRwLock for RawRwLockImpl { - fn lock_read(&self) { - loop { - let state = self.state.load(Ordering::Acquire); - if state & 1 == 0 { - if self.state.compare_and_swap(state, state + 2, Ordering::AcqRel) == state { - break; - } - } - } - } - - fn try_lock_read(&self) -> bool { - let state = self.state.load(Ordering::Acquire); - if state & 1 == 0 { - if self.state.compare_and_swap(state, state + 2, Ordering::AcqRel) == state { - return true; - } - } - false - } - - fn unlock_read(&self) { - self.state.fetch_sub(2, Ordering::Release); - if self.state.load(Ordering::Acquire) == 0 { - if let Some(waker) = unsafe { &*self.waker.get() } { - waker.wake_by_ref(); - } - } - } - - fn lock_write(&self) { - loop { - let state = self.state.load(Ordering::Acquire); - if state == 0 { - if self.state.compare_and_swap(0, 1, Ordering::AcqRel) == 0 { - break; - } - } - } - } - - fn try_lock_write(&self) -> bool { - if self.state.compare_and_swap(0, 1, Ordering::AcqRel) == 0 { - return true; - } - false - } - - fn unlock_write(&self) { - self.state.store(0, Ordering::Release); - if let Some(waker) = unsafe { &*self.waker.get() } { - waker.wake_by_ref(); - } - } -}