aboutsummaryrefslogtreecommitdiff
path: root/lib/sbi/riscv_atomic.c
diff options
context:
space:
mode:
authorAtish Patra <atish.patra@wdc.com>2019-08-14 18:02:13 -0700
committerAnup Patel <anup@brainfault.org>2019-08-16 08:42:52 +0530
commitf6e13e0dd30b164eb444bc08c70fa1b8576e0bca (patch)
tree35ab39e652592d5456b85ae00855a791e8a4cb3f /lib/sbi/riscv_atomic.c
parenta88e424f6c3a42a38e9395726d9fd4e50a96abd2 (diff)
lib: Provide an atomic exchange function unsigned long
Signed-off-by: Anup Patel <anup.patel@wdc.com> Signed-off-by: Atish Patra <atish.patra@wdc.com>
Diffstat (limited to 'lib/sbi/riscv_atomic.c')
-rw-r--r--lib/sbi/riscv_atomic.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/lib/sbi/riscv_atomic.c b/lib/sbi/riscv_atomic.c
index 34bf522..996e893 100644
--- a/lib/sbi/riscv_atomic.c
+++ b/lib/sbi/riscv_atomic.c
@@ -175,6 +175,22 @@ unsigned int atomic_raw_xchg_uint(volatile unsigned int *ptr,
#endif
}
+unsigned long atomic_raw_xchg_ulong(volatile unsigned long *ptr,
+ unsigned 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(ptr, newval);
+#else
+ return xchg(ptr, newval);
+#endif
+}
+
#if (BITS_PER_LONG == 64)
#define __AMO(op) "amo" #op ".d"
#elif (BITS_PER_LONG == 32)