diff options
author | Chris Robinson <[email protected]> | 2016-12-21 19:58:03 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2016-12-21 19:58:03 -0800 |
commit | 4c33818dde702128be13040f9fc8bd0a5b835c76 (patch) | |
tree | 27c77c6283e35ec0f4e42d3163174f41018dda00 /include/atomic.h | |
parent | 315bd556acdc4b8b67b073f64d472f243a96544d (diff) |
Avoid duplicating code using a macro
Diffstat (limited to 'include/atomic.h')
-rw-r--r-- | include/atomic.h | 12 |
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 |