parent
296b6196f4
commit
10e3cea340
@ -1,103 +0,0 @@
|
||||
--- atomic_backup.rs 2018-07-10 00:29:48.000000000 +0800
|
||||
+++ atomic.rs 2018-07-12 18:32:26.000000000 +0800
|
||||
@@ -1556,15 +1556,9 @@
|
||||
}
|
||||
|
||||
#[inline]
|
||||
-unsafe fn atomic_store<T>(dst: *mut T, val: T, order: Ordering) {
|
||||
- match order {
|
||||
- Release => intrinsics::atomic_store_rel(dst, val),
|
||||
- Relaxed => intrinsics::atomic_store_relaxed(dst, val),
|
||||
- SeqCst => intrinsics::atomic_store(dst, val),
|
||||
- Acquire => panic!("there is no such thing as an acquire store"),
|
||||
- AcqRel => panic!("there is no such thing as an acquire/release store"),
|
||||
- __Nonexhaustive => panic!("invalid memory ordering"),
|
||||
- }
|
||||
+unsafe fn atomic_store<T>(dst: *mut T, val: T, _order: Ordering) {
|
||||
+ use ptr::write;
|
||||
+ write(dst, val);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -1580,15 +1574,22 @@
|
||||
}
|
||||
|
||||
#[inline]
|
||||
-unsafe fn atomic_swap<T>(dst: *mut T, val: T, order: Ordering) -> T {
|
||||
- match order {
|
||||
- Acquire => intrinsics::atomic_xchg_acq(dst, val),
|
||||
- Release => intrinsics::atomic_xchg_rel(dst, val),
|
||||
- AcqRel => intrinsics::atomic_xchg_acqrel(dst, val),
|
||||
- Relaxed => intrinsics::atomic_xchg_relaxed(dst, val),
|
||||
- SeqCst => intrinsics::atomic_xchg(dst, val),
|
||||
- __Nonexhaustive => panic!("invalid memory ordering"),
|
||||
+unsafe fn atomic_swap<T>(dst: *mut T, val: T, _order: Ordering) -> T {
|
||||
+ let sstatus: usize;
|
||||
+ asm!("csrrs $0, 0x100, x0" : "=r"(sstatus) ::: "volatile");
|
||||
+ // Disable interrupt: sstatus::clear_sie()
|
||||
+ asm!("csrrc x0, 0x100, $0" :: "r"(1) :: "volatile");
|
||||
+
|
||||
+ use ptr::{read, write};
|
||||
+ let ret = read(dst);
|
||||
+ write(dst, val);
|
||||
+
|
||||
+ let sie = sstatus & 1 != 0;
|
||||
+ if sie {
|
||||
+ // Enable interrupt: sstatus::set_sie()
|
||||
+ asm!("csrrs x0, 0x100, $0" :: "r"(1) :: "volatile");
|
||||
}
|
||||
+ ret
|
||||
}
|
||||
|
||||
/// Returns the previous value (like __sync_fetch_and_add).
|
||||
@@ -1618,29 +1619,30 @@
|
||||
}
|
||||
|
||||
#[inline]
|
||||
-unsafe fn atomic_compare_exchange<T>(dst: *mut T,
|
||||
+#[cfg(target_arch = "riscv32")]
|
||||
+unsafe fn atomic_compare_exchange<T: PartialEq>(dst: *mut T,
|
||||
old: T,
|
||||
new: T,
|
||||
- success: Ordering,
|
||||
- failure: Ordering)
|
||||
+ _success: Ordering,
|
||||
+ _failure: Ordering)
|
||||
-> Result<T, T> {
|
||||
- let (val, ok) = match (success, failure) {
|
||||
- (Acquire, Acquire) => intrinsics::atomic_cxchg_acq(dst, old, new),
|
||||
- (Release, Relaxed) => intrinsics::atomic_cxchg_rel(dst, old, new),
|
||||
- (AcqRel, Acquire) => intrinsics::atomic_cxchg_acqrel(dst, old, new),
|
||||
- (Relaxed, Relaxed) => intrinsics::atomic_cxchg_relaxed(dst, old, new),
|
||||
- (SeqCst, SeqCst) => intrinsics::atomic_cxchg(dst, old, new),
|
||||
- (Acquire, Relaxed) => intrinsics::atomic_cxchg_acq_failrelaxed(dst, old, new),
|
||||
- (AcqRel, Relaxed) => intrinsics::atomic_cxchg_acqrel_failrelaxed(dst, old, new),
|
||||
- (SeqCst, Relaxed) => intrinsics::atomic_cxchg_failrelaxed(dst, old, new),
|
||||
- (SeqCst, Acquire) => intrinsics::atomic_cxchg_failacq(dst, old, new),
|
||||
- (__Nonexhaustive, _) => panic!("invalid memory ordering"),
|
||||
- (_, __Nonexhaustive) => panic!("invalid memory ordering"),
|
||||
- (_, AcqRel) => panic!("there is no such thing as an acquire/release failure ordering"),
|
||||
- (_, Release) => panic!("there is no such thing as a release failure ordering"),
|
||||
- _ => panic!("a failure ordering can't be stronger than a success ordering"),
|
||||
- };
|
||||
- if ok { Ok(val) } else { Err(val) }
|
||||
+ let sstatus: usize;
|
||||
+ asm!("csrrs $0, 0x100, x0" : "=r"(sstatus) ::: "volatile");
|
||||
+ // Disable interrupt: sstatus::clear_sie()
|
||||
+ asm!("csrrc x0, 0x100, $0" :: "r"(1) :: "volatile");
|
||||
+
|
||||
+ use ptr::{read, write};
|
||||
+ let ret = read(dst);
|
||||
+ if ret == old {
|
||||
+ write(dst, new);
|
||||
+ }
|
||||
+
|
||||
+ let sie = sstatus & 1 != 0;
|
||||
+ if sie {
|
||||
+ // Enable interrupt: sstatus::set_sie()
|
||||
+ asm!("csrrs x0, 0x100, $0" :: "r"(1) :: "volatile");
|
||||
+ }
|
||||
+ Ok(ret)
|
||||
}
|
||||
|
||||
#[inline]
|
@ -0,0 +1,73 @@
|
||||
//! Workaround for missing compiler-builtin symbols
|
||||
//!
|
||||
//! [atomic](http://llvm.org/docs/Atomics.html#libcalls-atomic)
|
||||
|
||||
/// Copy from:
|
||||
/// https://github.com/rust-lang-nursery/compiler-builtins/blob/master/src/riscv32.rs
|
||||
#[no_mangle]
|
||||
pub extern fn __mulsi3(mut a: u32, mut b: u32) -> u32 {
|
||||
let mut r: u32 = 0;
|
||||
|
||||
while a > 0 {
|
||||
if a & 1 > 0 {
|
||||
r += b;
|
||||
}
|
||||
a >>= 1;
|
||||
b <<= 1;
|
||||
}
|
||||
|
||||
r
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn abort() {
|
||||
loop {}
|
||||
}
|
||||
|
||||
use core::ptr::{read, write};
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn __atomic_load_1(src: *const u8) -> u8 {
|
||||
read(src)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn __atomic_load_2(src: *const u16) -> u16 {
|
||||
read(src)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn __atomic_load_4(src: *const u32) -> u32 {
|
||||
read(src)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn __atomic_store_1(dst: *mut u8, val: u8) {
|
||||
write(dst, val)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn __atomic_store_4(dst: *mut u32, val: u32) {
|
||||
write(dst, val)
|
||||
}
|
||||
|
||||
unsafe fn __atomic_compare_exchange<T: PartialEq>(dst: *mut T, old: T, new: T) -> (T, bool) {
|
||||
use super::interrupt;
|
||||
let flags = interrupt::disable_and_store();
|
||||
let ret = read(dst);
|
||||
if ret == old {
|
||||
write(dst, new);
|
||||
}
|
||||
interrupt::restore(flags);
|
||||
(ret, true)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn __atomic_compare_exchange_1(dst: *mut u8, old: u8, src: u8) -> (u8, bool) {
|
||||
__atomic_compare_exchange(dst, old, src)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn __atomic_compare_exchange_4(dst: *mut u32, old: u32, src: u32) -> (u32, bool) {
|
||||
__atomic_compare_exchange(dst, old, src)
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
#![no_std] // don't link the Rust standard library
|
||||
#![cfg_attr(not(test), no_main)] // disable all Rust-level entry points
|
||||
#![cfg_attr(test, allow(dead_code, unused_macros, unused_imports))]
|
||||
|
||||
#[macro_use]
|
||||
extern crate ucore;
|
Loading…
Reference in new issue