update atomic function and workaround the LLVM compiling bug(maybe)

master
chenqiuhao 6 years ago
parent 0a81014007
commit 9474ad7220

@ -70,3 +70,26 @@ pub unsafe extern fn __atomic_compare_exchange_1(dst: *mut u8, expected: *mut u8
pub unsafe extern fn __atomic_compare_exchange_4(dst: *mut u32, expected: *mut u32, desired: u32) -> bool { pub unsafe extern fn __atomic_compare_exchange_4(dst: *mut u32, expected: *mut u32, desired: u32) -> bool {
__atomic_compare_exchange(dst, expected, desired) __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
}

@ -69,8 +69,8 @@ pub fn kmain() -> ! {
// the test is not supported in riscv32(maybe) // the test is not supported in riscv32(maybe)
//thread::test::local_key(); //thread::test::local_key();
//thread::test::unpack(); //thread::test::unpack();
//sync::test::philosopher_using_mutex(); sync::test::philosopher_using_mutex();
//sync::test::philosopher_using_monitor(); sync::test::philosopher_using_monitor();
//sync::mpsc::test::test_all(); //sync::mpsc::test::test_all();
// come into shell // come into shell

@ -96,11 +96,17 @@ impl<T, S: MutexSupport> Mutex<T, S>
impl<T: ?Sized, S: MutexSupport> Mutex<T, S> impl<T: ?Sized, S: MutexSupport> Mutex<T, S>
{ {
fn obtain_lock(&self) { fn obtain_lock(&self) {
while self.lock.compare_and_swap(false, true, Ordering::Acquire) != false { 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 // Wait until the lock looks unlocked before retrying
while self.lock.load(Ordering::Relaxed) { while self.lock.load(Ordering::Relaxed) {
self.support.cpu_relax(); self.support.cpu_relax();
} }
},
};
} }
} }
@ -144,13 +150,13 @@ impl<T: ?Sized, S: MutexSupport> Mutex<T, S>
/// a guard within Some. /// a guard within Some.
pub fn try_lock(&self) -> Option<MutexGuard<T, S>> { pub fn try_lock(&self) -> Option<MutexGuard<T, S>> {
let support_guard = S::before_lock(); let support_guard = S::before_lock();
if self.lock.compare_and_swap(false, true, Ordering::Acquire) == false { match self.lock.compare_exchange(false, true, Ordering::Acquire, Ordering::Acquire) {
Ok(X) =>
Some(MutexGuard { Some(MutexGuard {
mutex: self, mutex: self,
support_guard, support_guard,
}) }),
} else { Err(X) => None,
None
} }
} }
} }

Loading…
Cancel
Save