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