From e1071587038b8bfbad2e47acf914d98cc2589860 Mon Sep 17 00:00:00 2001 From: Yuuki Takano Date: Tue, 24 Dec 2024 13:46:10 +0900 Subject: [PATCH] chore: remove awkernel_sync from this repository Signed-off-by: Yuuki Takano --- .cargo/config.toml | 1 - Cargo.toml | 1 - Makefile | 4 - VERIFICATION.md | 4 +- awkernel_lib/Cargo.toml | 2 +- awkernel_sync/Cargo.toml | 34 -- awkernel_sync/build.rs | 4 - awkernel_sync/src/interrupt_guard.rs | 65 ---- awkernel_sync/src/interrupt_guard/aarch64.rs | 14 - awkernel_sync/src/interrupt_guard/rv32.rs | 21 -- awkernel_sync/src/interrupt_guard/rv64.rs | 27 -- .../src/interrupt_guard/std_common.rs | 10 - awkernel_sync/src/interrupt_guard/x86_64.rs | 22 -- awkernel_sync/src/lib.rs | 9 - awkernel_sync/src/mcs.rs | 217 ------------- awkernel_sync/src/mutex.rs | 109 ------- awkernel_sync/src/rwlock.rs | 292 ------------------ awkernel_sync/src/spinlock.rs | 106 ------- .../tests/model_check_bravo_rwlock.rs | 54 ---- awkernel_sync/tests/model_check_mcslock.rs | 34 -- awkernel_sync/tests/model_check_rwlock.rs | 52 ---- 21 files changed, 3 insertions(+), 1079 deletions(-) delete mode 100644 awkernel_sync/Cargo.toml delete mode 100644 awkernel_sync/build.rs delete mode 100644 awkernel_sync/src/interrupt_guard.rs delete mode 100644 awkernel_sync/src/interrupt_guard/aarch64.rs delete mode 100644 awkernel_sync/src/interrupt_guard/rv32.rs delete mode 100644 awkernel_sync/src/interrupt_guard/rv64.rs delete mode 100644 awkernel_sync/src/interrupt_guard/std_common.rs delete mode 100644 awkernel_sync/src/interrupt_guard/x86_64.rs delete mode 100644 awkernel_sync/src/lib.rs delete mode 100644 awkernel_sync/src/mcs.rs delete mode 100644 awkernel_sync/src/mutex.rs delete mode 100644 awkernel_sync/src/rwlock.rs delete mode 100644 awkernel_sync/src/spinlock.rs delete mode 100644 awkernel_sync/tests/model_check_bravo_rwlock.rs delete mode 100644 awkernel_sync/tests/model_check_mcslock.rs delete mode 100644 awkernel_sync/tests/model_check_rwlock.rs diff --git a/.cargo/config.toml b/.cargo/config.toml index fb8f0a3b4..3e416a96b 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -5,7 +5,6 @@ rv32 = "build --package awkernel --no-default-features --features rv32 --target rv64 = "build --package awkernel --no-default-features --features rv64 --target riscv64gc-unknown-none-elf -Zbuild-std=core,alloc,compiler_builtins -Zbuild-std-features=compiler-builtins-mem" std = "build --package awkernel --no-default-features --features std" -test_awkernel_sync = "test --package awkernel_sync --no-default-features --features std" test_awkernel_lib = "test --package awkernel_lib --no-default-features --features std" test_awkernel_async_lib = "test --package awkernel_async_lib --no-default-features --features std" test_awkernel_drivers = "test --package awkernel_drivers --no-default-features --features std" diff --git a/Cargo.toml b/Cargo.toml index 628acb2b4..f0da030b5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,6 @@ members = [ "applications/awkernel_services", "applications/awkernel_shell", "applications/tests/*", - "awkernel_sync", ] resolver = "2" diff --git a/Makefile b/Makefile index d40fc8f8c..14be06395 100644 --- a/Makefile +++ b/Makefile @@ -220,10 +220,6 @@ test: FORCE cargo test_awkernel_async_lib -- --nocapture cargo test_awkernel_drivers -loom: FORCE - RUST_BACKTRACE=1 RUSTFLAGS="--cfg loom" cargo +$(RUSTV) test_awkernel_sync --test model_check_mcslock --release -- --nocapture - RUST_BACKTRACE=1 RUSTFLAGS="--cfg loom" cargo +$(RUSTV) test_awkernel_sync --test model_check_rwlock --release -- --nocapture - # Format fmt: FORCE diff --git a/VERIFICATION.md b/VERIFICATION.md index 8ad273e54..50d76fe66 100644 --- a/VERIFICATION.md +++ b/VERIFICATION.md @@ -10,8 +10,8 @@ | Target | Verification Code | Tool | |--------|--------|-----| -| [MCS Lock](./awkernel_sync/src/mcs.rs) | [model_check_mcslock.rs](./awkernel_lib/tests/model_check_mcslock.rs) | loom | -| [RW Lock](./awkernel_sync/src/rwlock.rs) | [model_check_rwlock.rs](./awkernel_lib/tests/model_check_rwlock.rs) | loom | +| [MCS Lock](https://github.com/tier4/awkernel_sync/blob/main/src/mcs.rs) | [model_check_mcslock.rs](https://github.com/tier4/awkernel_sync/blob/main/tests/model_check_mcslock.rs) | loom | +| [RW Lock](https://github.com/tier4/awkernel_sync/blob/main/src/rwlock.rs) | [model_check_rwlock.rs](https://github.com/tier4/awkernel_sync/blob/main/tests/model_check_rwlock.rs) | loom | | [Cooperative Async/await Scheduler](./awkernel_async_lib/src/task.rs) | [cooperative](./specification/awkernel_async_lib/src/task/cooperative/) | TLA+ | | [Exception Handler of AArch64](./kernel/asm/aarch64/exception.S) | [exception.S](./specification/kernel/asm/aarch64/exception.S/) | TLA+ | | [Context Switch of AArch64](./awkernel_lib/src/context/aarch64.rs) | [context/aarch64](./specification/awkernel_lib/src/context/aarch64/) | TLA+ | diff --git a/awkernel_lib/Cargo.toml b/awkernel_lib/Cargo.toml index 7717c8776..ebc3d8ffb 100644 --- a/awkernel_lib/Cargo.toml +++ b/awkernel_lib/Cargo.toml @@ -14,7 +14,7 @@ embedded-graphics-core = "0.4" embedded-graphics = "0.8" [dependencies.awkernel_sync] -path = "../awkernel_sync" +git = "https://github.com/tier4/awkernel_sync.git" [dependencies.awkernel_async_lib_verified] path = "../awkernel_async_lib_verified" diff --git a/awkernel_sync/Cargo.toml b/awkernel_sync/Cargo.toml deleted file mode 100644 index 4b2ce98e4..000000000 --- a/awkernel_sync/Cargo.toml +++ /dev/null @@ -1,34 +0,0 @@ -[package] -name = "awkernel_sync" -version = "0.1.0" -edition = "2021" -build = "build.rs" - -[features] -default = [] -std = ["dep:parking_lot"] -x86 = ["dep:x86_64"] -aarch64 = ["dep:awkernel_aarch64"] -rv64 = [] -rv32 = [] -spinlock = [] - -[dependencies.x86_64] -version = "0.15" -optional = true - -[dependencies.awkernel_aarch64] -path = "../awkernel_aarch64" -optional = true - -[dependencies.parking_lot] -version = "0.12" -optional = true - -[dependencies] - -[target.'cfg(loom)'.dependencies] -loom = "0.7" - -[dev-dependencies] -loom = "0.7" diff --git a/awkernel_sync/build.rs b/awkernel_sync/build.rs deleted file mode 100644 index df56fde06..000000000 --- a/awkernel_sync/build.rs +++ /dev/null @@ -1,4 +0,0 @@ -fn main() { - println!("cargo::rustc-check-cfg=cfg(loom)"); - println!("cargo::rustc-check-cfg=cfg(std)"); -} diff --git a/awkernel_sync/src/interrupt_guard.rs b/awkernel_sync/src/interrupt_guard.rs deleted file mode 100644 index 74662c305..000000000 --- a/awkernel_sync/src/interrupt_guard.rs +++ /dev/null @@ -1,65 +0,0 @@ -#[cfg(feature = "x86")] -mod x86_64; - -#[cfg(feature = "x86")] -pub use crate::interrupt_guard::x86_64::*; - -#[cfg(feature = "aarch64")] -mod aarch64; - -#[cfg(feature = "aarch64")] -pub use crate::interrupt_guard::aarch64::*; - -#[cfg(feature = "std")] -mod std_common; - -#[cfg(feature = "std")] -pub use crate::interrupt_guard::std_common::*; - -#[cfg(feature = "rv64")] -mod rv64; - -#[cfg(feature = "rv64")] -pub use crate::interrupt_guard::rv64::*; - -#[cfg(feature = "rv32")] -mod rv32; - -#[cfg(feature = "rv32")] -pub use crate::interrupt_guard::rv32::*; - -/// Disable interrupts and automatically restored the configuration. -/// -/// ``` -/// { -/// use awkernel_lib::interrupt::InterruptGuard; -/// -/// let _int_guard = InterruptGuard::new(); -/// // interrupts are disabled. -/// } -/// // The configuration will be restored here. -/// ``` -pub struct InterruptGuard { - flag: usize, -} - -impl Default for InterruptGuard { - fn default() -> Self { - Self::new() - } -} - -impl InterruptGuard { - pub fn new() -> Self { - let flag = get_flag(); - disable(); - - Self { flag } - } -} - -impl Drop for InterruptGuard { - fn drop(&mut self) { - set_flag(self.flag); - } -} diff --git a/awkernel_sync/src/interrupt_guard/aarch64.rs b/awkernel_sync/src/interrupt_guard/aarch64.rs deleted file mode 100644 index 81f89b2ec..000000000 --- a/awkernel_sync/src/interrupt_guard/aarch64.rs +++ /dev/null @@ -1,14 +0,0 @@ -#[inline(always)] -pub fn get_flag() -> usize { - awkernel_aarch64::daif::get() as usize -} - -#[inline(always)] -pub fn disable() { - unsafe { core::arch::asm!("msr daifset, #0b0010",) }; -} - -#[inline(always)] -pub fn set_flag(flag: usize) { - unsafe { awkernel_aarch64::daif::set(flag as u64) }; -} diff --git a/awkernel_sync/src/interrupt_guard/rv32.rs b/awkernel_sync/src/interrupt_guard/rv32.rs deleted file mode 100644 index 96e53fa53..000000000 --- a/awkernel_sync/src/interrupt_guard/rv32.rs +++ /dev/null @@ -1,21 +0,0 @@ -#[inline(always)] -pub fn get_flag() -> usize { - let x: usize; - unsafe { core::arch::asm!("csrr {}, mstatus", out(reg) x) }; - x & 0x08 -} - -#[inline(always)] -pub fn disable() { - let _x: usize; - unsafe { core::arch::asm!("csrrc {}, mstatus, 0x08", out(reg) _x) }; -} - -#[inline(always)] -pub fn set_flag(flag: usize) { - if flag & 0x08 > 0 { - Self::enable(); - } else { - Self::disable(); - } -} diff --git a/awkernel_sync/src/interrupt_guard/rv64.rs b/awkernel_sync/src/interrupt_guard/rv64.rs deleted file mode 100644 index a043c48da..000000000 --- a/awkernel_sync/src/interrupt_guard/rv64.rs +++ /dev/null @@ -1,27 +0,0 @@ -#[inline(always)] -pub fn get_flag() -> usize { - let x: usize; - unsafe { core::arch::asm!("csrr {}, mstatus", out(reg) x) }; - x & 0x08 -} - -#[inline(always)] -pub fn disable() { - let _x: usize; - unsafe { core::arch::asm!("csrrc {}, mstatus, 0x08", out(reg) _x) }; -} - -#[inline(always)] -pub fn enable() { - let _x: usize; - unsafe { core::arch::asm!("csrrs {}, mstatus, 0x08", out(reg) _x) }; -} - -#[inline(always)] -pub fn set_flag(flag: usize) { - if flag & 0x08 > 0 { - enable(); - } else { - disable(); - } -} diff --git a/awkernel_sync/src/interrupt_guard/std_common.rs b/awkernel_sync/src/interrupt_guard/std_common.rs deleted file mode 100644 index 824446a54..000000000 --- a/awkernel_sync/src/interrupt_guard/std_common.rs +++ /dev/null @@ -1,10 +0,0 @@ -#[inline(always)] -pub fn get_flag() -> usize { - 0 -} - -#[inline(always)] -pub fn disable() {} - -#[inline(always)] -pub fn set_flag(_flag: usize) {} diff --git a/awkernel_sync/src/interrupt_guard/x86_64.rs b/awkernel_sync/src/interrupt_guard/x86_64.rs deleted file mode 100644 index a7e6c1dac..000000000 --- a/awkernel_sync/src/interrupt_guard/x86_64.rs +++ /dev/null @@ -1,22 +0,0 @@ -#[inline(always)] -pub fn get_flag() -> usize { - if x86_64::instructions::interrupts::are_enabled() { - 1 - } else { - 0 - } -} - -#[inline(always)] -pub fn disable() { - x86_64::instructions::interrupts::disable(); -} - -#[inline(always)] -pub fn set_flag(flag: usize) { - if flag == 0 { - x86_64::instructions::interrupts::disable(); - } else { - x86_64::instructions::interrupts::enable(); - } -} diff --git a/awkernel_sync/src/lib.rs b/awkernel_sync/src/lib.rs deleted file mode 100644 index c4c388e40..000000000 --- a/awkernel_sync/src/lib.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![cfg_attr(not(feature = "std"), no_std)] - -extern crate alloc; - -mod interrupt_guard; -pub mod mcs; -pub mod mutex; -pub mod rwlock; -pub mod spinlock; diff --git a/awkernel_sync/src/mcs.rs b/awkernel_sync/src/mcs.rs deleted file mode 100644 index b0110e02e..000000000 --- a/awkernel_sync/src/mcs.rs +++ /dev/null @@ -1,217 +0,0 @@ -use core::{marker::PhantomData, ptr::null_mut}; - -#[cfg(not(loom))] -use core::{ - cell::UnsafeCell, - hint, - ops::{Deref, DerefMut}, - sync::atomic::{fence, AtomicBool, AtomicPtr, Ordering}, -}; - -#[cfg(loom)] -use loom::{ - cell::UnsafeCell, - hint, - sync::atomic::{fence, AtomicBool, AtomicPtr, Ordering}, -}; - -pub struct MCSLock { - last: AtomicPtr>, - data: UnsafeCell, -} - -pub struct MCSNode { - next: AtomicPtr>, - locked: AtomicBool, -} - -impl Default for MCSNode { - fn default() -> Self { - Self::new() - } -} - -impl MCSNode { - #[inline(always)] - pub fn new() -> Self { - MCSNode { - next: AtomicPtr::new(null_mut()), - locked: AtomicBool::new(false), - } - } -} - -impl MCSLock { - #[cfg(not(loom))] - pub const fn new(v: T) -> MCSLock { - MCSLock { - last: AtomicPtr::new(null_mut()), - data: UnsafeCell::new(v), - } - } - - #[cfg(loom)] - pub fn new(v: T) -> MCSLock { - MCSLock { - last: AtomicPtr::new(null_mut()), - data: UnsafeCell::new(v), - } - } - - #[inline(always)] - pub fn try_lock<'a>(&'a self, node: &'a mut MCSNode) -> Option> { - node.next.store(null_mut(), Ordering::Relaxed); - node.locked.store(false, Ordering::Relaxed); - - let _interrupt_guard = crate::interrupt_guard::InterruptGuard::new(); - - // set myself as the last node - let mut guard = MCSLockGuard { - node, - mcs_lock: self, - need_unlock: true, - _interrupt_guard, - _phantom: PhantomData, - }; - - let ptr = guard.node as *mut MCSNode; - - if self - .last - .compare_exchange(null_mut(), ptr, Ordering::Acquire, Ordering::Relaxed) - .is_ok() - { - Some(guard) - } else { - guard.need_unlock = false; - None - } - } - - /// acquire lock - #[inline(always)] - pub fn lock<'a>(&'a self, node: &'a mut MCSNode) -> MCSLockGuard<'a, T> { - node.next.store(null_mut(), Ordering::Relaxed); - node.locked.store(false, Ordering::Relaxed); - - let _interrupt_guard = crate::interrupt_guard::InterruptGuard::new(); - - // set myself as the last node - let guard = MCSLockGuard { - node, - mcs_lock: self, - need_unlock: true, - _interrupt_guard, - _phantom: Default::default(), - }; - - let ptr = guard.node as *mut MCSNode; - let prev = self.last.swap(ptr, Ordering::AcqRel); - - // if prev is null then nobody is trying to acquire lock - if prev.is_null() { - return guard; - } - - // enqueue myself - let prev = unsafe { &*prev }; - prev.next.store(ptr, Ordering::Release); - - // spin until other thread sets locked true - while !guard.node.locked.load(Ordering::Relaxed) { - hint::spin_loop(); - - #[cfg(loom)] - loom::thread::yield_now(); - } - fence(Ordering::Acquire); - - guard - } -} - -unsafe impl Sync for MCSLock {} -unsafe impl Send for MCSLock {} - -pub struct MCSLockGuard<'a, T: Send> { - node: &'a mut MCSNode, - mcs_lock: &'a MCSLock, - need_unlock: bool, - _interrupt_guard: crate::interrupt_guard::InterruptGuard, - _phantom: PhantomData<*mut ()>, -} - -impl MCSLockGuard<'_, T> { - #[cfg(loom)] - pub fn with_mut(&mut self, f: F) -> R - where - F: FnOnce(*mut T) -> R, - { - self.mcs_lock.data.with_mut(f) - } -} - -impl Drop for MCSLockGuard<'_, T> { - #[inline(always)] - fn drop(&mut self) { - if !self.need_unlock { - return; - } - - // if next node is null and self is the last node - // set the last node to null - if self.node.next.load(Ordering::Relaxed).is_null() { - let ptr = self.node as *mut MCSNode; - if self - .mcs_lock - .last - .compare_exchange(ptr, null_mut(), Ordering::Release, Ordering::Relaxed) - .is_ok() - { - return; - } - - // other thread is entering lock and wait the execution - while self.node.next.load(Ordering::Relaxed).is_null() { - hint::spin_loop(); - - #[cfg(loom)] - loom::thread::yield_now(); - } - } - - // make next thread executable - let next = unsafe { &mut *self.node.next.load(Ordering::Acquire) }; - next.locked.store(true, Ordering::Release); - } -} - -#[cfg(not(loom))] -impl Deref for MCSLockGuard<'_, T> { - type Target = T; - - fn deref(&self) -> &Self::Target { - unsafe { &*self.mcs_lock.data.get() } - } -} - -#[cfg(not(loom))] -impl DerefMut for MCSLockGuard<'_, T> { - fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { &mut *self.mcs_lock.data.get() } - } -} - -#[cfg(not(loom))] -impl AsMut for MCSLockGuard<'_, T> { - fn as_mut(&mut self) -> &mut T { - unsafe { &mut *self.mcs_lock.data.get() } - } -} - -#[cfg(not(loom))] -impl AsRef for MCSLockGuard<'_, T> { - fn as_ref(&self) -> &T { - unsafe { &*self.mcs_lock.data.get() } - } -} diff --git a/awkernel_sync/src/mutex.rs b/awkernel_sync/src/mutex.rs deleted file mode 100644 index 8f207ff2e..000000000 --- a/awkernel_sync/src/mutex.rs +++ /dev/null @@ -1,109 +0,0 @@ -//! # Mutex and LockGuard Types -//! -//! The `Mutex` and `LockGuard` types in this module provide a way to manage concurrent access to shared resources. -//! These types have different implementations depending on whether the `std` feature is enabled or not. -//! When the `std` feature is enabled, it uses `parking_lot::Mutex` for efficient locking. -//! When the `std` feature is disabled, it falls back to using `super::mcs::MCSLock`. - -#[cfg(all(not(feature = "std"), not(feature = "spinlock")))] -type Lock = super::mcs::MCSLock; - -#[cfg(all(not(feature = "std"), feature = "spinlock"))] -type Lock = super::spinlock::SpinLock; - -#[cfg(all(not(feature = "std"), not(feature = "spinlock")))] -pub type LockGuard<'a, T> = super::mcs::MCSLockGuard<'a, T>; - -#[cfg(all(not(feature = "std"), feature = "spinlock"))] -pub type LockGuard<'a, T> = super::spinlock::SpinLockGuard<'a, T>; - -#[cfg(feature = "std")] -type Lock = parking_lot::Mutex; - -#[cfg(feature = "std")] -pub type LockGuard<'a, T> = parking_lot::MutexGuard<'a, T>; - -/// A mutual exclusion primitive that provides safe concurrent access to the inner data. -/// -/// The `Mutex` type can be used to ensure that only one thread can access the data at a time. -/// -/// It has different implementations depending on whether the `std` feature is enabled or not. -/// When the `std` feature is enabled, it uses `parking_lot::Mutex` for efficient locking. -/// When the `std` feature is disabled, it falls back to using `super::mcs::MCSLock`. -/// -/// # Example -/// -/// ``` -/// use awkernel_lib::sync::mutex::{MCSNode, Mutex}; -/// use std::{thread, sync::Arc}; -/// -/// let data = Arc::new(Mutex::new(0)); -/// -/// let handles: Vec<_> = (0..10).map(|_| { -/// let data = data.clone(); -/// thread::spawn(move || { -/// // Lock the data to access the shared resource. -/// let mut node = MCSNode::new(); -/// let mut guard = data.lock(&mut node); -/// *guard += 1; -/// }) -/// }).collect(); -/// -/// for handle in handles { -/// handle.join().unwrap(); -/// } -/// -/// // Since only one thread can access the data at a time, the final value will be 10. -/// let mut node = MCSNode::new(); -/// assert_eq!(*data.lock(&mut node), 10); -/// ``` -pub struct Mutex { - #[cfg(not(std))] - mutex: Lock, -} - -impl Mutex { - pub const fn new(v: T) -> Self { - Self { - mutex: Lock::new(v), - } - } - - #[cfg(all(not(feature = "std"), not(feature = "spinlock")))] - #[inline(always)] - pub fn lock<'a>(&'a self, node: &'a mut MCSNode) -> LockGuard<'a, T> { - self.mutex.lock(node) - } - - #[cfg(all(not(feature = "std"), feature = "spinlock"))] - #[inline(always)] - pub fn lock<'a>(&'a self, _node: &'a mut MCSNode) -> LockGuard<'a, T> { - self.mutex.lock() - } - - #[cfg(feature = "std")] - #[inline(always)] - pub fn lock<'a>(&'a self, _node: &mut MCSNode) -> LockGuard<'a, T> { - self.mutex.lock() - } - - #[cfg(all(not(feature = "std"), not(feature = "spinlock")))] - #[inline(always)] - pub fn try_lock<'a>(&'a self, node: &'a mut MCSNode) -> Option> { - self.mutex.try_lock(node) - } - - #[cfg(all(not(feature = "std"), feature = "spinlock"))] - #[inline(always)] - pub fn try_lock<'a>(&'a self, _node: &'a mut MCSNode) -> Option> { - self.mutex.try_lock() - } - - #[cfg(feature = "std")] - #[inline(always)] - pub fn try_lock<'a>(&'a self, _node: &mut MCSNode) -> Option> { - self.mutex.try_lock() - } -} - -pub use super::mcs::MCSNode; diff --git a/awkernel_sync/src/rwlock.rs b/awkernel_sync/src/rwlock.rs deleted file mode 100644 index e9cb7ff68..000000000 --- a/awkernel_sync/src/rwlock.rs +++ /dev/null @@ -1,292 +0,0 @@ -use core::{ - marker::PhantomData, - ops::{Deref, DerefMut}, -}; - -#[cfg(not(loom))] -use core::{ - cell::UnsafeCell, - hint, - sync::atomic::{AtomicUsize, Ordering}, -}; - -#[cfg(loom)] -use loom::{ - cell::UnsafeCell, - hint, - sync::atomic::{AtomicUsize, Ordering}, -}; - -pub struct RwLock { - state: AtomicUsize, - writer_wake_counter: AtomicUsize, - data: UnsafeCell, -} - -impl RwLock { - #[cfg(not(loom))] - pub const fn new(v: T) -> RwLock { - RwLock { - state: AtomicUsize::new(0), - writer_wake_counter: AtomicUsize::new(0), - data: UnsafeCell::new(v), - } - } - - #[cfg(loom)] - pub fn new(v: T) -> RwLock { - RwLock { - state: AtomicUsize::new(0), - writer_wake_counter: AtomicUsize::new(0), - data: UnsafeCell::new(v), - } - } - - /// acquire reader lock - #[inline(always)] - pub fn read(&self) -> RwLockReadGuard { - let _interrupt_guard = crate::interrupt_guard::InterruptGuard::new(); - - let mut s = self.state.load(Ordering::Relaxed); - loop { - if s & 1 == 0 { - match self.state.compare_exchange_weak( - s, - s + 2, - Ordering::Acquire, - Ordering::Relaxed, - ) { - Ok(_) => { - return RwLockReadGuard { - rwlock: self, - _interrupt_guard, - _phantom: Default::default(), - }; - } - Err(e) => s = e, - } - } - - if s & 1 == 1 { - while self.state.load(Ordering::Relaxed) == s { - hint::spin_loop(); - - #[cfg(loom)] - loom::thread::yield_now(); - } - s = self.state.load(Ordering::Relaxed); - } - - #[cfg(loom)] - loom::thread::yield_now(); - } - } - - /// acquire writer lock - #[inline(always)] - pub fn write(&self) -> RwLockWriteGuard { - let _interrupt_guard = crate::interrupt_guard::InterruptGuard::new(); - - let mut s = self.state.load(Ordering::Relaxed); - loop { - if s <= 1 { - match self.state.compare_exchange( - s, - usize::MAX, - Ordering::Acquire, - Ordering::Relaxed, - ) { - Ok(_) => { - return RwLockWriteGuard { - rwlock: self, - _interrupt_guard, - _phantom: Default::default(), - }; - } - Err(e) => { - s = e; - continue; - } - } - } - - if s & 1 == 0 { - match self - .state - .compare_exchange(s, s + 1, Ordering::Relaxed, Ordering::Relaxed) - { - Ok(_) => (), - Err(e) => { - s = e; - continue; - } - } - } - - let w = self.writer_wake_counter.load(Ordering::Acquire); - s = self.state.load(Ordering::Relaxed); - - if s >= 2 { - while self.writer_wake_counter.load(Ordering::Acquire) == w { - hint::spin_loop(); - - #[cfg(loom)] - loom::thread::yield_now(); - } - s = self.state.load(Ordering::Relaxed); - } - - #[cfg(loom)] - loom::thread::yield_now(); - } - } -} - -pub struct RwLockReadGuard<'a, T: Send> { - rwlock: &'a RwLock, - _interrupt_guard: crate::interrupt_guard::InterruptGuard, - _phantom: PhantomData<*mut ()>, -} - -impl RwLockReadGuard<'_, T> { - /// unlock read lock - pub fn unlock(self) {} - - #[cfg(loom)] - pub fn with(&self, f: F) -> R - where - F: FnOnce(*const T) -> R, - { - self.rwlock.data.with(f) - } -} - -pub struct RwLockWriteGuard<'a, T: Send> { - rwlock: &'a RwLock, - _interrupt_guard: crate::interrupt_guard::InterruptGuard, - _phantom: PhantomData<*mut ()>, -} - -impl RwLockWriteGuard<'_, T> { - /// unlock write lock - pub fn unlock(self) {} - - #[cfg(loom)] - pub fn with_mut(&mut self, f: F) -> R - where - F: FnOnce(*mut T) -> R, - { - self.rwlock.data.with_mut(f) - } -} - -#[cfg(not(loom))] -impl AsMut for RwLockWriteGuard<'_, T> { - #[inline(always)] - fn as_mut(&mut self) -> &mut T { - unsafe { &mut *self.rwlock.data.get() } - } -} - -#[cfg(not(loom))] -impl AsRef for RwLockWriteGuard<'_, T> { - #[inline(always)] - fn as_ref(&self) -> &T { - unsafe { &*self.rwlock.data.get() } - } -} - -unsafe impl Sync for RwLock {} -unsafe impl Send for RwLock {} - -#[cfg(not(loom))] -impl AsMut for RwLockReadGuard<'_, T> { - #[inline(always)] - fn as_mut(&mut self) -> &mut T { - unsafe { &mut *self.rwlock.data.get() } - } -} - -#[cfg(not(loom))] -impl AsRef for RwLockReadGuard<'_, T> { - #[inline(always)] - fn as_ref(&self) -> &T { - unsafe { &*self.rwlock.data.get() } - } -} - -#[cfg(not(loom))] -impl Deref for RwLockReadGuard<'_, T> { - type Target = T; - - #[inline(always)] - fn deref(&self) -> &Self::Target { - unsafe { &*self.rwlock.data.get() } - } -} - -#[cfg(not(loom))] -impl Deref for RwLockWriteGuard<'_, T> { - type Target = T; - - #[inline(always)] - fn deref(&self) -> &Self::Target { - unsafe { &*self.rwlock.data.get() } - } -} - -#[cfg(not(loom))] -impl DerefMut for RwLockWriteGuard<'_, T> { - #[inline(always)] - fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { &mut *self.rwlock.data.get() } - } -} - -/// release read lock -impl Drop for RwLockReadGuard<'_, T> { - #[inline(always)] - fn drop(&mut self) { - if self.rwlock.state.fetch_sub(2, Ordering::Release) == 3 { - self.rwlock - .writer_wake_counter - .fetch_add(1, Ordering::Release); - } - } -} - -/// release write lock -impl Drop for RwLockWriteGuard<'_, T> { - #[inline(always)] - fn drop(&mut self) { - self.rwlock.state.store(0, Ordering::Release); - self.rwlock - .writer_wake_counter - .fetch_add(1, Ordering::Release); - } -} - -#[cfg(loom)] -impl<'a, T: Send> Deref for RwLockReadGuard<'a, T> { - type Target = T; - - fn deref(&self) -> &Self::Target { - unimplemented!("loom does not support deref"); - } -} - -#[cfg(loom)] -impl<'a, T: Send> Deref for RwLockWriteGuard<'a, T> { - type Target = T; - - fn deref(&self) -> &Self::Target { - unimplemented!("loom does not support deref"); - } -} - -#[cfg(loom)] -impl<'a, T: Send> DerefMut for RwLockWriteGuard<'a, T> { - fn deref_mut(&mut self) -> &mut Self::Target { - unimplemented!("loom does not support deref_mut"); - } -} diff --git a/awkernel_sync/src/spinlock.rs b/awkernel_sync/src/spinlock.rs deleted file mode 100644 index d70b5e19a..000000000 --- a/awkernel_sync/src/spinlock.rs +++ /dev/null @@ -1,106 +0,0 @@ -use core::{ - cell::UnsafeCell, - marker::PhantomData, - ops::{Deref, DerefMut}, - sync::atomic::{AtomicBool, Ordering}, -}; - -pub struct SpinLock { - lock_var: AtomicBool, - data: UnsafeCell, -} - -unsafe impl Sync for SpinLock {} -unsafe impl Send for SpinLock {} - -impl SpinLock { - pub const fn new(v: T) -> Self { - SpinLock { - lock_var: AtomicBool::new(false), - data: UnsafeCell::new(v), - } - } - - #[inline(always)] - pub fn try_lock(&self) -> Option> { - let _interrupt_guard = crate::interrupt_guard::InterruptGuard::new(); - if self - .lock_var - .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) - .is_ok() - { - Some(SpinLockGuard { - spin_lock: self, - _interrupt_guard, - _phantom: PhantomData, - }) - } else { - None - } - } - - #[inline(always)] - pub fn lock(&self) -> SpinLockGuard { - let _interrupt_guard = loop { - if !self.lock_var.load(Ordering::Relaxed) { - let interrupt_guard = crate::interrupt_guard::InterruptGuard::new(); - if self - .lock_var - .compare_exchange_weak(false, true, Ordering::Acquire, Ordering::Relaxed) - .is_ok() - { - break interrupt_guard; - }; - } - }; - - SpinLockGuard { - spin_lock: self, - _interrupt_guard, - _phantom: PhantomData, - } - } -} - -pub struct SpinLockGuard<'a, T> { - spin_lock: &'a SpinLock, - _interrupt_guard: crate::interrupt_guard::InterruptGuard, - _phantom: PhantomData<*mut ()>, -} - -impl Drop for SpinLockGuard<'_, T> { - #[inline(always)] - fn drop(&mut self) { - self.spin_lock.lock_var.store(false, Ordering::Release); - } -} - -impl Deref for SpinLockGuard<'_, T> { - type Target = T; - - #[inline(always)] - fn deref(&self) -> &Self::Target { - unsafe { &*self.spin_lock.data.get() } - } -} - -impl DerefMut for SpinLockGuard<'_, T> { - #[inline(always)] - fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { &mut *self.spin_lock.data.get() } - } -} - -impl AsMut for SpinLockGuard<'_, T> { - #[inline(always)] - fn as_mut(&mut self) -> &mut T { - unsafe { &mut *self.spin_lock.data.get() } - } -} - -impl AsRef for SpinLockGuard<'_, T> { - #[inline(always)] - fn as_ref(&self) -> &T { - unsafe { &*self.spin_lock.data.get() } - } -} diff --git a/awkernel_sync/tests/model_check_bravo_rwlock.rs b/awkernel_sync/tests/model_check_bravo_rwlock.rs deleted file mode 100644 index 01d0989de..000000000 --- a/awkernel_sync/tests/model_check_bravo_rwlock.rs +++ /dev/null @@ -1,54 +0,0 @@ -#[cfg(loom)] -#[test] -fn model_check_rwlock() { - use awkernel_lib::sync::bravo_rwlock; - use loom::sync::Arc; - - loom::model(|| { - bravo_rwlock::init_visible_readers(); - - let n = Arc::new(bravo_rwlock::BravoRwLock::new(0)); - let mut readers = Vec::new(); - let mut writers = Vec::new(); - - let num_readers = 1; - let num_writers = 2; - let num_iterations = 1; - - for i in 0..num_readers { - let n0 = n.clone(); - let t = loom::thread::spawn(move || { - for _ in 0..num_iterations { - let r = n0.read_cpu_id(i); - let data = r.with(|data| unsafe { *data }); - assert_eq!(data, 0); - } - }); - - readers.push(t); - } - - for _ in 0..num_writers { - let n0 = n.clone(); - let t = loom::thread::spawn(move || { - for _ in 0..num_iterations { - let mut r = n0.write(); - r.with_mut(|data| unsafe { - *data += 1; - *data -= 1; - }); - } - }); - - writers.push(t); - } - - for t in readers { - t.join().unwrap(); - } - - for t in writers { - t.join().unwrap(); - } - }); -} diff --git a/awkernel_sync/tests/model_check_mcslock.rs b/awkernel_sync/tests/model_check_mcslock.rs deleted file mode 100644 index a59c90cd7..000000000 --- a/awkernel_sync/tests/model_check_mcslock.rs +++ /dev/null @@ -1,34 +0,0 @@ -#[cfg(loom)] -#[test] -fn model_check_mcslock() { - use awkernel_lib::sync::{mcs::MCSLock, mutex::MCSNode}; - use loom::{sync::Arc, thread}; - - loom::model(|| { - let lock = Arc::new(MCSLock::new(0)); - let num_threads = 2; - let num_iterations = 2; - - let threads: Vec<_> = (0..num_threads) - .map(|_| { - let lock = lock.clone(); - thread::spawn(move || { - for _ in 0..num_iterations { - let mut node = MCSNode::new(); - let mut guard = lock.lock(&mut node); - guard.with_mut(|data| unsafe { *data += 1 }); - } - }) - }) - .collect(); - - for thread in threads { - thread.join().unwrap(); - } - - let mut node = MCSNode::new(); - let data = lock.lock(&mut node).with_mut(|data| unsafe { *data }); - - assert_eq!(num_threads * num_iterations, data); - }); -} diff --git a/awkernel_sync/tests/model_check_rwlock.rs b/awkernel_sync/tests/model_check_rwlock.rs deleted file mode 100644 index 582e54b98..000000000 --- a/awkernel_sync/tests/model_check_rwlock.rs +++ /dev/null @@ -1,52 +0,0 @@ -#[cfg(loom)] -#[test] -fn model_check_rwlock() { - use awkernel_lib::sync::rwlock; - use loom::sync::Arc; - - loom::model(|| { - let n = Arc::new(rwlock::RwLock::new(0)); - let mut readers = Vec::new(); - let mut writers = Vec::new(); - - let num_readers = 1; - let num_writers = 2; - let num_iterations = 1; - - for _ in 0..num_readers { - let n0 = n.clone(); - let t = loom::thread::spawn(move || { - for _ in 0..num_iterations { - let r = n0.read(); - let data = r.with(|data| unsafe { *data }); - assert_eq!(data, 0); - } - }); - - readers.push(t); - } - - for _ in 0..num_writers { - let n0 = n.clone(); - let t = loom::thread::spawn(move || { - for _ in 0..num_iterations { - let mut r = n0.write(); - r.with_mut(|data| unsafe { - *data += 1; - *data -= 1; - }); - } - }); - - writers.push(t); - } - - for t in readers { - t.join().unwrap(); - } - - for t in writers { - t.join().unwrap(); - } - }); -}