]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
atomics: stdatomics.h version of SC_ATOMIC_* wrappers
authorVictor Julien <victor@inliniac.net>
Sun, 12 Apr 2020 09:12:28 +0000 (11:12 +0200)
committerVictor Julien <victor@inliniac.net>
Thu, 16 Apr 2020 12:37:34 +0000 (14:37 +0200)
configure.ac
src/util-atomic.h

index 67a590d1abf1a9bac0644736cae0cb2abf8aec30..71de01602a938d011f4a98c4e0f404321c53977e 100644 (file)
     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
index 0b7e5593e9c3c7efdbf750929bfeea2ae41379ad..d38740f25472a3afd603a8b8525249c0ced4e811 100644 (file)
@@ -21,7 +21,8 @@
  * \author Victor Julien <victor@inliniac.net>
  * \author Pablo Rincon <pablo.rincon.crespo@gmail.com>
  *
- * 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
 #ifndef __UTIL_ATOMIC_H__
 #define __UTIL_ATOMIC_H__
 
+#if HAVE_STDATOMIC_H==1
+
+#include <stdatomic.h>
+
+/**
+ *  \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.
         ;                                                       \
         })
 
+#endif /* no c11 atomics */
+
 void SCAtomicRegisterTests(void);
 
 #endif /* __UTIL_ATOMIC_H__ */