aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Roxell <anders.roxell@linaro.org>2015-01-27 19:41:51 +0100
committerMaxim Uvarov <maxim.uvarov@linaro.org>2015-01-29 20:42:33 +0300
commit6f7cc553219676c71b83954e384b8071f6c144b9 (patch)
tree25c22ee0076da406ba9b989becd76a13ebaf2bf8
parentcb197cd973230fe765adc159ba82bd9edda0dd9f (diff)
api: atomic: move typedefs and inline functions
Align the style with the rest of the header files of linux-generic Signed-off-by: Anders Roxell <anders.roxell@linaro.org> Reviewed-by: Balasubramanian Manoharan <bala.manoharan@linaro.org> Reviewed-by: Taras Kondratiuk <taras.kondratiuk@linaro.org> Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
-rw-r--r--include/odp/api/atomic.h209
-rw-r--r--platform/linux-generic/Makefile.am1
-rw-r--r--platform/linux-generic/include/odp/atomic.h165
-rw-r--r--platform/linux-generic/include/odp/atomic_types.h78
4 files changed, 267 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);
/**
* @}
diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am
index d07dbaa5a..f8a313322 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -12,6 +12,7 @@ odpincludedir= $(includedir)/odp
odpinclude_HEADERS = \
$(top_srcdir)/platform/linux-generic/include/odp/align.h \
$(top_srcdir)/platform/linux-generic/include/odp/atomic.h \
+ $(top_srcdir)/platform/linux-generic/include/odp/atomic_types.h \
$(top_srcdir)/platform/linux-generic/include/odp/barrier.h \
$(top_srcdir)/platform/linux-generic/include/odp/buffer.h \
$(top_srcdir)/platform/linux-generic/include/odp/pool.h \
diff --git a/platform/linux-generic/include/odp/atomic.h b/platform/linux-generic/include/odp/atomic.h
index f39ef2a81..952b0f4a0 100644
--- a/platform/linux-generic/include/odp/atomic.h
+++ b/platform/linux-generic/include/odp/atomic.h
@@ -17,10 +17,175 @@
extern "C" {
#endif
+#include <stdint.h>
+#include <odp/align.h>
+#include <odp/atomic_types.h>
+
/** @ingroup odp_synchronizers
* @{
*/
+static inline void odp_atomic_init_u32(odp_atomic_u32_t *atom, uint32_t val)
+{
+ __atomic_store_n(&atom->v, val, __ATOMIC_RELAXED);
+}
+
+static inline uint32_t odp_atomic_load_u32(odp_atomic_u32_t *atom)
+{
+ return __atomic_load_n(&atom->v, __ATOMIC_RELAXED);
+}
+
+static inline void odp_atomic_store_u32(odp_atomic_u32_t *atom,
+ uint32_t val)
+{
+ __atomic_store_n(&atom->v, val, __ATOMIC_RELAXED);
+}
+
+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);
+}
+
+static inline void odp_atomic_add_u32(odp_atomic_u32_t *atom,
+ uint32_t val)
+{
+ (void)__atomic_fetch_add(&atom->v, val, __ATOMIC_RELAXED);
+}
+
+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);
+}
+
+static inline void odp_atomic_sub_u32(odp_atomic_u32_t *atom,
+ uint32_t val)
+{
+ (void)__atomic_fetch_sub(&atom->v, val, __ATOMIC_RELAXED);
+}
+
+static inline uint32_t odp_atomic_fetch_inc_u32(odp_atomic_u32_t *atom)
+{
+ return __atomic_fetch_add(&atom->v, 1, __ATOMIC_RELAXED);
+}
+
+static inline void odp_atomic_inc_u32(odp_atomic_u32_t *atom)
+{
+ (void)__atomic_fetch_add(&atom->v, 1, __ATOMIC_RELAXED);
+}
+
+static inline uint32_t odp_atomic_fetch_dec_u32(odp_atomic_u32_t *atom)
+{
+ return __atomic_fetch_sub(&atom->v, 1, __ATOMIC_RELAXED);
+}
+
+static inline void odp_atomic_dec_u32(odp_atomic_u32_t *atom)
+{
+ (void)__atomic_fetch_sub(&atom->v, 1, __ATOMIC_RELAXED);
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
/**
* @}
*/
diff --git a/platform/linux-generic/include/odp/atomic_types.h b/platform/linux-generic/include/odp/atomic_types.h
new file mode 100644
index 000000000..69a50c927
--- /dev/null
+++ b/platform/linux-generic/include/odp/atomic_types.h
@@ -0,0 +1,78 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/**
+ * @file
+ *
+ * ODP atomic operations
+ */
+
+#ifndef ODP_ATOMIC_TYPES_H_
+#define ODP_ATOMIC_TYPES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup odp_synchronizers
+ * Atomic types and relaxed operations. These operations cannot be used for
+ * synchronization.
+ * @{
+ */
+
+/**
+ * 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! */
+
+#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
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif