forked from OISF/suricata
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
atomics: stdatomics.h version of SC_ATOMIC_* wrappers
- Loading branch information
1 parent
7553937
commit 32cfd71
Showing
2 changed files
with
118 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
|
@@ -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__ */ | ||
|