#define atomic_exchange_explicit __atomic_exchange_n
#define atomic_fetch_add_explicit __atomic_fetch_add
#define atomic_fetch_sub_explicit __atomic_fetch_sub
+#define atomic_fetch_and_explicit __atomic_fetch_and
+#define atomic_fetch_or_explicit __atomic_fetch_or
#define atomic_compare_exchange_weak_explicit(atom, expect, desire, mem1, \
mem2) \
*_expect = rval; \
ret; \
})
+#define atomic_fetch_and_explicit(ptr, val, mem) \
+ ({ \
+ __sync_synchronize(); \
+ typeof(*ptr) rval = __sync_fetch_and_and(ptr, val); \
+ __sync_synchronize(); \
+ rval; \
+ })
+#define atomic_fetch_or_explicit(ptr, val, mem) \
+ ({ \
+ __sync_synchronize(); \
+ typeof(*ptr) rval = __sync_fetch_and_or(ptr, val); \
+ __sync_synchronize(); \
+ rval; \
+ })
#else /* !HAVE___ATOMIC && !HAVE_STDATOMIC_H */
#error no atomic functions...
#define UNSET_FLAG(V,F) (V) &= ~(F)
#define RESET_FLAG(V) (V) = 0
+/* Atomic flag manipulation macros. */
+#define CHECK_FLAG_ATOMIC(PV, F) \
+ ((atomic_load_explicit(PV, memory_order_seq_cst)) & (F))
+#define SET_FLAG_ATOMIC(PV, F) \
+ ((atomic_fetch_or_explicit(PV, (F), memory_order_seq_cst)))
+#define UNSET_FLAG_ATOMIC(PV, F) \
+ ((atomic_fetch_and_explicit(PV, ~(F), memory_order_seq_cst)))
+#define RESET_FLAG_ATOMIC(PV) \
+ ((atomic_store_explicit(PV, 0, memory_order_seq_cst)))
+
/* Zebra types. Used in Zserv message header. */
typedef u_int16_t zebra_size_t;
typedef u_int16_t zebra_command_t;