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>
This commit is contained in:
Anup Patel
2019-01-21 16:53:46 +05:30
committed by Anup Patel
parent b5be19f9e5
commit 1ee745fe57

View File

@@ -137,16 +137,40 @@ long atomic_sub_return(atomic_t *atom, long value)
long arch_atomic_cmpxchg(atomic_t *atom, long oldval, long newval) 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); return cmpxchg(&atom->counter, oldval, newval);
#endif
} }
long arch_atomic_xchg(atomic_t *atom, long newval) 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); return xchg(&atom->counter, newval);
#endif
} }
unsigned int atomic_raw_xchg_uint(volatile unsigned int *ptr, unsigned int atomic_raw_xchg_uint(volatile unsigned int *ptr,
unsigned int newval) 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); return xchg(ptr, newval);
#endif
} }