Message ID | 1403027720-9738-5-git-send-email-taras.kondratiuk@linaro.org |
---|---|
State | RFC |
Headers | show |
On 2014-06-17 20:55, Taras Kondratiuk wrote: > Signed-off-by: Taras Kondratiuk <taras.kondratiuk@linaro.org> > --- > include/odp_atomic.h | 207 ++-------- > platform/linux-generic/include/plat/odp_atomic.h | 457 ++++++++++++++++++++++ > 2 files changed, 493 insertions(+), 171 deletions(-) > create mode 100644 platform/linux-generic/include/plat/odp_atomic.h > > diff --git a/include/odp_atomic.h b/include/odp_atomic.h > index 5a25dc7..d33c226 100644 > --- a/include/odp_atomic.h > +++ b/include/odp_atomic.h > @@ -20,22 +20,22 @@ extern "C" { > > > #include <odp_std_types.h> > - > +#include <plat/odp_atomic.h> > > /** > * Atomic integer > */ > -typedef volatile int32_t odp_atomic_int_t; > +typedef plat_odp_atomic_int_t odp_atomic_int_t; > > /** > * Atomic unsigned integer 64 bits > */ > -typedef volatile uint64_t odp_atomic_u64_t; > +typedef plat_odp_atomic_u64_t odp_atomic_u64_t; > > /** > * Atomic unsigned integer 32 bits > */ > -typedef volatile uint32_t odp_atomic_u32_t; > +typedef plat_odp_atomic_u32_t odp_atomic_u32_t; > > > /** > @@ -45,10 +45,7 @@ typedef volatile uint32_t odp_atomic_u32_t; > * > * @note The operation is not synchoronized with other threads > */ > -static inline void odp_atomic_init_int(odp_atomic_int_t *ptr) > -{ > - *ptr = 0; > -} > +void odp_atomic_init_int(odp_atomic_int_t *ptr); > > /** > * Load value of atomic integer > @@ -59,10 +56,7 @@ static inline void odp_atomic_init_int(odp_atomic_int_t *ptr) > * > * @note The operation is not synchoronized with other threads > */ > -static inline int odp_atomic_load_int(odp_atomic_int_t *ptr) > -{ > - return *ptr; > -} > +int odp_atomic_load_int(odp_atomic_int_t *ptr); > > /** > * Store value to atomic integer > @@ -72,10 +66,7 @@ static inline int odp_atomic_load_int(odp_atomic_int_t *ptr) > * > * @note The operation is not synchoronized with other threads > */ > -static inline void odp_atomic_store_int(odp_atomic_int_t *ptr, int new_value) > -{ > - *ptr = new_value; > -} > +void odp_atomic_store_int(odp_atomic_int_t *ptr, int new_value); > > /** > * Fetch and add atomic integer > @@ -85,10 +76,7 @@ static inline void odp_atomic_store_int(odp_atomic_int_t *ptr, int new_value) > * > * @return Value of the variable before the operation > */ > -static inline int odp_atomic_fetch_add_int(odp_atomic_int_t *ptr, int value) > -{ > - return __sync_fetch_and_add(ptr, value); > -} > +int odp_atomic_fetch_add_int(odp_atomic_int_t *ptr, int value); > > /** > * Fetch and substract atomic integer > @@ -98,10 +86,7 @@ static inline int odp_atomic_fetch_add_int(odp_atomic_int_t *ptr, int value) > * > * @return Value of the variable before the operation > */ > -static inline int odp_atomic_fetch_sub_int(odp_atomic_int_t *ptr, int value) > -{ > - return __sync_fetch_and_sub(ptr, value); > -} > +int odp_atomic_fetch_sub_int(odp_atomic_int_t *ptr, int value); > > /** > * Fetch and increment atomic integer by 1 > @@ -110,10 +95,7 @@ static inline int odp_atomic_fetch_sub_int(odp_atomic_int_t *ptr, int value) > * > * @return Value of the variable before the operation > */ > -static inline int odp_atomic_fetch_inc_int(odp_atomic_int_t *ptr) > -{ > - return odp_atomic_fetch_add_int(ptr, 1); > -} > +int odp_atomic_fetch_inc_int(odp_atomic_int_t *ptr); > > /** > * Increment atomic integer by 1 > @@ -121,10 +103,7 @@ static inline int odp_atomic_fetch_inc_int(odp_atomic_int_t *ptr) > * @param ptr An atomic variable > * > */ > -static inline void odp_atomic_inc_int(odp_atomic_int_t *ptr) > -{ > - odp_atomic_fetch_add_int(ptr, 1); > -} > +void odp_atomic_inc_int(odp_atomic_int_t *ptr); > > /** > * Fetch and decrement atomic integer by 1 > @@ -133,10 +112,7 @@ static inline void odp_atomic_inc_int(odp_atomic_int_t *ptr) > * > * @return Value of the variable before the operation > */ > -static inline int odp_atomic_fetch_dec_int(odp_atomic_int_t *ptr) > -{ > - return odp_atomic_fetch_sub_int(ptr, 1); > -} > +int odp_atomic_fetch_dec_int(odp_atomic_int_t *ptr); > > /** > * Decrement atomic integer by 1 > @@ -144,10 +120,7 @@ static inline int odp_atomic_fetch_dec_int(odp_atomic_int_t *ptr) > * @param ptr An atomic variable > * > */ > -static inline void odp_atomic_dec_int(odp_atomic_int_t *ptr) > -{ > - odp_atomic_fetch_sub_int(ptr, 1); > -} > +void odp_atomic_dec_int(odp_atomic_int_t *ptr); > > /** > * Initialize atomic uint32 > @@ -156,10 +129,7 @@ static inline void odp_atomic_dec_int(odp_atomic_int_t *ptr) > * > * @note The operation is not synchoronized with other threads > */ > -static inline void odp_atomic_init_u32(odp_atomic_u32_t *ptr) > -{ > - *ptr = 0; > -} > +void odp_atomic_init_u32(odp_atomic_u32_t *ptr); > > /** > * Load value of atomic uint32 > @@ -170,10 +140,7 @@ static inline void odp_atomic_init_u32(odp_atomic_u32_t *ptr) > * > * @note The operation is not synchoronized with other threads > */ > -static inline uint32_t odp_atomic_load_u32(odp_atomic_u32_t *ptr) > -{ > - return *ptr; > -} > +uint32_t odp_atomic_load_u32(odp_atomic_u32_t *ptr); > > /** > * Store value to atomic uint32 > @@ -183,11 +150,7 @@ static inline uint32_t odp_atomic_load_u32(odp_atomic_u32_t *ptr) > * > * @note The operation is not synchoronized with other threads > */ > -static inline void odp_atomic_store_u32(odp_atomic_u32_t *ptr, > - uint32_t new_value) > -{ > - *ptr = new_value; > -} > +void odp_atomic_store_u32(odp_atomic_u32_t *ptr, uint32_t new_value); > > /** > * Fetch and add atomic uint32 > @@ -197,11 +160,7 @@ static inline void odp_atomic_store_u32(odp_atomic_u32_t *ptr, > * > * @return Value of the variable before the operation > */ > -static inline uint32_t odp_atomic_fetch_add_u32(odp_atomic_u32_t *ptr, > - uint32_t value) > -{ > - return __sync_fetch_and_add(ptr, value); > -} > +uint32_t odp_atomic_fetch_add_u32(odp_atomic_u32_t *ptr, uint32_t value); > > /** > * Fetch and substract uint32 > @@ -211,11 +170,7 @@ static inline uint32_t odp_atomic_fetch_add_u32(odp_atomic_u32_t *ptr, > * > * @return Value of the variable before the operation > */ > -static inline uint32_t odp_atomic_fetch_sub_u32(odp_atomic_u32_t *ptr, > - uint32_t value) > -{ > - return __sync_fetch_and_sub(ptr, value); > -} > +uint32_t odp_atomic_fetch_sub_u32(odp_atomic_u32_t *ptr, uint32_t value); > > /** > * Fetch and increment atomic uint32 by 1 > @@ -224,27 +179,7 @@ static inline uint32_t odp_atomic_fetch_sub_u32(odp_atomic_u32_t *ptr, > * > * @return Value of the variable before the operation > */ > -#if defined __OCTEON__ > - > -static inline uint32_t odp_atomic_fetch_inc_u32(odp_atomic_u32_t *ptr) > -{ > - uint32_t ret; > - > - __asm__ __volatile__ ("syncws"); > - __asm__ __volatile__ ("lai %0,(%2)" : "=r" (ret), "+m" (ptr) : > - "r" (ptr)); > - > - return ret; > -} > - > -#else > - > -static inline uint32_t odp_atomic_fetch_inc_u32(odp_atomic_u32_t *ptr) > -{ > - return odp_atomic_fetch_add_u32(ptr, 1); > -} > - > -#endif > +uint32_t odp_atomic_fetch_inc_u32(odp_atomic_u32_t *ptr); > > /** > * Increment atomic uint32 by 1 > @@ -252,10 +187,7 @@ static inline uint32_t odp_atomic_fetch_inc_u32(odp_atomic_u32_t *ptr) > * @param ptr An atomic variable > * > */ > -static inline void odp_atomic_inc_u32(odp_atomic_u32_t *ptr) > -{ > - odp_atomic_fetch_add_u32(ptr, 1); > -} > +void odp_atomic_inc_u32(odp_atomic_u32_t *ptr); > > /** > * Fetch and decrement uint32 by 1 > @@ -264,10 +196,7 @@ static inline void odp_atomic_inc_u32(odp_atomic_u32_t *ptr) > * > * @return Value of the variable before the operation > */ > -static inline uint32_t odp_atomic_fetch_dec_u32(odp_atomic_u32_t *ptr) > -{ > - return odp_atomic_fetch_sub_u32(ptr, 1); > -} > +uint32_t odp_atomic_fetch_dec_u32(odp_atomic_u32_t *ptr); > > /** > * Decrement atomic uint32 by 1 > @@ -275,10 +204,7 @@ static inline uint32_t odp_atomic_fetch_dec_u32(odp_atomic_u32_t *ptr) > * @param ptr An atomic variable > * > */ > -static inline void odp_atomic_dec_u32(odp_atomic_u32_t *ptr) > -{ > - odp_atomic_fetch_sub_u32(ptr, 1); > -} > +void odp_atomic_dec_u32(odp_atomic_u32_t *ptr); > > /** > * Atomic compare and set for 32bit > @@ -288,11 +214,7 @@ static inline void odp_atomic_dec_u32(odp_atomic_u32_t *ptr) > * @param src new value. > * @return Non-zero on success; 0 on failure. > */ > -static inline int > -odp_atomic_cmpset_u32(odp_atomic_u32_t *dst, uint32_t exp, uint32_t src) > -{ > - return __sync_bool_compare_and_swap(dst, exp, src); > -} > +int odp_atomic_cmpset_u32(odp_atomic_u32_t *dst, uint32_t exp, uint32_t src); > > /** > * Initialize atomic uint64 > @@ -301,10 +223,7 @@ odp_atomic_cmpset_u32(odp_atomic_u32_t *dst, uint32_t exp, uint32_t src) > * > * @note The operation is not synchoronized with other threads > */ > -static inline void odp_atomic_init_u64(odp_atomic_u64_t *ptr) > -{ > - *ptr = 0; > -} > +void odp_atomic_init_u64(odp_atomic_u64_t *ptr); > > /** > * Load value of atomic uint64 > @@ -315,10 +234,7 @@ static inline void odp_atomic_init_u64(odp_atomic_u64_t *ptr) > * > * @note The operation is not synchoronized with other threads > */ > -static inline uint64_t odp_atomic_load_u64(odp_atomic_u64_t *ptr) > -{ > - return *ptr; > -} > +uint64_t odp_atomic_load_u64(odp_atomic_u64_t *ptr); > > /** > * Store value to atomic uint64 > @@ -328,11 +244,7 @@ static inline uint64_t odp_atomic_load_u64(odp_atomic_u64_t *ptr) > * > * @note The operation is not synchoronized with other threads > */ > -static inline void odp_atomic_store_u64(odp_atomic_u64_t *ptr, > - uint64_t new_value) > -{ > - *ptr = new_value; > -} > +void odp_atomic_store_u64(odp_atomic_u64_t *ptr, uint64_t new_value); > > /** > * Add atomic uint64 > @@ -341,10 +253,7 @@ static inline void odp_atomic_store_u64(odp_atomic_u64_t *ptr, > * @param value A value to be added to the variable > * > */ > -static inline void odp_atomic_add_u64(odp_atomic_u64_t *ptr, uint64_t value) > -{ > - __sync_fetch_and_add(ptr, value); > -} > +void odp_atomic_add_u64(odp_atomic_u64_t *ptr, uint64_t value); > > /** > * Fetch and add atomic uint64 > @@ -354,21 +263,8 @@ static inline void odp_atomic_add_u64(odp_atomic_u64_t *ptr, uint64_t value) > * > * @return Value of the variable before the operation > */ > +uint64_t odp_atomic_fetch_add_u64(odp_atomic_u64_t *ptr, uint64_t value); > > -#if defined __powerpc__ && !defined __powerpc64__ > -static inline uint64_t odp_atomic_fetch_add_u64(odp_atomic_u64_t *ptr, > - uint64_t value) > -{ > - return __sync_fetch_and_add((odp_atomic_u32_t *)ptr, > - (uint32_t)value); > -} > -#else > -static inline uint64_t odp_atomic_fetch_add_u64(odp_atomic_u64_t *ptr, > - uint64_t value) > -{ > - return __sync_fetch_and_add(ptr, value); > -} > -#endif > /** > * Subtract atomic uint64 > * > @@ -376,10 +272,7 @@ static inline uint64_t odp_atomic_fetch_add_u64(odp_atomic_u64_t *ptr, > * @param value A value to be subtracted from the variable > * > */ > -static inline void odp_atomic_sub_u64(odp_atomic_u64_t *ptr, uint64_t value) > -{ > - __sync_fetch_and_sub(ptr, value); > -} > +void odp_atomic_sub_u64(odp_atomic_u64_t *ptr, uint64_t value); > > /** > * Fetch and subtract atomic uint64 > @@ -389,20 +282,8 @@ static inline void odp_atomic_sub_u64(odp_atomic_u64_t *ptr, uint64_t value) > * > * @return Value of the variable before the operation > */ > -#if defined __powerpc__ && !defined __powerpc64__ > -static inline uint64_t odp_atomic_fetch_sub_u64(odp_atomic_u64_t *ptr, > - uint64_t value) > -{ > - return __sync_fetch_and_sub((odp_atomic_u32_t *)ptr, > - (uint32_t)value); > -} > -#else > -static inline uint64_t odp_atomic_fetch_sub_u64(odp_atomic_u64_t *ptr, > - uint64_t value) > -{ > - return __sync_fetch_and_sub(ptr, value); > -} > -#endif > +uint64_t odp_atomic_fetch_sub_u64(odp_atomic_u64_t *ptr, uint64_t value); > + > /** > * Fetch and increment atomic uint64 by 1 > * > @@ -410,10 +291,7 @@ static inline uint64_t odp_atomic_fetch_sub_u64(odp_atomic_u64_t *ptr, > * > * @return Value of the variable before the operation > */ > -static inline uint64_t odp_atomic_fetch_inc_u64(odp_atomic_u64_t *ptr) > -{ > - return odp_atomic_fetch_add_u64(ptr, 1); > -} > +uint64_t odp_atomic_fetch_inc_u64(odp_atomic_u64_t *ptr); > > /** > * Increment atomic uint64 by 1 > @@ -421,10 +299,7 @@ static inline uint64_t odp_atomic_fetch_inc_u64(odp_atomic_u64_t *ptr) > * @param ptr An atomic variable > * > */ > -static inline void odp_atomic_inc_u64(odp_atomic_u64_t *ptr) > -{ > - odp_atomic_fetch_add_u64(ptr, 1); > -} > +void odp_atomic_inc_u64(odp_atomic_u64_t *ptr); > > /** > * Fetch and decement atomic uint64 by 1 > @@ -433,10 +308,7 @@ static inline void odp_atomic_inc_u64(odp_atomic_u64_t *ptr) > * > * @return Value of the variable before the operation > */ > -static inline uint64_t odp_atomic_fetch_dec_u64(odp_atomic_u64_t *ptr) > -{ > - return odp_atomic_fetch_sub_u64(ptr, 1); > -} > +uint64_t odp_atomic_fetch_dec_u64(odp_atomic_u64_t *ptr); > > /** > * Deccrement atomic uint64 by 1 > @@ -444,10 +316,7 @@ static inline uint64_t odp_atomic_fetch_dec_u64(odp_atomic_u64_t *ptr) > * @param ptr An atomic variable > * > */ > -static inline void odp_atomic_dec_u64(odp_atomic_u64_t *ptr) > -{ > - odp_atomic_fetch_sub_u64(ptr, 1); > -} > +void odp_atomic_dec_u64(odp_atomic_u64_t *ptr); > > /** > * Atomic compare and set for 64bit > @@ -457,11 +326,7 @@ static inline void odp_atomic_dec_u64(odp_atomic_u64_t *ptr) > * @param src new value. > * @return Non-zero on success; 0 on failure. > */ > -static inline int > -odp_atomic_cmpset_u64(odp_atomic_u64_t *dst, uint64_t exp, uint64_t src) > -{ > - return __sync_bool_compare_and_swap(dst, exp, src); > -} > +int odp_atomic_cmpset_u64(odp_atomic_u64_t *dst, uint64_t exp, uint64_t src); > > #ifdef __cplusplus > } > diff --git a/platform/linux-generic/include/plat/odp_atomic.h b/platform/linux-generic/include/plat/odp_atomic.h > new file mode 100644 > index 0000000..e70608d > --- /dev/null > +++ b/platform/linux-generic/include/plat/odp_atomic.h > @@ -0,0 +1,457 @@ > +/* Copyright (c) 2013, Linaro Limited > + * All rights reserved. > + * > + * SPDX-License-Identifier: BSD-3-Clause > + */ > + > + > +/** > + * @file > + * > + * ODP atomic operations > + */ > + > +#ifndef ODP_ATOMIC_H_ > +#error This file should be included only into corresponding top level header > +#else > + > +/** > + * Atomic integer > + */ > +typedef volatile int32_t plat_odp_atomic_int_t; > + > +/** > + * Atomic unsigned integer 64 bits > + */ > +typedef volatile uint64_t plat_odp_atomic_u64_t; > + > +/** > + * Atomic unsigned integer 32 bits > + */ > +typedef volatile uint32_t plat_odp_atomic_u32_t; > + > +/* Define OPD types here to use them in inline functions below */ Nit: Define ODP types here which are use by the inline functions below Cheers, Anders > +typedef plat_odp_atomic_int_t odp_atomic_int_t; > +typedef plat_odp_atomic_u64_t odp_atomic_u64_t; > +typedef plat_odp_atomic_u32_t odp_atomic_u32_t; > + > + > +static inline void odp_atomic_init_int(odp_atomic_int_t *ptr) > +{ > + *ptr = 0; > +} > + > +/** > + * Load value of atomic integer > + * > + * @param ptr An atomic variable > + * > + * @return atomic integer value > + * > + * @note The operation is not synchoronized with other threads > + */ > +static inline int odp_atomic_load_int(odp_atomic_int_t *ptr) > +{ > + return *ptr; > +} > + > +/** > + * Store value to atomic integer > + * > + * @param ptr An atomic variable > + * @param new_value Store new_value to a variable > + * > + * @note The operation is not synchoronized with other threads > + */ > +static inline void odp_atomic_store_int(odp_atomic_int_t *ptr, int new_value) > +{ > + *ptr = new_value; > +} > + > +/** > + * Fetch and add atomic integer > + * > + * @param ptr An atomic variable > + * @param value A value to be added to the variable > + * > + * @return Value of the variable before the operation > + */ > +static inline int odp_atomic_fetch_add_int(odp_atomic_int_t *ptr, int value) > +{ > + return __sync_fetch_and_add(ptr, value); > +} > + > +/** > + * Fetch and substract atomic integer > + * > + * @param ptr An atomic int variable > + * @param value A value to be subtracted from the variable > + * > + * @return Value of the variable before the operation > + */ > +static inline int odp_atomic_fetch_sub_int(odp_atomic_int_t *ptr, int value) > +{ > + return __sync_fetch_and_sub(ptr, value); > +} > + > +/** > + * Fetch and increment atomic integer by 1 > + * > + * @param ptr An atomic variable > + * > + * @return Value of the variable before the operation > + */ > +static inline int odp_atomic_fetch_inc_int(odp_atomic_int_t *ptr) > +{ > + return odp_atomic_fetch_add_int(ptr, 1); > +} > + > +/** > + * Increment atomic integer by 1 > + * > + * @param ptr An atomic variable > + * > + */ > +static inline void odp_atomic_inc_int(odp_atomic_int_t *ptr) > +{ > + odp_atomic_fetch_add_int(ptr, 1); > +} > + > +/** > + * Fetch and decrement atomic integer by 1 > + * > + * @param ptr An atomic int variable > + * > + * @return Value of the variable before the operation > + */ > +static inline int odp_atomic_fetch_dec_int(odp_atomic_int_t *ptr) > +{ > + return odp_atomic_fetch_sub_int(ptr, 1); > +} > + > +/** > + * Decrement atomic integer by 1 > + * > + * @param ptr An atomic variable > + * > + */ > +static inline void odp_atomic_dec_int(odp_atomic_int_t *ptr) > +{ > + odp_atomic_fetch_sub_int(ptr, 1); > +} > + > +/** > + * Initialize atomic uint32 > + * > + * @param ptr An atomic variable > + * > + * @note The operation is not synchoronized with other threads > + */ > +static inline void odp_atomic_init_u32(odp_atomic_u32_t *ptr) > +{ > + *ptr = 0; > +} > + > +/** > + * Load value of atomic uint32 > + * > + * @param ptr An atomic variable > + * > + * @return atomic uint32 value > + * > + * @note The operation is not synchoronized with other threads > + */ > +static inline uint32_t odp_atomic_load_u32(odp_atomic_u32_t *ptr) > +{ > + return *ptr; > +} > + > +/** > + * Store value to atomic uint32 > + * > + * @param ptr An atomic variable > + * @param new_value Store new_value to a variable > + * > + * @note The operation is not synchoronized with other threads > + */ > +static inline void odp_atomic_store_u32(odp_atomic_u32_t *ptr, > + uint32_t new_value) > +{ > + *ptr = new_value; > +} > + > +/** > + * Fetch and add atomic uint32 > + * > + * @param ptr An atomic variable > + * @param value A value to be added to the variable > + * > + * @return Value of the variable before the operation > + */ > +static inline uint32_t odp_atomic_fetch_add_u32(odp_atomic_u32_t *ptr, > + uint32_t value) > +{ > + return __sync_fetch_and_add(ptr, value); > +} > + > +/** > + * Fetch and substract uint32 > + * > + * @param ptr An atomic variable > + * @param value A value to be sub to the variable > + * > + * @return Value of the variable before the operation > + */ > +static inline uint32_t odp_atomic_fetch_sub_u32(odp_atomic_u32_t *ptr, > + uint32_t value) > +{ > + return __sync_fetch_and_sub(ptr, value); > +} > + > +/** > + * Fetch and increment atomic uint32 by 1 > + * > + * @param ptr An atomic variable > + * > + * @return Value of the variable before the operation > + */ > +#if defined __OCTEON__ > + > +static inline uint32_t odp_atomic_fetch_inc_u32(odp_atomic_u32_t *ptr) > +{ > + uint32_t ret; > + > + __asm__ __volatile__ ("syncws"); > + __asm__ __volatile__ ("lai %0,(%2)" : "=r" (ret), "+m" (ptr) : > + "r" (ptr)); > + > + return ret; > +} > + > +#else > + > +static inline uint32_t odp_atomic_fetch_inc_u32(odp_atomic_u32_t *ptr) > +{ > + return odp_atomic_fetch_add_u32(ptr, 1); > +} > + > +#endif > + > +/** > + * Increment atomic uint32 by 1 > + * > + * @param ptr An atomic variable > + * > + */ > +static inline void odp_atomic_inc_u32(odp_atomic_u32_t *ptr) > +{ > + odp_atomic_fetch_add_u32(ptr, 1); > +} > + > +/** > + * Fetch and decrement uint32 by 1 > + * > + * @param ptr An atomic variable > + * > + * @return Value of the variable before the operation > + */ > +static inline uint32_t odp_atomic_fetch_dec_u32(odp_atomic_u32_t *ptr) > +{ > + return odp_atomic_fetch_sub_u32(ptr, 1); > +} > + > +/** > + * Decrement atomic uint32 by 1 > + * > + * @param ptr An atomic variable > + * > + */ > +static inline void odp_atomic_dec_u32(odp_atomic_u32_t *ptr) > +{ > + odp_atomic_fetch_sub_u32(ptr, 1); > +} > + > +/** > + * Atomic compare and set for 32bit > + * > + * @param dst destination location into which the value will be written. > + * @param exp expected value. > + * @param src new value. > + * @return Non-zero on success; 0 on failure. > + */ > +static inline int > +odp_atomic_cmpset_u32(odp_atomic_u32_t *dst, uint32_t exp, uint32_t src) > +{ > + return __sync_bool_compare_and_swap(dst, exp, src); > +} > + > +/** > + * Initialize atomic uint64 > + * > + * @param ptr An atomic variable > + * > + * @note The operation is not synchoronized with other threads > + */ > +static inline void odp_atomic_init_u64(odp_atomic_u64_t *ptr) > +{ > + *ptr = 0; > +} > + > +/** > + * Load value of atomic uint64 > + * > + * @param ptr An atomic variable > + * > + * @return atomic uint64 value > + * > + * @note The operation is not synchoronized with other threads > + */ > +static inline uint64_t odp_atomic_load_u64(odp_atomic_u64_t *ptr) > +{ > + return *ptr; > +} > + > +/** > + * Store value to atomic uint64 > + * > + * @param ptr An atomic variable > + * @param new_value Store new_value to a variable > + * > + * @note The operation is not synchoronized with other threads > + */ > +static inline void odp_atomic_store_u64(odp_atomic_u64_t *ptr, > + uint64_t new_value) > +{ > + *ptr = new_value; > +} > + > +/** > + * Add atomic uint64 > + * > + * @param ptr An atomic variable > + * @param value A value to be added to the variable > + * > + */ > +static inline void odp_atomic_add_u64(odp_atomic_u64_t *ptr, uint64_t value) > +{ > + __sync_fetch_and_add(ptr, value); > +} > + > +/** > + * Fetch and add atomic uint64 > + * > + * @param ptr An atomic variable > + * @param value A value to be added to the variable > + * > + * @return Value of the variable before the operation > + */ > + > +#if defined __powerpc__ && !defined __powerpc64__ > +static inline uint64_t odp_atomic_fetch_add_u64(odp_atomic_u64_t *ptr, > + uint64_t value) > +{ > + return __sync_fetch_and_add((odp_atomic_u32_t *)ptr, > + (uint32_t)value); > +} > +#else > +static inline uint64_t odp_atomic_fetch_add_u64(odp_atomic_u64_t *ptr, > + uint64_t value) > +{ > + return __sync_fetch_and_add(ptr, value); > +} > +#endif > +/** > + * Subtract atomic uint64 > + * > + * @param ptr An atomic variable > + * @param value A value to be subtracted from the variable > + * > + */ > +static inline void odp_atomic_sub_u64(odp_atomic_u64_t *ptr, uint64_t value) > +{ > + __sync_fetch_and_sub(ptr, value); > +} > + > +/** > + * Fetch and subtract atomic uint64 > + * > + * @param ptr An atomic variable > + * @param value A value to be subtracted from the variable > + * > + * @return Value of the variable before the operation > + */ > +#if defined __powerpc__ && !defined __powerpc64__ > +static inline uint64_t odp_atomic_fetch_sub_u64(odp_atomic_u64_t *ptr, > + uint64_t value) > +{ > + return __sync_fetch_and_sub((odp_atomic_u32_t *)ptr, > + (uint32_t)value); > +} > +#else > +static inline uint64_t odp_atomic_fetch_sub_u64(odp_atomic_u64_t *ptr, > + uint64_t value) > +{ > + return __sync_fetch_and_sub(ptr, value); > +} > +#endif > +/** > + * Fetch and increment atomic uint64 by 1 > + * > + * @param ptr An atomic variable > + * > + * @return Value of the variable before the operation > + */ > +static inline uint64_t odp_atomic_fetch_inc_u64(odp_atomic_u64_t *ptr) > +{ > + return odp_atomic_fetch_add_u64(ptr, 1); > +} > + > +/** > + * Increment atomic uint64 by 1 > + * > + * @param ptr An atomic variable > + * > + */ > +static inline void odp_atomic_inc_u64(odp_atomic_u64_t *ptr) > +{ > + odp_atomic_fetch_add_u64(ptr, 1); > +} > + > +/** > + * Fetch and decement atomic uint64 by 1 > + * > + * @param ptr An atomic variable > + * > + * @return Value of the variable before the operation > + */ > +static inline uint64_t odp_atomic_fetch_dec_u64(odp_atomic_u64_t *ptr) > +{ > + return odp_atomic_fetch_sub_u64(ptr, 1); > +} > + > +/** > + * Deccrement atomic uint64 by 1 > + * > + * @param ptr An atomic variable > + * > + */ > +static inline void odp_atomic_dec_u64(odp_atomic_u64_t *ptr) > +{ > + odp_atomic_fetch_sub_u64(ptr, 1); > +} > + > +/** > + * Atomic compare and set for 64bit > + * > + * @param dst destination location into which the value will be written. > + * @param exp expected value. > + * @param src new value. > + * @return Non-zero on success; 0 on failure. > + */ > +static inline int > +odp_atomic_cmpset_u64(odp_atomic_u64_t *dst, uint64_t exp, uint64_t src) > +{ > + return __sync_bool_compare_and_swap(dst, exp, src); > +} > + > +#endif > -- > 1.7.9.5 > > > _______________________________________________ > lng-odp mailing list > lng-odp@lists.linaro.org > http://lists.linaro.org/mailman/listinfo/lng-odp
On 06/19/2014 04:05 PM, Anders Roxell wrote: > On 2014-06-17 20:55, Taras Kondratiuk wrote: >> Signed-off-by: Taras Kondratiuk <taras.kondratiuk@linaro.org> >> diff --git a/platform/linux-generic/include/plat/odp_atomic.h b/platform/linux-generic/include/plat/odp_atomic.h >> new file mode 100644 >> index 0000000..e70608d >> --- /dev/null >> +++ b/platform/linux-generic/include/plat/odp_atomic.h >> @@ -0,0 +1,457 @@ >> +/* Copyright (c) 2013, Linaro Limited >> + * All rights reserved. >> + * >> + * SPDX-License-Identifier: BSD-3-Clause >> + */ >> + >> + >> +/** >> + * @file >> + * >> + * ODP atomic operations >> + */ >> + >> +#ifndef ODP_ATOMIC_H_ >> +#error This file should be included only into corresponding top level header >> +#else >> + >> +/** >> + * Atomic integer >> + */ >> +typedef volatile int32_t plat_odp_atomic_int_t; >> + >> +/** >> + * Atomic unsigned integer 64 bits >> + */ >> +typedef volatile uint64_t plat_odp_atomic_u64_t; >> + >> +/** >> + * Atomic unsigned integer 32 bits >> + */ >> +typedef volatile uint32_t plat_odp_atomic_u32_t; >> + >> +/* Define OPD types here to use them in inline functions below */ > > Nit: > Define ODP types here which are use by the inline functions below Ugh. This's is not updated patch. It seems I didn't commit v2 changes for this patch when migrating the code from laptop to workstation. All odp_*_t should be replaced by plat_odp_*_t and typedefs below should be removed. >> +typedef plat_odp_atomic_int_t odp_atomic_int_t; >> +typedef plat_odp_atomic_u64_t odp_atomic_u64_t; >> +typedef plat_odp_atomic_u32_t odp_atomic_u32_t; >> + >> + >> +static inline void odp_atomic_init_int(odp_atomic_int_t *ptr) >> +{ >> + *ptr = 0; >> +}
On 19 June 2014 15:25, Taras Kondratiuk <taras.kondratiuk@linaro.org> wrote: > On 06/19/2014 04:05 PM, Anders Roxell wrote: > >> On 2014-06-17 20:55, Taras Kondratiuk wrote: >> >>> Signed-off-by: Taras Kondratiuk <taras.kondratiuk@linaro.org> >>> >>> diff --git a/platform/linux-generic/include/plat/odp_atomic.h >>> b/platform/linux-generic/include/plat/odp_atomic.h >>> new file mode 100644 >>> index 0000000..e70608d >>> --- /dev/null >>> +++ b/platform/linux-generic/include/plat/odp_atomic.h >>> @@ -0,0 +1,457 @@ >>> +/* Copyright (c) 2013, Linaro Limited >>> + * All rights reserved. >>> + * >>> + * SPDX-License-Identifier: BSD-3-Clause >>> + */ >>> + >>> + >>> +/** >>> + * @file >>> + * >>> + * ODP atomic operations >>> + */ >>> + >>> +#ifndef ODP_ATOMIC_H_ >>> +#error This file should be included only into corresponding top level >>> header >>> +#else >>> + >>> +/** >>> + * Atomic integer >>> + */ >>> +typedef volatile int32_t plat_odp_atomic_int_t; >>> + >>> +/** >>> + * Atomic unsigned integer 64 bits >>> + */ >>> +typedef volatile uint64_t plat_odp_atomic_u64_t; >>> + >>> +/** >>> + * Atomic unsigned integer 32 bits >>> + */ >>> +typedef volatile uint32_t plat_odp_atomic_u32_t; >>> + >>> +/* Define OPD types here to use them in inline functions below */ >>> >> >> Nit: >> Define ODP types here which are use by the inline functions below >> > > Ugh. This's is not updated patch. It seems I didn't commit v2 changes > for this patch when migrating the code from laptop to workstation. > > All odp_*_t should be replaced by plat_odp_*_t and typedefs below > should be removed. Ok even better =) > > > +typedef plat_odp_atomic_int_t odp_atomic_int_t; >>> +typedef plat_odp_atomic_u64_t odp_atomic_u64_t; >>> +typedef plat_odp_atomic_u32_t odp_atomic_u32_t; >>> + >>> + >>> +static inline void odp_atomic_init_int(odp_atomic_int_t *ptr) >>> +{ >>> + *ptr = 0; >>> +} >>> >> > > -- > Taras Kondratiuk >
diff --git a/include/odp_atomic.h b/include/odp_atomic.h index 5a25dc7..d33c226 100644 --- a/include/odp_atomic.h +++ b/include/odp_atomic.h @@ -20,22 +20,22 @@ extern "C" { #include <odp_std_types.h> - +#include <plat/odp_atomic.h> /** * Atomic integer */ -typedef volatile int32_t odp_atomic_int_t; +typedef plat_odp_atomic_int_t odp_atomic_int_t; /** * Atomic unsigned integer 64 bits */ -typedef volatile uint64_t odp_atomic_u64_t; +typedef plat_odp_atomic_u64_t odp_atomic_u64_t; /** * Atomic unsigned integer 32 bits */ -typedef volatile uint32_t odp_atomic_u32_t; +typedef plat_odp_atomic_u32_t odp_atomic_u32_t; /** @@ -45,10 +45,7 @@ typedef volatile uint32_t odp_atomic_u32_t; * * @note The operation is not synchoronized with other threads */ -static inline void odp_atomic_init_int(odp_atomic_int_t *ptr) -{ - *ptr = 0; -} +void odp_atomic_init_int(odp_atomic_int_t *ptr); /** * Load value of atomic integer @@ -59,10 +56,7 @@ static inline void odp_atomic_init_int(odp_atomic_int_t *ptr) * * @note The operation is not synchoronized with other threads */ -static inline int odp_atomic_load_int(odp_atomic_int_t *ptr) -{ - return *ptr; -} +int odp_atomic_load_int(odp_atomic_int_t *ptr); /** * Store value to atomic integer @@ -72,10 +66,7 @@ static inline int odp_atomic_load_int(odp_atomic_int_t *ptr) * * @note The operation is not synchoronized with other threads */ -static inline void odp_atomic_store_int(odp_atomic_int_t *ptr, int new_value) -{ - *ptr = new_value; -} +void odp_atomic_store_int(odp_atomic_int_t *ptr, int new_value); /** * Fetch and add atomic integer @@ -85,10 +76,7 @@ static inline void odp_atomic_store_int(odp_atomic_int_t *ptr, int new_value) * * @return Value of the variable before the operation */ -static inline int odp_atomic_fetch_add_int(odp_atomic_int_t *ptr, int value) -{ - return __sync_fetch_and_add(ptr, value); -} +int odp_atomic_fetch_add_int(odp_atomic_int_t *ptr, int value); /** * Fetch and substract atomic integer @@ -98,10 +86,7 @@ static inline int odp_atomic_fetch_add_int(odp_atomic_int_t *ptr, int value) * * @return Value of the variable before the operation */ -static inline int odp_atomic_fetch_sub_int(odp_atomic_int_t *ptr, int value) -{ - return __sync_fetch_and_sub(ptr, value); -} +int odp_atomic_fetch_sub_int(odp_atomic_int_t *ptr, int value); /** * Fetch and increment atomic integer by 1 @@ -110,10 +95,7 @@ static inline int odp_atomic_fetch_sub_int(odp_atomic_int_t *ptr, int value) * * @return Value of the variable before the operation */ -static inline int odp_atomic_fetch_inc_int(odp_atomic_int_t *ptr) -{ - return odp_atomic_fetch_add_int(ptr, 1); -} +int odp_atomic_fetch_inc_int(odp_atomic_int_t *ptr); /** * Increment atomic integer by 1 @@ -121,10 +103,7 @@ static inline int odp_atomic_fetch_inc_int(odp_atomic_int_t *ptr) * @param ptr An atomic variable * */ -static inline void odp_atomic_inc_int(odp_atomic_int_t *ptr) -{ - odp_atomic_fetch_add_int(ptr, 1); -} +void odp_atomic_inc_int(odp_atomic_int_t *ptr); /** * Fetch and decrement atomic integer by 1 @@ -133,10 +112,7 @@ static inline void odp_atomic_inc_int(odp_atomic_int_t *ptr) * * @return Value of the variable before the operation */ -static inline int odp_atomic_fetch_dec_int(odp_atomic_int_t *ptr) -{ - return odp_atomic_fetch_sub_int(ptr, 1); -} +int odp_atomic_fetch_dec_int(odp_atomic_int_t *ptr); /** * Decrement atomic integer by 1 @@ -144,10 +120,7 @@ static inline int odp_atomic_fetch_dec_int(odp_atomic_int_t *ptr) * @param ptr An atomic variable * */ -static inline void odp_atomic_dec_int(odp_atomic_int_t *ptr) -{ - odp_atomic_fetch_sub_int(ptr, 1); -} +void odp_atomic_dec_int(odp_atomic_int_t *ptr); /** * Initialize atomic uint32 @@ -156,10 +129,7 @@ static inline void odp_atomic_dec_int(odp_atomic_int_t *ptr) * * @note The operation is not synchoronized with other threads */ -static inline void odp_atomic_init_u32(odp_atomic_u32_t *ptr) -{ - *ptr = 0; -} +void odp_atomic_init_u32(odp_atomic_u32_t *ptr); /** * Load value of atomic uint32 @@ -170,10 +140,7 @@ static inline void odp_atomic_init_u32(odp_atomic_u32_t *ptr) * * @note The operation is not synchoronized with other threads */ -static inline uint32_t odp_atomic_load_u32(odp_atomic_u32_t *ptr) -{ - return *ptr; -} +uint32_t odp_atomic_load_u32(odp_atomic_u32_t *ptr); /** * Store value to atomic uint32 @@ -183,11 +150,7 @@ static inline uint32_t odp_atomic_load_u32(odp_atomic_u32_t *ptr) * * @note The operation is not synchoronized with other threads */ -static inline void odp_atomic_store_u32(odp_atomic_u32_t *ptr, - uint32_t new_value) -{ - *ptr = new_value; -} +void odp_atomic_store_u32(odp_atomic_u32_t *ptr, uint32_t new_value); /** * Fetch and add atomic uint32 @@ -197,11 +160,7 @@ static inline void odp_atomic_store_u32(odp_atomic_u32_t *ptr, * * @return Value of the variable before the operation */ -static inline uint32_t odp_atomic_fetch_add_u32(odp_atomic_u32_t *ptr, - uint32_t value) -{ - return __sync_fetch_and_add(ptr, value); -} +uint32_t odp_atomic_fetch_add_u32(odp_atomic_u32_t *ptr, uint32_t value); /** * Fetch and substract uint32 @@ -211,11 +170,7 @@ static inline uint32_t odp_atomic_fetch_add_u32(odp_atomic_u32_t *ptr, * * @return Value of the variable before the operation */ -static inline uint32_t odp_atomic_fetch_sub_u32(odp_atomic_u32_t *ptr, - uint32_t value) -{ - return __sync_fetch_and_sub(ptr, value); -} +uint32_t odp_atomic_fetch_sub_u32(odp_atomic_u32_t *ptr, uint32_t value); /** * Fetch and increment atomic uint32 by 1 @@ -224,27 +179,7 @@ static inline uint32_t odp_atomic_fetch_sub_u32(odp_atomic_u32_t *ptr, * * @return Value of the variable before the operation */ -#if defined __OCTEON__ - -static inline uint32_t odp_atomic_fetch_inc_u32(odp_atomic_u32_t *ptr) -{ - uint32_t ret; - - __asm__ __volatile__ ("syncws"); - __asm__ __volatile__ ("lai %0,(%2)" : "=r" (ret), "+m" (ptr) : - "r" (ptr)); - - return ret; -} - -#else - -static inline uint32_t odp_atomic_fetch_inc_u32(odp_atomic_u32_t *ptr) -{ - return odp_atomic_fetch_add_u32(ptr, 1); -} - -#endif +uint32_t odp_atomic_fetch_inc_u32(odp_atomic_u32_t *ptr); /** * Increment atomic uint32 by 1 @@ -252,10 +187,7 @@ static inline uint32_t odp_atomic_fetch_inc_u32(odp_atomic_u32_t *ptr) * @param ptr An atomic variable * */ -static inline void odp_atomic_inc_u32(odp_atomic_u32_t *ptr) -{ - odp_atomic_fetch_add_u32(ptr, 1); -} +void odp_atomic_inc_u32(odp_atomic_u32_t *ptr); /** * Fetch and decrement uint32 by 1 @@ -264,10 +196,7 @@ static inline void odp_atomic_inc_u32(odp_atomic_u32_t *ptr) * * @return Value of the variable before the operation */ -static inline uint32_t odp_atomic_fetch_dec_u32(odp_atomic_u32_t *ptr) -{ - return odp_atomic_fetch_sub_u32(ptr, 1); -} +uint32_t odp_atomic_fetch_dec_u32(odp_atomic_u32_t *ptr); /** * Decrement atomic uint32 by 1 @@ -275,10 +204,7 @@ static inline uint32_t odp_atomic_fetch_dec_u32(odp_atomic_u32_t *ptr) * @param ptr An atomic variable * */ -static inline void odp_atomic_dec_u32(odp_atomic_u32_t *ptr) -{ - odp_atomic_fetch_sub_u32(ptr, 1); -} +void odp_atomic_dec_u32(odp_atomic_u32_t *ptr); /** * Atomic compare and set for 32bit @@ -288,11 +214,7 @@ static inline void odp_atomic_dec_u32(odp_atomic_u32_t *ptr) * @param src new value. * @return Non-zero on success; 0 on failure. */ -static inline int -odp_atomic_cmpset_u32(odp_atomic_u32_t *dst, uint32_t exp, uint32_t src) -{ - return __sync_bool_compare_and_swap(dst, exp, src); -} +int odp_atomic_cmpset_u32(odp_atomic_u32_t *dst, uint32_t exp, uint32_t src); /** * Initialize atomic uint64 @@ -301,10 +223,7 @@ odp_atomic_cmpset_u32(odp_atomic_u32_t *dst, uint32_t exp, uint32_t src) * * @note The operation is not synchoronized with other threads */ -static inline void odp_atomic_init_u64(odp_atomic_u64_t *ptr) -{ - *ptr = 0; -} +void odp_atomic_init_u64(odp_atomic_u64_t *ptr); /** * Load value of atomic uint64 @@ -315,10 +234,7 @@ static inline void odp_atomic_init_u64(odp_atomic_u64_t *ptr) * * @note The operation is not synchoronized with other threads */ -static inline uint64_t odp_atomic_load_u64(odp_atomic_u64_t *ptr) -{ - return *ptr; -} +uint64_t odp_atomic_load_u64(odp_atomic_u64_t *ptr); /** * Store value to atomic uint64 @@ -328,11 +244,7 @@ static inline uint64_t odp_atomic_load_u64(odp_atomic_u64_t *ptr) * * @note The operation is not synchoronized with other threads */ -static inline void odp_atomic_store_u64(odp_atomic_u64_t *ptr, - uint64_t new_value) -{ - *ptr = new_value; -} +void odp_atomic_store_u64(odp_atomic_u64_t *ptr, uint64_t new_value); /** * Add atomic uint64 @@ -341,10 +253,7 @@ static inline void odp_atomic_store_u64(odp_atomic_u64_t *ptr, * @param value A value to be added to the variable * */ -static inline void odp_atomic_add_u64(odp_atomic_u64_t *ptr, uint64_t value) -{ - __sync_fetch_and_add(ptr, value); -} +void odp_atomic_add_u64(odp_atomic_u64_t *ptr, uint64_t value); /** * Fetch and add atomic uint64 @@ -354,21 +263,8 @@ static inline void odp_atomic_add_u64(odp_atomic_u64_t *ptr, uint64_t value) * * @return Value of the variable before the operation */ +uint64_t odp_atomic_fetch_add_u64(odp_atomic_u64_t *ptr, uint64_t value); -#if defined __powerpc__ && !defined __powerpc64__ -static inline uint64_t odp_atomic_fetch_add_u64(odp_atomic_u64_t *ptr, - uint64_t value) -{ - return __sync_fetch_and_add((odp_atomic_u32_t *)ptr, - (uint32_t)value); -} -#else -static inline uint64_t odp_atomic_fetch_add_u64(odp_atomic_u64_t *ptr, - uint64_t value) -{ - return __sync_fetch_and_add(ptr, value); -} -#endif /** * Subtract atomic uint64 * @@ -376,10 +272,7 @@ static inline uint64_t odp_atomic_fetch_add_u64(odp_atomic_u64_t *ptr, * @param value A value to be subtracted from the variable * */ -static inline void odp_atomic_sub_u64(odp_atomic_u64_t *ptr, uint64_t value) -{ - __sync_fetch_and_sub(ptr, value); -} +void odp_atomic_sub_u64(odp_atomic_u64_t *ptr, uint64_t value); /** * Fetch and subtract atomic uint64 @@ -389,20 +282,8 @@ static inline void odp_atomic_sub_u64(odp_atomic_u64_t *ptr, uint64_t value) * * @return Value of the variable before the operation */ -#if defined __powerpc__ && !defined __powerpc64__ -static inline uint64_t odp_atomic_fetch_sub_u64(odp_atomic_u64_t *ptr, - uint64_t value) -{ - return __sync_fetch_and_sub((odp_atomic_u32_t *)ptr, - (uint32_t)value); -} -#else -static inline uint64_t odp_atomic_fetch_sub_u64(odp_atomic_u64_t *ptr, - uint64_t value) -{ - return __sync_fetch_and_sub(ptr, value); -} -#endif +uint64_t odp_atomic_fetch_sub_u64(odp_atomic_u64_t *ptr, uint64_t value); + /** * Fetch and increment atomic uint64 by 1 * @@ -410,10 +291,7 @@ static inline uint64_t odp_atomic_fetch_sub_u64(odp_atomic_u64_t *ptr, * * @return Value of the variable before the operation */ -static inline uint64_t odp_atomic_fetch_inc_u64(odp_atomic_u64_t *ptr) -{ - return odp_atomic_fetch_add_u64(ptr, 1); -} +uint64_t odp_atomic_fetch_inc_u64(odp_atomic_u64_t *ptr); /** * Increment atomic uint64 by 1 @@ -421,10 +299,7 @@ static inline uint64_t odp_atomic_fetch_inc_u64(odp_atomic_u64_t *ptr) * @param ptr An atomic variable * */ -static inline void odp_atomic_inc_u64(odp_atomic_u64_t *ptr) -{ - odp_atomic_fetch_add_u64(ptr, 1); -} +void odp_atomic_inc_u64(odp_atomic_u64_t *ptr); /** * Fetch and decement atomic uint64 by 1 @@ -433,10 +308,7 @@ static inline void odp_atomic_inc_u64(odp_atomic_u64_t *ptr) * * @return Value of the variable before the operation */ -static inline uint64_t odp_atomic_fetch_dec_u64(odp_atomic_u64_t *ptr) -{ - return odp_atomic_fetch_sub_u64(ptr, 1); -} +uint64_t odp_atomic_fetch_dec_u64(odp_atomic_u64_t *ptr); /** * Deccrement atomic uint64 by 1 @@ -444,10 +316,7 @@ static inline uint64_t odp_atomic_fetch_dec_u64(odp_atomic_u64_t *ptr) * @param ptr An atomic variable * */ -static inline void odp_atomic_dec_u64(odp_atomic_u64_t *ptr) -{ - odp_atomic_fetch_sub_u64(ptr, 1); -} +void odp_atomic_dec_u64(odp_atomic_u64_t *ptr); /** * Atomic compare and set for 64bit @@ -457,11 +326,7 @@ static inline void odp_atomic_dec_u64(odp_atomic_u64_t *ptr) * @param src new value. * @return Non-zero on success; 0 on failure. */ -static inline int -odp_atomic_cmpset_u64(odp_atomic_u64_t *dst, uint64_t exp, uint64_t src) -{ - return __sync_bool_compare_and_swap(dst, exp, src); -} +int odp_atomic_cmpset_u64(odp_atomic_u64_t *dst, uint64_t exp, uint64_t src); #ifdef __cplusplus } diff --git a/platform/linux-generic/include/plat/odp_atomic.h b/platform/linux-generic/include/plat/odp_atomic.h new file mode 100644 index 0000000..e70608d --- /dev/null +++ b/platform/linux-generic/include/plat/odp_atomic.h @@ -0,0 +1,457 @@ +/* Copyright (c) 2013, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + + +/** + * @file + * + * ODP atomic operations + */ + +#ifndef ODP_ATOMIC_H_ +#error This file should be included only into corresponding top level header +#else + +/** + * Atomic integer + */ +typedef volatile int32_t plat_odp_atomic_int_t; + +/** + * Atomic unsigned integer 64 bits + */ +typedef volatile uint64_t plat_odp_atomic_u64_t; + +/** + * Atomic unsigned integer 32 bits + */ +typedef volatile uint32_t plat_odp_atomic_u32_t; + +/* Define OPD types here to use them in inline functions below */ +typedef plat_odp_atomic_int_t odp_atomic_int_t; +typedef plat_odp_atomic_u64_t odp_atomic_u64_t; +typedef plat_odp_atomic_u32_t odp_atomic_u32_t; + + +static inline void odp_atomic_init_int(odp_atomic_int_t *ptr) +{ + *ptr = 0; +} + +/** + * Load value of atomic integer + * + * @param ptr An atomic variable + * + * @return atomic integer value + * + * @note The operation is not synchoronized with other threads + */ +static inline int odp_atomic_load_int(odp_atomic_int_t *ptr) +{ + return *ptr; +} + +/** + * Store value to atomic integer + * + * @param ptr An atomic variable + * @param new_value Store new_value to a variable + * + * @note The operation is not synchoronized with other threads + */ +static inline void odp_atomic_store_int(odp_atomic_int_t *ptr, int new_value) +{ + *ptr = new_value; +} + +/** + * Fetch and add atomic integer + * + * @param ptr An atomic variable + * @param value A value to be added to the variable + * + * @return Value of the variable before the operation + */ +static inline int odp_atomic_fetch_add_int(odp_atomic_int_t *ptr, int value) +{ + return __sync_fetch_and_add(ptr, value); +} + +/** + * Fetch and substract atomic integer + * + * @param ptr An atomic int variable + * @param value A value to be subtracted from the variable + * + * @return Value of the variable before the operation + */ +static inline int odp_atomic_fetch_sub_int(odp_atomic_int_t *ptr, int value) +{ + return __sync_fetch_and_sub(ptr, value); +} + +/** + * Fetch and increment atomic integer by 1 + * + * @param ptr An atomic variable + * + * @return Value of the variable before the operation + */ +static inline int odp_atomic_fetch_inc_int(odp_atomic_int_t *ptr) +{ + return odp_atomic_fetch_add_int(ptr, 1); +} + +/** + * Increment atomic integer by 1 + * + * @param ptr An atomic variable + * + */ +static inline void odp_atomic_inc_int(odp_atomic_int_t *ptr) +{ + odp_atomic_fetch_add_int(ptr, 1); +} + +/** + * Fetch and decrement atomic integer by 1 + * + * @param ptr An atomic int variable + * + * @return Value of the variable before the operation + */ +static inline int odp_atomic_fetch_dec_int(odp_atomic_int_t *ptr) +{ + return odp_atomic_fetch_sub_int(ptr, 1); +} + +/** + * Decrement atomic integer by 1 + * + * @param ptr An atomic variable + * + */ +static inline void odp_atomic_dec_int(odp_atomic_int_t *ptr) +{ + odp_atomic_fetch_sub_int(ptr, 1); +} + +/** + * Initialize atomic uint32 + * + * @param ptr An atomic variable + * + * @note The operation is not synchoronized with other threads + */ +static inline void odp_atomic_init_u32(odp_atomic_u32_t *ptr) +{ + *ptr = 0; +} + +/** + * Load value of atomic uint32 + * + * @param ptr An atomic variable + * + * @return atomic uint32 value + * + * @note The operation is not synchoronized with other threads + */ +static inline uint32_t odp_atomic_load_u32(odp_atomic_u32_t *ptr) +{ + return *ptr; +} + +/** + * Store value to atomic uint32 + * + * @param ptr An atomic variable + * @param new_value Store new_value to a variable + * + * @note The operation is not synchoronized with other threads + */ +static inline void odp_atomic_store_u32(odp_atomic_u32_t *ptr, + uint32_t new_value) +{ + *ptr = new_value; +} + +/** + * Fetch and add atomic uint32 + * + * @param ptr An atomic variable + * @param value A value to be added to the variable + * + * @return Value of the variable before the operation + */ +static inline uint32_t odp_atomic_fetch_add_u32(odp_atomic_u32_t *ptr, + uint32_t value) +{ + return __sync_fetch_and_add(ptr, value); +} + +/** + * Fetch and substract uint32 + * + * @param ptr An atomic variable + * @param value A value to be sub to the variable + * + * @return Value of the variable before the operation + */ +static inline uint32_t odp_atomic_fetch_sub_u32(odp_atomic_u32_t *ptr, + uint32_t value) +{ + return __sync_fetch_and_sub(ptr, value); +} + +/** + * Fetch and increment atomic uint32 by 1 + * + * @param ptr An atomic variable + * + * @return Value of the variable before the operation + */ +#if defined __OCTEON__ + +static inline uint32_t odp_atomic_fetch_inc_u32(odp_atomic_u32_t *ptr) +{ + uint32_t ret; + + __asm__ __volatile__ ("syncws"); + __asm__ __volatile__ ("lai %0,(%2)" : "=r" (ret), "+m" (ptr) : + "r" (ptr)); + + return ret; +} + +#else + +static inline uint32_t odp_atomic_fetch_inc_u32(odp_atomic_u32_t *ptr) +{ + return odp_atomic_fetch_add_u32(ptr, 1); +} + +#endif + +/** + * Increment atomic uint32 by 1 + * + * @param ptr An atomic variable + * + */ +static inline void odp_atomic_inc_u32(odp_atomic_u32_t *ptr) +{ + odp_atomic_fetch_add_u32(ptr, 1); +} + +/** + * Fetch and decrement uint32 by 1 + * + * @param ptr An atomic variable + * + * @return Value of the variable before the operation + */ +static inline uint32_t odp_atomic_fetch_dec_u32(odp_atomic_u32_t *ptr) +{ + return odp_atomic_fetch_sub_u32(ptr, 1); +} + +/** + * Decrement atomic uint32 by 1 + * + * @param ptr An atomic variable + * + */ +static inline void odp_atomic_dec_u32(odp_atomic_u32_t *ptr) +{ + odp_atomic_fetch_sub_u32(ptr, 1); +} + +/** + * Atomic compare and set for 32bit + * + * @param dst destination location into which the value will be written. + * @param exp expected value. + * @param src new value. + * @return Non-zero on success; 0 on failure. + */ +static inline int +odp_atomic_cmpset_u32(odp_atomic_u32_t *dst, uint32_t exp, uint32_t src) +{ + return __sync_bool_compare_and_swap(dst, exp, src); +} + +/** + * Initialize atomic uint64 + * + * @param ptr An atomic variable + * + * @note The operation is not synchoronized with other threads + */ +static inline void odp_atomic_init_u64(odp_atomic_u64_t *ptr) +{ + *ptr = 0; +} + +/** + * Load value of atomic uint64 + * + * @param ptr An atomic variable + * + * @return atomic uint64 value + * + * @note The operation is not synchoronized with other threads + */ +static inline uint64_t odp_atomic_load_u64(odp_atomic_u64_t *ptr) +{ + return *ptr; +} + +/** + * Store value to atomic uint64 + * + * @param ptr An atomic variable + * @param new_value Store new_value to a variable + * + * @note The operation is not synchoronized with other threads + */ +static inline void odp_atomic_store_u64(odp_atomic_u64_t *ptr, + uint64_t new_value) +{ + *ptr = new_value; +} + +/** + * Add atomic uint64 + * + * @param ptr An atomic variable + * @param value A value to be added to the variable + * + */ +static inline void odp_atomic_add_u64(odp_atomic_u64_t *ptr, uint64_t value) +{ + __sync_fetch_and_add(ptr, value); +} + +/** + * Fetch and add atomic uint64 + * + * @param ptr An atomic variable + * @param value A value to be added to the variable + * + * @return Value of the variable before the operation + */ + +#if defined __powerpc__ && !defined __powerpc64__ +static inline uint64_t odp_atomic_fetch_add_u64(odp_atomic_u64_t *ptr, + uint64_t value) +{ + return __sync_fetch_and_add((odp_atomic_u32_t *)ptr, + (uint32_t)value); +} +#else +static inline uint64_t odp_atomic_fetch_add_u64(odp_atomic_u64_t *ptr, + uint64_t value) +{ + return __sync_fetch_and_add(ptr, value); +} +#endif +/** + * Subtract atomic uint64 + * + * @param ptr An atomic variable + * @param value A value to be subtracted from the variable + * + */ +static inline void odp_atomic_sub_u64(odp_atomic_u64_t *ptr, uint64_t value) +{ + __sync_fetch_and_sub(ptr, value); +} + +/** + * Fetch and subtract atomic uint64 + * + * @param ptr An atomic variable + * @param value A value to be subtracted from the variable + * + * @return Value of the variable before the operation + */ +#if defined __powerpc__ && !defined __powerpc64__ +static inline uint64_t odp_atomic_fetch_sub_u64(odp_atomic_u64_t *ptr, + uint64_t value) +{ + return __sync_fetch_and_sub((odp_atomic_u32_t *)ptr, + (uint32_t)value); +} +#else +static inline uint64_t odp_atomic_fetch_sub_u64(odp_atomic_u64_t *ptr, + uint64_t value) +{ + return __sync_fetch_and_sub(ptr, value); +} +#endif +/** + * Fetch and increment atomic uint64 by 1 + * + * @param ptr An atomic variable + * + * @return Value of the variable before the operation + */ +static inline uint64_t odp_atomic_fetch_inc_u64(odp_atomic_u64_t *ptr) +{ + return odp_atomic_fetch_add_u64(ptr, 1); +} + +/** + * Increment atomic uint64 by 1 + * + * @param ptr An atomic variable + * + */ +static inline void odp_atomic_inc_u64(odp_atomic_u64_t *ptr) +{ + odp_atomic_fetch_add_u64(ptr, 1); +} + +/** + * Fetch and decement atomic uint64 by 1 + * + * @param ptr An atomic variable + * + * @return Value of the variable before the operation + */ +static inline uint64_t odp_atomic_fetch_dec_u64(odp_atomic_u64_t *ptr) +{ + return odp_atomic_fetch_sub_u64(ptr, 1); +} + +/** + * Deccrement atomic uint64 by 1 + * + * @param ptr An atomic variable + * + */ +static inline void odp_atomic_dec_u64(odp_atomic_u64_t *ptr) +{ + odp_atomic_fetch_sub_u64(ptr, 1); +} + +/** + * Atomic compare and set for 64bit + * + * @param dst destination location into which the value will be written. + * @param exp expected value. + * @param src new value. + * @return Non-zero on success; 0 on failure. + */ +static inline int +odp_atomic_cmpset_u64(odp_atomic_u64_t *dst, uint64_t exp, uint64_t src) +{ + return __sync_bool_compare_and_swap(dst, exp, src); +} + +#endif
Signed-off-by: Taras Kondratiuk <taras.kondratiuk@linaro.org> --- include/odp_atomic.h | 207 ++-------- platform/linux-generic/include/plat/odp_atomic.h | 457 ++++++++++++++++++++++ 2 files changed, 493 insertions(+), 171 deletions(-) create mode 100644 platform/linux-generic/include/plat/odp_atomic.h