From f765d422d1b54f51d3735dcc584efd714007f6e2 Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Wed, 28 Feb 2018 16:11:42 -0500 Subject: [PATCH] lib: add atomic bitwise OR, AND * Add support for C11 bitwise OR & AND operations * Add atomic versions of bitfield macros Signed-off-by: Quentin Young --- lib/frratomic.h | 16 ++++++++++++++++ lib/zebra.h | 10 ++++++++++ 2 files changed, 26 insertions(+) diff --git a/lib/frratomic.h b/lib/frratomic.h index 4ae84c4018..689b25255d 100644 --- a/lib/frratomic.h +++ b/lib/frratomic.h @@ -46,6 +46,8 @@ #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) \ @@ -135,6 +137,20 @@ *_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... diff --git a/lib/zebra.h b/lib/zebra.h index 11bf764b63..e592118f69 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -481,6 +481,16 @@ typedef enum { #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; -- 2.39.5