diff --git a/kernel/src/arch/riscv32/compiler_rt.rs b/kernel/src/arch/riscv32/compiler_rt.rs index 80dbdf8..aaf9be0 100644 --- a/kernel/src/arch/riscv32/compiler_rt.rs +++ b/kernel/src/arch/riscv32/compiler_rt.rs @@ -69,4 +69,27 @@ pub unsafe extern fn __atomic_compare_exchange_1(dst: *mut u8, expected: *mut u8 #[no_mangle] pub unsafe extern fn __atomic_compare_exchange_4(dst: *mut u32, expected: *mut u32, desired: u32) -> bool { __atomic_compare_exchange(dst, expected, desired) +} + + +#[no_mangle] +pub unsafe extern fn __atomic_fetch_add_4(dst: *mut u32, delta: u32) -> u32 { + use super::interrupt; + let flags = interrupt::disable_and_store(); + let val = read(dst); + let new_val = val + delta; + write(dst, new_val); + interrupt::restore(flags); + val +} + +#[no_mangle] +pub unsafe extern fn __atomic_fetch_sub_4(dst: *mut u32, delta: u32) -> u32 { + use super::interrupt; + let flags = interrupt::disable_and_store(); + let val = read(dst); + let new_val = val - delta; + write(dst, new_val); + interrupt::restore(flags); + val } \ No newline at end of file diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index 28ef150..685eeea 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -69,8 +69,8 @@ pub fn kmain() -> ! { // the test is not supported in riscv32(maybe) //thread::test::local_key(); //thread::test::unpack(); - //sync::test::philosopher_using_mutex(); - //sync::test::philosopher_using_monitor(); + sync::test::philosopher_using_mutex(); + sync::test::philosopher_using_monitor(); //sync::mpsc::test::test_all(); // come into shell diff --git a/kernel/src/sync/mutex.rs b/kernel/src/sync/mutex.rs index c8e62ea..73e902b 100644 --- a/kernel/src/sync/mutex.rs +++ b/kernel/src/sync/mutex.rs @@ -96,11 +96,17 @@ impl Mutex impl Mutex { fn obtain_lock(&self) { - while self.lock.compare_and_swap(false, true, Ordering::Acquire) != false { - // Wait until the lock looks unlocked before retrying - while self.lock.load(Ordering::Relaxed) { - self.support.cpu_relax(); - } + while true { + match self.lock.compare_exchange(false, true, Ordering::Acquire, Ordering::Acquire) { + Ok(X) => break, + Err(X) => { + // Wait until the lock looks unlocked before retrying + while self.lock.load(Ordering::Relaxed) { + self.support.cpu_relax(); + } + }, + }; + } } @@ -144,13 +150,13 @@ impl Mutex /// a guard within Some. pub fn try_lock(&self) -> Option> { let support_guard = S::before_lock(); - if self.lock.compare_and_swap(false, true, Ordering::Acquire) == false { - Some(MutexGuard { - mutex: self, - support_guard, - }) - } else { - None + match self.lock.compare_exchange(false, true, Ordering::Acquire, Ordering::Acquire) { + Ok(X) => + Some(MutexGuard { + mutex: self, + support_guard, + }), + Err(X) => None, } } }