33#ifndef SURICATA_UTIL_ATOMIC_H
34#define SURICATA_UTIL_ATOMIC_H
36#if HAVE_STDATOMIC_H==1
40#define SC_ATOMIC_MEMORY_ORDER_RELAXED memory_order_relaxed
41#define SC_ATOMIC_MEMORY_ORDER_CONSUME memory_order_consume
42#define SC_ATOMIC_MEMORY_ORDER_ACQUIRE memory_order_acquire
43#define SC_ATOMIC_MEMORY_ORDER_RELEASE memory_order_release
44#define SC_ATOMIC_MEMORY_ORDER_ACQ_REL memory_order_acq_rel
45#define SC_ATOMIC_MEMORY_ORDER_SEQ_CST memory_order_seq_cst
58#define SC_ATOMIC_DECLARE(type, name) \
59 _Atomic(type) name ## _sc_atomic__
71#define SC_ATOMIC_EXTERN(type, name) \
72 extern _Atomic(type) (name ## _sc_atomic__)
77#define SC_ATOMIC_DECL_AND_INIT(type, name) \
78 _Atomic(type) (name ## _sc_atomic__) = 0
84#define SC_ATOMIC_DECL_AND_INIT_WITH_VAL(type, name, val) _Atomic(type)(name##_sc_atomic__) = val
89#define SC_ATOMIC_INIT(name) \
90 (name ## _sc_atomic__) = 0
91#define SC_ATOMIC_INITPTR(name) \
92 (name ## _sc_atomic__) = NULL
97#define SC_ATOMIC_RESET(name) \
106#define SC_ATOMIC_ADD(name, val) \
107 atomic_fetch_add(&(name ## _sc_atomic__), (val))
115#define SC_ATOMIC_SUB(name, val) \
116 atomic_fetch_sub(&(name ## _sc_atomic__), (val))
124#define SC_ATOMIC_OR(name, val) \
125 atomic_fetch_or(&(name ## _sc_atomic__), (val))
133#define SC_ATOMIC_AND(name, val) \
134 atomic_fetch_and(&(name ## _sc_atomic__), (val))
141#define SC_ATOMIC_CAS(name, cmpval, newval) \
142 atomic_compare_exchange_strong((name ## _sc_atomic__), &(cmpval), (newval))
149#define SC_ATOMIC_GET(name) \
150 atomic_load(&(name ## _sc_atomic__))
152#define SC_ATOMIC_LOAD_EXPLICIT(name, order) \
153 atomic_load_explicit(&(name ## _sc_atomic__), (order))
160#define SC_ATOMIC_SET(name, val) \
161 atomic_store(&(name ## _sc_atomic__), (val))
165#define SC_ATOMIC_MEMORY_ORDER_RELAXED
166#define SC_ATOMIC_MEMORY_ORDER_CONSUME
167#define SC_ATOMIC_MEMORY_ORDER_ACQUIRE
168#define SC_ATOMIC_MEMORY_ORDER_RELEASE
169#define SC_ATOMIC_MEMORY_ORDER_ACQ_REL
170#define SC_ATOMIC_MEMORY_ORDER_SEQ_CST
183#define SCAtomicCompareAndSwap(addr, tv, nv) \
184 __sync_bool_compare_and_swap((addr), (tv), (nv))
193#define SCAtomicFetchAndAdd(addr, value) \
194 __sync_fetch_and_add((addr), (value))
203#define SCAtomicFetchAndSub(addr, value) \
204 __sync_fetch_and_sub((addr), (value))
213#define SCAtomicAddAndFetch(addr, value) \
214 __sync_add_and_fetch((addr), (value))
223#define SCAtomicSubAndFetch(addr, value) \
224 __sync_sub_and_fetch((addr), (value))
233#define SCAtomicFetchAndAnd(addr, value) \
234 __sync_fetch_and_and((addr), (value))
243#define SCAtomicFetchAndNand(addr, value) \
244 __sync_fetch_and_nand((addr), (value))
253#define SCAtomicFetchAndXor(addr, value) \
254 __sync_fetch_and_xor((addr), (value))
263#define SCAtomicFetchAndOr(addr, value) \
264 __sync_fetch_and_or((addr), (value))
280#define SC_ATOMIC_DECLARE(type, name) \
281 type name ## _sc_atomic__
296#define SC_ATOMIC_EXTERN(type, name) \
297 extern type name ## _sc_atomic__
303#define SC_ATOMIC_DECL_AND_INIT_WITH_VAL(type, name, val) type name##_sc_atomic__ = val
308#define SC_ATOMIC_DECL_AND_INIT(type, name) \
309 type name ## _sc_atomic__ = 0
314#define SC_ATOMIC_INIT(name) \
315 (name ## _sc_atomic__) = 0
317#define SC_ATOMIC_INITPTR(name) \
318 (name ## _sc_atomic__) = NULL
323#define SC_ATOMIC_RESET(name) \
324 (name ## _sc_atomic__) = 0
332#define SC_ATOMIC_ADD(name, val) \
333 SCAtomicFetchAndAdd(&(name ## _sc_atomic__), (val))
341#define SC_ATOMIC_SUB(name, val) \
342 SCAtomicFetchAndSub(&(name ## _sc_atomic__), (val))
350#define SC_ATOMIC_OR(name, val) \
351 SCAtomicFetchAndOr(&(name ## _sc_atomic__), (val))
359#define SC_ATOMIC_AND(name, val) \
360 SCAtomicFetchAndAnd(&(name ## _sc_atomic__), (val))
367#define SC_ATOMIC_CAS(name, cmpval, newval) \
368 SCAtomicCompareAndSwap((name ## _sc_atomic__), cmpval, newval)
375#define SC_ATOMIC_GET(name) \
376 (name ## _sc_atomic__)
378#define SC_ATOMIC_LOAD_EXPLICIT(name, order) \
379 (name ## _sc_atomic__)
386#define SC_ATOMIC_SET(name, val) ({ \
387 while (SC_ATOMIC_CAS(&name, SC_ATOMIC_GET(name), val) == 0) \
void SCAtomicRegisterTests(void)