From: Victor Julien Date: Sun, 12 Apr 2020 09:12:28 +0000 (+0200) Subject: atomics: stdatomics.h version of SC_ATOMIC_* wrappers X-Git-Tag: suricata-6.0.0-beta1~506 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=32cfd71f1a9326e6f6b2b280e3c458e767fba287;p=thirdparty%2Fsuricata.git atomics: stdatomics.h version of SC_ATOMIC_* wrappers --- diff --git a/configure.ac b/configure.ac index 67a590d1ab..71de01602a 100644 --- a/configure.ac +++ b/configure.ac @@ -185,6 +185,7 @@ AC_CHECK_HEADERS([utime.h]) AC_CHECK_HEADERS([libgen.h]) AC_CHECK_HEADERS([mach/mach.h]) + AC_CHECK_HEADERS([stdatomic.h]) AC_CHECK_HEADERS([sys/socket.h net/if.h sys/mman.h linux/if_arp.h], [], [], [[#ifdef HAVE_SYS_SOCKET_H diff --git a/src/util-atomic.h b/src/util-atomic.h index 0b7e5593e9..d38740f254 100644 --- a/src/util-atomic.h +++ b/src/util-atomic.h @@ -21,7 +21,8 @@ * \author Victor Julien * \author Pablo Rincon * - * API for atomic operations. Uses atomic instructions (GCC only at this time). + * API for atomic operations. Uses C11 atomic instructions + * where available, GCC/clang specific (gnu99) operations otherwise. * * To prevent developers from accidentally working with the atomic variables * directly instead of through the proper macro's, a marco trick is performed @@ -33,6 +34,119 @@ #ifndef __UTIL_ATOMIC_H__ #define __UTIL_ATOMIC_H__ +#if HAVE_STDATOMIC_H==1 + +#include + +/** + * \brief wrapper for declaring atomic variables. + * + * \param type Type of the variable (char, short, int, long, long long) + * \param name Name of the variable. + * + * We just declare the variable here as we rely on atomic operations + * to modify it, so no need for locks. + * + * \warning variable is not initialized + */ +#define SC_ATOMIC_DECLARE(type, name) \ + _Atomic(type) name ## _sc_atomic__ + +/** + * \brief wrapper for referencing an atomic variable declared on another file. + * + * \param type Type of the variable (char, short, int, long, long long) + * \param name Name of the variable. + * + * We just declare the variable here as we rely on atomic operations + * to modify it, so no need for locks. + * + */ +#define SC_ATOMIC_EXTERN(type, name) \ + extern _Atomic(type) (name ## _sc_atomic__) + +/** + * \brief wrapper for declaring an atomic variable and initializing it. + **/ +#define SC_ATOMIC_DECL_AND_INIT(type, name) \ + _Atomic(type) (name ## _sc_atomic__) = 0 + +/** + * \brief wrapper for initializing an atomic variable. + **/ +#define SC_ATOMIC_INIT(name) \ + (name ## _sc_atomic__) = 0 +#define SC_ATOMIC_INITPTR(name) \ + (name ## _sc_atomic__) = NULL + +/** + * \brief wrapper for reinitializing an atomic variable. + **/ +#define SC_ATOMIC_RESET(name) \ + SC_ATOMIC_INIT(name) + +/** + * \brief add a value to our atomic variable + * + * \param name the atomic variable + * \param val the value to add to the variable + */ +#define SC_ATOMIC_ADD(name, val) \ + atomic_fetch_add(&(name ## _sc_atomic__), (val)) + +/** + * \brief sub a value from our atomic variable + * + * \param name the atomic variable + * \param val the value to sub from the variable + */ +#define SC_ATOMIC_SUB(name, val) \ + atomic_fetch_sub(&(name ## _sc_atomic__), (val)) + +/** + * \brief Bitwise OR a value to our atomic variable + * + * \param name the atomic variable + * \param val the value to OR to the variable + */ +#define SC_ATOMIC_OR(name, val) \ + atomic_fetch_or(&(name ## _sc_atomic__), (val)) + +/** + * \brief Bitwise AND a value to our atomic variable + * + * \param name the atomic variable + * \param val the value to AND to the variable + */ +#define SC_ATOMIC_AND(name, val) \ + atomic_fetch_and(&(name ## _sc_atomic__), (val)) + +/** + * \brief atomic Compare and Switch + * + * \warning "name" is passed to us as "&var" + */ +#define SC_ATOMIC_CAS(name, cmpval, newval) \ + atomic_compare_exchange_strong((name ## _sc_atomic__), &(cmpval), (newval)) + +/** + * \brief Get the value from the atomic variable. + * + * \retval var value + */ +#define SC_ATOMIC_GET(name) \ + atomic_load(&(name ## _sc_atomic__)) + +/** + * \brief Set the value for the atomic variable. + * + * \retval var value + */ +#define SC_ATOMIC_SET(name, val) \ + atomic_store(&(name ## _sc_atomic__), (val)) + +#else + /** * \brief wrapper for OS/compiler specific atomic compare and swap (CAS) * function. @@ -243,6 +357,8 @@ ; \ }) +#endif /* no c11 atomics */ + void SCAtomicRegisterTests(void); #endif /* __UTIL_ATOMIC_H__ */