aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2016-02-23 12:44:42 -0800
committerAndrew Waterman <waterman@cs.berkeley.edu>2016-02-23 12:44:42 -0800
commitbf9ee5ca114921718da280de46046dbc43722641 (patch)
tree5e99e0ad886e24800387bc9dde43199454c9463b
parent573c7d3f12f50fec5aa974c7ebe61f1db59f5152 (diff)
downloadpk-bf9ee5ca114921718da280de46046dbc43722641.zip
pk-bf9ee5ca114921718da280de46046dbc43722641.tar.gz
pk-bf9ee5ca114921718da280de46046dbc43722641.tar.bz2
simplify pk atomics and add atomic_or
-rw-r--r--pk/atomic.h18
1 files changed, 8 insertions, 10 deletions
diff --git a/pk/atomic.h b/pk/atomic.h
index 37f43e5..e4610de 100644
--- a/pk/atomic.h
+++ b/pk/atomic.h
@@ -13,27 +13,25 @@
typedef struct { int lock; } spinlock_t;
#define SPINLOCK_INIT {0}
-#define mb() __sync_synchronize()
+#define mb() asm volatile ("fence" ::: "memory")
#define atomic_set(ptr, val) (*(volatile typeof(*(ptr)) *)(ptr) = val)
#define atomic_read(ptr) (*(volatile typeof(*(ptr)) *)(ptr))
#ifdef __riscv_atomic
# define atomic_add(ptr, inc) __sync_fetch_and_add(ptr, inc)
+# define atomic_or(ptr, inc) __sync_fetch_and_or(ptr, inc)
# define atomic_swap(ptr, swp) __sync_lock_test_and_set(ptr, swp)
# define atomic_cas(ptr, cmp, swp) __sync_val_compare_and_swap(ptr, cmp, swp)
#else
-# define atomic_add(ptr, inc) ({ \
+# define atomic_binop(ptr, inc, op) ({ \
long flags = disable_irqsave(); \
- typeof(*(ptr)) res = *(volatile typeof(*(ptr)) *)(ptr); \
- *(volatile typeof(ptr))(ptr) = res + (inc); \
- enable_irqrestore(flags); \
- res; })
-# define atomic_swap(ptr, swp) ({ \
- long flags = disable_irqsave(); \
- typeof(*(ptr)) res = *(volatile typeof(*(ptr)) *)(ptr); \
- *(volatile typeof(ptr))(ptr) = (swp); \
+ typeof(*(ptr)) res = atomic_read(ptr); \
+ atomic_set(ptr, op); \
enable_irqrestore(flags); \
res; })
+# define atomic_add(ptr, inc) atomic_binop(ptr, inc, res + (inc))
+# define atomic_or(ptr, inc) atomic_binop(ptr, inc, res | (inc))
+# define atomic_swap(ptr, inc) atomic_binop(ptr, inc, (inc))
# define atomic_cas(ptr, cmp, swp) ({ \
long flags = disable_irqsave(); \
typeof(*(ptr)) res = *(volatile typeof(*(ptr)) *)(ptr); \