aboutsummaryrefslogtreecommitdiff
path: root/include/odp/api/atomic.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/odp/api/atomic.h')
-rw-r--r--include/odp/api/atomic.h209
1 files changed, 23 insertions, 186 deletions
diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h
index ab424c096..93287499e 100644
--- a/include/odp/api/atomic.h
+++ b/include/odp/api/atomic.h
@@ -18,9 +18,6 @@
extern "C" {
#endif
-#include <stdint.h>
-#include <odp/align.h>
-
/** @addtogroup odp_synchronizers
* Atomic types and relaxed operations. These operations cannot be used for
* synchronization.
@@ -29,39 +26,14 @@ extern "C" {
/**
- * Atomic 64-bit unsigned integer
- */
-typedef struct {
- uint64_t v; /**< Actual storage for the atomic variable */
-#if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
- /* Some architectures do not support lock-free operations on 64-bit
- * data types. We use a spin lock to ensure atomicity. */
- char lock; /**< Spin lock (if needed) used to ensure atomic access */
-#endif
-} odp_atomic_u64_t
-ODP_ALIGNED(sizeof(uint64_t)); /* Enforce alignement! */
-
-
-/**
- * Atomic 32-bit unsigned integer
- */
-typedef struct {
- uint32_t v; /**< Actual storage for the atomic variable */
-} odp_atomic_u32_t
-ODP_ALIGNED(sizeof(uint32_t)); /* Enforce alignement! */
-
-
-/**
* Initialize atomic uint32 variable
* @note Relaxed memory order, cannot be used for synchronization
*
* @param[out] atom Pointer to an atomic uint32 variable
* @param val Value to initialize the variable with
*/
-static inline void odp_atomic_init_u32(odp_atomic_u32_t *atom, uint32_t val)
-{
- __atomic_store_n(&atom->v, val, __ATOMIC_RELAXED);
-}
+void odp_atomic_init_u32(odp_atomic_u32_t *atom, uint32_t val);
+
/**
* Load value of atomic uint32 variable
@@ -71,10 +43,7 @@ static inline void odp_atomic_init_u32(odp_atomic_u32_t *atom, uint32_t val)
*
* @return Value of the variable
*/
-static inline uint32_t odp_atomic_load_u32(odp_atomic_u32_t *atom)
-{
- return __atomic_load_n(&atom->v, __ATOMIC_RELAXED);
-}
+uint32_t odp_atomic_load_u32(odp_atomic_u32_t *atom);
/**
* Store value to atomic uint32 variable
@@ -83,11 +52,7 @@ static inline uint32_t odp_atomic_load_u32(odp_atomic_u32_t *atom)
* @param[out] atom Pointer to an atomic uint32 variable
* @param val Value to store in the variable
*/
-static inline void odp_atomic_store_u32(odp_atomic_u32_t *atom,
- uint32_t val)
-{
- __atomic_store_n(&atom->v, val, __ATOMIC_RELAXED);
-}
+void odp_atomic_store_u32(odp_atomic_u32_t *atom, uint32_t val);
/**
* Fetch and add to atomic uint32 variable
@@ -98,11 +63,7 @@ static inline void odp_atomic_store_u32(odp_atomic_u32_t *atom,
*
* @return Value of the variable before the addition
*/
-static inline uint32_t odp_atomic_fetch_add_u32(odp_atomic_u32_t *atom,
- uint32_t val)
-{
- return __atomic_fetch_add(&atom->v, val, __ATOMIC_RELAXED);
-}
+uint32_t odp_atomic_fetch_add_u32(odp_atomic_u32_t *atom, uint32_t val);
/**
* Add to atomic uint32 variable
@@ -111,11 +72,7 @@ static inline uint32_t odp_atomic_fetch_add_u32(odp_atomic_u32_t *atom,
* @param[in,out] atom Pointer to an atomic uint32 variable
* @param val A value to be added to the variable
*/
-static inline void odp_atomic_add_u32(odp_atomic_u32_t *atom,
- uint32_t val)
-{
- (void)__atomic_fetch_add(&atom->v, val, __ATOMIC_RELAXED);
-}
+void odp_atomic_add_u32(odp_atomic_u32_t *atom, uint32_t val);
/**
* Fetch and subtract from atomic uint32 variable
@@ -126,11 +83,7 @@ static inline void odp_atomic_add_u32(odp_atomic_u32_t *atom,
*
* @return Value of the variable before the subtraction
*/
-static inline uint32_t odp_atomic_fetch_sub_u32(odp_atomic_u32_t *atom,
- uint32_t val)
-{
- return __atomic_fetch_sub(&atom->v, val, __ATOMIC_RELAXED);
-}
+uint32_t odp_atomic_fetch_sub_u32(odp_atomic_u32_t *atom, uint32_t val);
/**
* Subtract from atomic uint32 variable
@@ -139,11 +92,7 @@ static inline uint32_t odp_atomic_fetch_sub_u32(odp_atomic_u32_t *atom,
* @param[in,out] atom Pointer to an atomic uint32 variable
* @param val Value to be subtracted from the variable
*/
-static inline void odp_atomic_sub_u32(odp_atomic_u32_t *atom,
- uint32_t val)
-{
- (void)__atomic_fetch_sub(&atom->v, val, __ATOMIC_RELAXED);
-}
+void odp_atomic_sub_u32(odp_atomic_u32_t *atom, uint32_t val);
/**
* Fetch and increment atomic uint32 variable
@@ -154,10 +103,7 @@ static inline void odp_atomic_sub_u32(odp_atomic_u32_t *atom,
* @return Value of the variable before the increment
*/
-static inline uint32_t odp_atomic_fetch_inc_u32(odp_atomic_u32_t *atom)
-{
- return __atomic_fetch_add(&atom->v, 1, __ATOMIC_RELAXED);
-}
+uint32_t odp_atomic_fetch_inc_u32(odp_atomic_u32_t *atom);
/**
* Increment atomic uint32 variable
@@ -165,10 +111,7 @@ static inline uint32_t odp_atomic_fetch_inc_u32(odp_atomic_u32_t *atom)
*
* @param[in,out] atom Pointer to an atomic uint32 variable
*/
-static inline void odp_atomic_inc_u32(odp_atomic_u32_t *atom)
-{
- (void)__atomic_fetch_add(&atom->v, 1, __ATOMIC_RELAXED);
-}
+void odp_atomic_inc_u32(odp_atomic_u32_t *atom);
/**
* Fetch and decrement atomic uint32 variable
@@ -178,10 +121,7 @@ static inline void odp_atomic_inc_u32(odp_atomic_u32_t *atom)
*
* @return Value of the variable before the subtraction
*/
-static inline uint32_t odp_atomic_fetch_dec_u32(odp_atomic_u32_t *atom)
-{
- return __atomic_fetch_sub(&atom->v, 1, __ATOMIC_RELAXED);
-}
+uint32_t odp_atomic_fetch_dec_u32(odp_atomic_u32_t *atom);
/**
* Decrement atomic uint32 variable
@@ -189,10 +129,7 @@ static inline uint32_t odp_atomic_fetch_dec_u32(odp_atomic_u32_t *atom)
*
* @param[in,out] atom Pointer to an atomic uint32 variable
*/
-static inline void odp_atomic_dec_u32(odp_atomic_u32_t *atom)
-{
- (void)__atomic_fetch_sub(&atom->v, 1, __ATOMIC_RELAXED);
-}
+void odp_atomic_dec_u32(odp_atomic_u32_t *atom);
/**
* Initialize atomic uint64 variable
@@ -201,34 +138,7 @@ static inline void odp_atomic_dec_u32(odp_atomic_u32_t *atom)
* @param[out] atom Pointer to an atomic uint64 variable
* @param val Value to initialize the variable with
*/
-static inline void odp_atomic_init_u64(odp_atomic_u64_t *atom, uint64_t val)
-{
- atom->v = val;
-#if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
- __atomic_clear(&atom->lock, __ATOMIC_RELAXED);
-#endif
-}
-
-#if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
-/**
- * @internal
- * Helper macro for lock-based atomic operations on 64-bit integers
- * @param[in,out] atom Pointer to the 64-bit atomic variable
- * @param expr Expression used update the variable.
- * @return The old value of the variable.
- */
-#define ATOMIC_OP(atom, expr) \
-({ \
- uint64_t old_val; \
- /* Loop while lock is already taken, stop when lock becomes clear */ \
- while (__atomic_test_and_set(&(atom)->lock, __ATOMIC_ACQUIRE)) \
- (void)0; \
- old_val = (atom)->v; \
- (expr); /* Perform whatever update is desired */ \
- __atomic_clear(&(atom)->lock, __ATOMIC_RELEASE); \
- old_val; /* Return old value */ \
-})
-#endif
+void odp_atomic_init_u64(odp_atomic_u64_t *atom, uint64_t val);
/**
* Load value of atomic uint64 variable
@@ -238,14 +148,7 @@ static inline void odp_atomic_init_u64(odp_atomic_u64_t *atom, uint64_t val)
*
* @return Value of the variable
*/
-static inline uint64_t odp_atomic_load_u64(odp_atomic_u64_t *atom)
-{
-#if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
- return ATOMIC_OP(atom, (void)0);
-#else
- return __atomic_load_n(&atom->v, __ATOMIC_RELAXED);
-#endif
-}
+uint64_t odp_atomic_load_u64(odp_atomic_u64_t *atom);
/**
* Store value to atomic uint64 variable
@@ -254,15 +157,7 @@ static inline uint64_t odp_atomic_load_u64(odp_atomic_u64_t *atom)
* @param[out] atom Pointer to an atomic uint64 variable
* @param val Value to store in the variable
*/
-static inline void odp_atomic_store_u64(odp_atomic_u64_t *atom,
- uint64_t val)
-{
-#if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
- (void)ATOMIC_OP(atom, atom->v = val);
-#else
- __atomic_store_n(&atom->v, val, __ATOMIC_RELAXED);
-#endif
-}
+void odp_atomic_store_u64(odp_atomic_u64_t *atom, uint64_t val);
/**
* Fetch and add to atomic uint64 variable
@@ -274,15 +169,7 @@ static inline void odp_atomic_store_u64(odp_atomic_u64_t *atom,
* @return Value of the variable before the addition
*/
-static inline uint64_t odp_atomic_fetch_add_u64(odp_atomic_u64_t *atom,
- uint64_t val)
-{
-#if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
- return ATOMIC_OP(atom, atom->v += val);
-#else
- return __atomic_fetch_add(&atom->v, val, __ATOMIC_RELAXED);
-#endif
-}
+uint64_t odp_atomic_fetch_add_u64(odp_atomic_u64_t *atom, uint64_t val);
/**
* Add to atomic uint64 variable
@@ -292,14 +179,7 @@ static inline uint64_t odp_atomic_fetch_add_u64(odp_atomic_u64_t *atom,
* @param val Value to be added to the variable
*
*/
-static inline void odp_atomic_add_u64(odp_atomic_u64_t *atom, uint64_t val)
-{
-#if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
- (void)ATOMIC_OP(atom, atom->v += val);
-#else
- (void)__atomic_fetch_add(&atom->v, val, __ATOMIC_RELAXED);
-#endif
-}
+void odp_atomic_add_u64(odp_atomic_u64_t *atom, uint64_t val);
/**
* Fetch and subtract from atomic uint64 variable
@@ -310,15 +190,7 @@ static inline void odp_atomic_add_u64(odp_atomic_u64_t *atom, uint64_t val)
*
* @return Value of the variable before the subtraction
*/
-static inline uint64_t odp_atomic_fetch_sub_u64(odp_atomic_u64_t *atom,
- uint64_t val)
-{
-#if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
- return ATOMIC_OP(atom, atom->v -= val);
-#else
- return __atomic_fetch_sub(&atom->v, val, __ATOMIC_RELAXED);
-#endif
-}
+uint64_t odp_atomic_fetch_sub_u64(odp_atomic_u64_t *atom, uint64_t val);
/**
* Subtract from atomic uint64 variable
@@ -327,14 +199,7 @@ static inline uint64_t odp_atomic_fetch_sub_u64(odp_atomic_u64_t *atom,
* @param[in,out] atom Pointer to an atomic uint64 variable
* @param val Value to be subtracted from the variable
*/
-static inline void odp_atomic_sub_u64(odp_atomic_u64_t *atom, uint64_t val)
-{
-#if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
- (void)ATOMIC_OP(atom, atom->v -= val);
-#else
- (void)__atomic_fetch_sub(&atom->v, val, __ATOMIC_RELAXED);
-#endif
-}
+void odp_atomic_sub_u64(odp_atomic_u64_t *atom, uint64_t val);
/**
* Fetch and increment atomic uint64 variable
@@ -344,14 +209,7 @@ static inline void odp_atomic_sub_u64(odp_atomic_u64_t *atom, uint64_t val)
*
* @return Value of the variable before the increment
*/
-static inline uint64_t odp_atomic_fetch_inc_u64(odp_atomic_u64_t *atom)
-{
-#if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
- return ATOMIC_OP(atom, atom->v++);
-#else
- return __atomic_fetch_add(&atom->v, 1, __ATOMIC_RELAXED);
-#endif
-}
+uint64_t odp_atomic_fetch_inc_u64(odp_atomic_u64_t *atom);
/**
* Increment atomic uint64 variable
@@ -359,14 +217,7 @@ static inline uint64_t odp_atomic_fetch_inc_u64(odp_atomic_u64_t *atom)
*
* @param[in,out] atom Pointer to an atomic uint64 variable
*/
-static inline void odp_atomic_inc_u64(odp_atomic_u64_t *atom)
-{
-#if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
- (void)ATOMIC_OP(atom, atom->v++);
-#else
- (void)__atomic_fetch_add(&atom->v, 1, __ATOMIC_RELAXED);
-#endif
-}
+void odp_atomic_inc_u64(odp_atomic_u64_t *atom);
/**
* Fetch and decrement atomic uint64 variable
@@ -376,14 +227,7 @@ static inline void odp_atomic_inc_u64(odp_atomic_u64_t *atom)
*
* @return Value of the variable before the decrement
*/
-static inline uint64_t odp_atomic_fetch_dec_u64(odp_atomic_u64_t *atom)
-{
-#if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
- return ATOMIC_OP(atom, atom->v--);
-#else
- return __atomic_fetch_sub(&atom->v, 1, __ATOMIC_RELAXED);
-#endif
-}
+uint64_t odp_atomic_fetch_dec_u64(odp_atomic_u64_t *atom);
/**
* Decrement atomic uint64 variable
@@ -391,14 +235,7 @@ static inline uint64_t odp_atomic_fetch_dec_u64(odp_atomic_u64_t *atom)
*
* @param[in,out] atom Pointer to an atomic uint64 variable
*/
-static inline void odp_atomic_dec_u64(odp_atomic_u64_t *atom)
-{
-#if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
- (void)ATOMIC_OP(atom, atom->v--);
-#else
- (void)__atomic_fetch_sub(&atom->v, 1, __ATOMIC_RELAXED);
-#endif
-}
+void odp_atomic_dec_u64(odp_atomic_u64_t *atom);
/**
* @}