diff options
author | Anup Patel <anup.patel@wdc.com> | 2019-01-21 14:23:46 +0300 |
---|---|---|
committer | Anup Patel <anup@brainfault.org> | 2019-01-21 18:42:48 +0300 |
commit | 1ee745fe57c3ad9db64bb31564f21a4fab101f22 (patch) | |
tree | f2becf650d53144455d26636a58e2adb2c091967 | |
parent | b5be19f9e5c8f25b07375429aa5d00895a8645cc (diff) | |
download | opensbi-1ee745fe57c3ad9db64bb31564f21a4fab101f22.tar.xz |
lib: Use AMO instructions whenever __riscv_atomic is defined
We should use AMO instructions whenever __riscv_atomic is
defined (i.e. atomics are supported). We use LR/SC only when
__riscv_atomic is not defined.
Signed-off-by: Anup Patel <anup.patel@wdc.com>
-rw-r--r-- | lib/riscv_atomic.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/lib/riscv_atomic.c b/lib/riscv_atomic.c index 3a599f5..bef607f 100644 --- a/lib/riscv_atomic.c +++ b/lib/riscv_atomic.c @@ -137,16 +137,40 @@ long atomic_sub_return(atomic_t *atom, long value) long arch_atomic_cmpxchg(atomic_t *atom, long oldval, long newval) { +#ifdef __riscv_atomic + return __sync_val_compare_and_swap(&atom->counter, oldval, newval); +#else return cmpxchg(&atom->counter, oldval, newval); +#endif } long arch_atomic_xchg(atomic_t *atom, long newval) { + /* Atomically set new value and return old value. */ +#ifdef __riscv_atomic + /* + * The name of GCC built-in macro __sync_lock_test_and_set() + * is misleading. A more appropriate name for GCC built-in + * macro would be __sync_val_exchange(). + */ + return __sync_lock_test_and_set(&atom->counter, newval); +#else return xchg(&atom->counter, newval); +#endif } unsigned int atomic_raw_xchg_uint(volatile unsigned int *ptr, unsigned int newval) { + /* Atomically set new value and return old value. */ +#ifdef __riscv_atomic + /* + * The name of GCC built-in macro __sync_lock_test_and_set() + * is misleading. A more appropriate name for GCC built-in + * macro would be __sync_val_exchange(). + */ + return __sync_lock_test_and_set(ptr, newval); +#else return xchg(ptr, newval); +#endif } |