atomics: stdatomics.h version of SC_ATOMIC_* wrappers

pull/4832/head
Victor Julien 5 years ago
parent 7553937a22
commit 32cfd71f1a

@ -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

@ -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
@ -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.
@ -243,6 +357,8 @@
; \
})
#endif /* no c11 atomics */
void SCAtomicRegisterTests(void);
#endif /* __UTIL_ATOMIC_H__ */

Loading…
Cancel
Save