Skip to content

Commit

Permalink
atomics: stdatomics.h version of SC_ATOMIC_* wrappers
Browse files Browse the repository at this point in the history
  • Loading branch information
victorjulien committed Apr 16, 2020
1 parent 7553937 commit 32cfd71
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 1 deletion.
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
118 changes: 117 additions & 1 deletion src/util-atomic.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
* \author Victor Julien <[email protected]>
* \author Pablo Rincon <[email protected]>
*
* 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
Expand All @@ -33,6 +34,119 @@
#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.
Expand Down Expand Up @@ -243,6 +357,8 @@
; \
})

#endif /* no c11 atomics */

void SCAtomicRegisterTests(void);

#endif /* __UTIL_ATOMIC_H__ */
Expand Down

0 comments on commit 32cfd71

Please sign in to comment.