std: use queue-based RwLock on Xous
This commit is contained in:
parent
a30a79c5b4
commit
8afee14202
1 changed files with 0 additions and 74 deletions
|
|
@ -1,74 +0,0 @@
|
|||
use crate::sync::atomic::{AtomicIsize, Ordering::Acquire};
|
||||
use crate::thread::yield_now;
|
||||
|
||||
pub struct RwLock {
|
||||
/// The "mode" value indicates how many threads are waiting on this
|
||||
/// Mutex. Possible values are:
|
||||
/// -1: The lock is locked for writing
|
||||
/// 0: The lock is unlocked
|
||||
/// >=1: The lock is locked for reading
|
||||
///
|
||||
/// This currently spins waiting for the lock to be freed. An
|
||||
/// optimization would be to involve the ticktimer server to
|
||||
/// coordinate unlocks.
|
||||
mode: AtomicIsize,
|
||||
}
|
||||
|
||||
const RWLOCK_WRITING: isize = -1;
|
||||
const RWLOCK_FREE: isize = 0;
|
||||
|
||||
unsafe impl Send for RwLock {}
|
||||
unsafe impl Sync for RwLock {}
|
||||
|
||||
impl RwLock {
|
||||
#[inline]
|
||||
#[rustc_const_stable(feature = "const_locks", since = "1.63.0")]
|
||||
pub const fn new() -> RwLock {
|
||||
RwLock { mode: AtomicIsize::new(RWLOCK_FREE) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn read(&self) {
|
||||
while !unsafe { self.try_read() } {
|
||||
yield_now();
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn try_read(&self) -> bool {
|
||||
self.mode
|
||||
.fetch_update(
|
||||
Acquire,
|
||||
Acquire,
|
||||
|v| if v == RWLOCK_WRITING { None } else { Some(v + 1) },
|
||||
)
|
||||
.is_ok()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn write(&self) {
|
||||
while !unsafe { self.try_write() } {
|
||||
yield_now();
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn try_write(&self) -> bool {
|
||||
self.mode.compare_exchange(RWLOCK_FREE, RWLOCK_WRITING, Acquire, Acquire).is_ok()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn read_unlock(&self) {
|
||||
let previous = self.mode.fetch_sub(1, Acquire);
|
||||
assert!(previous != RWLOCK_FREE);
|
||||
assert!(previous != RWLOCK_WRITING);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn write_unlock(&self) {
|
||||
assert_eq!(
|
||||
self.mode.compare_exchange(RWLOCK_WRITING, RWLOCK_FREE, Acquire, Acquire),
|
||||
Ok(RWLOCK_WRITING)
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue