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