aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2016-12-21 19:58:03 -0800
committerChris Robinson <[email protected]>2016-12-21 19:58:03 -0800
commit4c33818dde702128be13040f9fc8bd0a5b835c76 (patch)
tree27c77c6283e35ec0f4e42d3163174f41018dda00 /include
parent315bd556acdc4b8b67b073f64d472f243a96544d (diff)
Avoid duplicating code using a macro
Diffstat (limited to 'include')
-rw-r--r--include/atomic.h12
1 files changed, 12 insertions, 0 deletions
diff --git a/include/atomic.h b/include/atomic.h
index 4783defe..57609c33 100644
--- a/include/atomic.h
+++ b/include/atomic.h
@@ -373,6 +373,18 @@ inline uint DecrementRef(RefCount *ptr)
{ return ATOMIC_SUB_SEQ(ptr, 1)-1; }
+/* WARNING: A livelock is theoretically possible if another thread keeps
+ * changing the head without giving this a chance to actually swap in the new
+ * one (practically impossible with this little code, but...).
+ */
+#define ATOMIC_REPLACE_HEAD(T, _head, _entry) do { \
+ T _first = ATOMIC_LOAD(_head, almemory_order_acquire); \
+ do { \
+ ATOMIC_STORE(&(_entry)->next, _first, almemory_order_relaxed); \
+ } while(ATOMIC_COMPARE_EXCHANGE_WEAK(T, _head, &_first, _entry, \
+ almemory_order_acq_rel, almemory_order_acquire) == 0); \
+} while(0)
+
#ifdef __cplusplus
}
#endif