| /* |
| * Copyright © 2012 Linux Box Corporation |
| * |
| * This program is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public License |
| * as published by the Free Software Foundation; either version 3 of |
| * the License, or (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, but |
| * WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
| * 02110-1301 USA |
| * |
| * --------------------------------------- |
| */ |
| |
| /** |
| * @file abstract_atomic.h |
| * @author Adam C. Emerson <aemerson@linuxbox.com> |
| * @author Frank S. Filz <ffilz@us.ibm.com> |
| * @brief Shim for compiler or library supplied atomic operations |
| * |
| * This file provides inline functions that provide atomic operations |
| * appropriate to the compiler being used. (Someone can add support |
| * for an appropriate library later on.) |
| * |
| * The types functions are provided for are: |
| * |
| * ptrdiff_t (fetch and store only) |
| * time_t (fetch and store only) |
| * void* (fetch and store only) |
| * uintptr_t (fetch and store only) |
| * int64_t |
| * uint64_t |
| * int32_t |
| * uint21_t |
| * int16_t |
| * uint16_t |
| * int8_t |
| * uint8_t |
| * size_t |
| * |
| * The functions provided are (using int64_t for example): |
| * |
| * int64_t atomic_add_int64_t(int64_t *augend, int64_t addend) |
| * int64_t atomic_inc_int64_t(int64_t *var) |
| * int64_t atomic_sub_int64_t(int64_t *minuend, int64_t subtrahend) |
| * int64_t atomic_dec_int64_t(int64_t *var) |
| * int64_t atomic_postadd_int64_t(int64_t *augend, int64_t addend) |
| * int64_t atomic_postinc_int64_t(int64_t *var) |
| * int64_t atomic_postsub_int64_t(int64_t *minuend, int64_t subtrahend) |
| * int64_t atomic_postdec_int64_t(int64_t *var) |
| * int64_t atomic_fetch_int64_t(int64_t *var) |
| * void atomic_store_int64_t(int64_t *var, int64_t val) |
| * |
| * The following bit mask operations are provided for |
| * uint64_t, uint32_t, uint_16t, and uint8_t: |
| * |
| * uint64_t atomic_clear_uint64_t_bits(uint64_t *var, uint64_t bits) |
| * uint64_t atomic_set_uint64_t_bits(uint64_t *var, uint64_t bits) |
| * uint64_t atomic_postclear_uint64_t_bits(uint64_t *var, |
| * uint64_t atomic_postset_uint64_t_bits(uint64_t *var, |
| * |
| */ |
| |
| #ifndef _ABSTRACT_ATOMIC_H |
| #define _ABSTRACT_ATOMIC_H |
| #include <stddef.h> |
| #include <stdint.h> |
| #include <time.h> |
| |
| #undef GCC_SYNC_FUNCTIONS |
| #undef GCC_ATOMIC_FUNCTIONS |
| |
| #ifndef __GNUC__ |
| #error Please edit abstract_atomic.h and implement support for \ |
| non-GNU compilers. |
| #else /* __GNUC__ */ |
| #define ATOMIC_GCC_VERSION (__GNUC__ * 10000 \ |
| + __GNUC_MINOR__ * 100 \ |
| + __GNUC_PATCHLEVEL__) |
| |
| #if ((ATOMIC_GCC_VERSION) >= 40700) |
| #define GCC_ATOMIC_FUNCTIONS 1 |
| #elif defined(__APPLE__) && defined(__x86_64__) |
| #include "atomic_x86_64.h" |
| #elif ((ATOMIC_GCC_VERSION) >= 40100) |
| #define GCC_SYNC_FUNCTIONS 1 |
| #else |
| #error This verison of GCC does not support atomics. |
| #endif /* Version check */ |
| #endif /* __GNUC__ */ |
| |
| /* |
| * Preaddition, presubtraction, preincrement, predecrement (return the |
| * value after the operation, by analogy with the ++n preincrement |
| * operator.) |
| */ |
| |
| /** |
| * @brief Atomically add to an int64_t |
| * |
| * This function atomically adds to the supplied value. |
| * |
| * @param[in,out] augend Number to be added to |
| * @param[in] addend Number to add |
| * |
| * @return The value after addition. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline int64_t atomic_add_int64_t(int64_t *augend, int64_t addend) |
| { |
| return __atomic_add_fetch(augend, addend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline int64_t atomic_add_int64_t(int64_t *augend, int64_t addend) |
| { |
| return __sync_add_and_fetch(augend, addend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically increment an int64_t |
| * |
| * This function atomically adds 1 to the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value after increment. |
| */ |
| |
| static inline int64_t atomic_inc_int64_t(int64_t *var) |
| { |
| return atomic_add_int64_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically subtract from an int64_t |
| * |
| * This function atomically subtracts from the supplied value. |
| * |
| * @param[in,out] minuend Number to be subtracted from |
| * @param[in] subtrahend Number to subtract |
| * |
| * @return The value after subtraction. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline int64_t atomic_sub_int64_t(int64_t *minuend, int64_t subtrahend) |
| { |
| return __atomic_sub_fetch(minuend, subtrahend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline int64_t atomic_sub_int64_t(int64_t *minuend, int64_t subtrahend) |
| { |
| return __sync_sub_and_fetch(minuend, subtrahend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically decrement an int64_t |
| * |
| * This function atomically subtracts 1 from the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| */ |
| |
| static inline int64_t atomic_dec_int64_t(int64_t *var) |
| { |
| return atomic_sub_int64_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically add to an int64_t |
| * |
| * This function atomically adds to the supplied value. |
| * |
| * @param[in,out] augend Number to be added to |
| * @param[in] addend Number to add |
| * |
| * @return The value after addition. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint64_t atomic_add_uint64_t(uint64_t *augend, uint64_t addend) |
| { |
| return __atomic_add_fetch(augend, addend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint64_t atomic_add_uint64_t(uint64_t *augend, uint64_t addend) |
| { |
| return __sync_add_and_fetch(augend, addend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically increment a uint64_t |
| * |
| * This function atomically adds 1 to the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value after increment. |
| */ |
| |
| static inline uint64_t atomic_inc_uint64_t(uint64_t *var) |
| { |
| return atomic_add_uint64_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically subtract from a uint64_t |
| * |
| * This function atomically subtracts from the supplied value. |
| * |
| * @param[in,out] minuend Number to be subtracted from |
| * @param[in] subtrahend Number to subtract |
| * |
| * @return The value after subtraction. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint64_t atomic_sub_uint64_t(uint64_t *minuend, |
| uint64_t subtrahend) |
| { |
| return __atomic_sub_fetch(minuend, subtrahend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint64_t atomic_sub_uint64_t(uint64_t *minuend, |
| uint64_t subtrahend) |
| { |
| return __sync_sub_and_fetch(minuend, subtrahend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically decrement a uint64_t |
| * |
| * This function atomically subtracts 1 from the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value after decrement. |
| */ |
| |
| static inline uint64_t atomic_dec_uint64_t(uint64_t *var) |
| { |
| return atomic_sub_uint64_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically add to an int32_t |
| * |
| * This function atomically adds to the supplied value. |
| * |
| * @param[in,out] augend Number to be added to |
| * @param[in] addend Number to add |
| * |
| * @return The value after addition. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline int32_t atomic_add_int32_t(int32_t *augend, int32_t addend) |
| { |
| return __atomic_add_fetch(augend, addend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline int32_t atomic_add_int32_t(int32_t *augend, int32_t addend) |
| { |
| return __sync_add_and_fetch(augend, addend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically increment an int32_t |
| * |
| * This function atomically adds 1 to the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value after increment. |
| */ |
| |
| static inline int32_t atomic_inc_int32_t(int32_t *var) |
| { |
| return atomic_add_int32_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically subtract from an int32_t |
| * |
| * This function atomically subtracts from the supplied value. |
| * |
| * @param[in,out] minuend Number to be subtracted from |
| * @param[in] subtrahend Number to subtract |
| * |
| * @return The value after subtraction. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline int32_t atomic_sub_int32_t(int32_t *minuend, int32_t subtrahend) |
| { |
| return __atomic_sub_fetch(minuend, subtrahend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline int32_t atomic_sub_int32_t(int32_t *minuend, int32_t subtrahend) |
| { |
| return __sync_sub_and_fetch(minuend, subtrahend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically decrement an int32_t |
| * |
| * This function atomically subtracts 1 from the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value after decrement. |
| */ |
| |
| static inline int32_t atomic_dec_int32_t(int32_t *var) |
| { |
| return atomic_sub_int32_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically add to a uint32_t |
| * |
| * This function atomically adds to the supplied value. |
| * |
| * @param[in,out] augend Number to be added to |
| * @param[in] addend Number to add |
| * |
| * @return The value after addition. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint32_t atomic_add_uint32_t(uint32_t *augend, uint32_t addend) |
| { |
| return __atomic_add_fetch(augend, addend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint32_t atomic_add_uint32_t(uint32_t *augend, uint32_t addend) |
| { |
| return __sync_add_and_fetch(augend, addend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically increment a uint32_t |
| * |
| * This function atomically adds 1 to the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value after increment. |
| */ |
| |
| static inline uint32_t atomic_inc_uint32_t(uint32_t *var) |
| { |
| return atomic_add_uint32_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically subtract from a uint32_t |
| * |
| * This function atomically subtracts from the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value after subtraction. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint32_t atomic_sub_uint32_t(uint32_t *var, uint32_t sub) |
| { |
| return __atomic_sub_fetch(var, sub, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint32_t atomic_sub_uint32_t(uint32_t *var, uint32_t sub) |
| { |
| return __sync_sub_and_fetch(var, sub); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically decrement a uint32_t |
| * |
| * This function atomically subtracts 1 from the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value after decrement. |
| */ |
| |
| static inline uint32_t atomic_dec_uint32_t(uint32_t *var) |
| { |
| return atomic_sub_uint32_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically add to an int16_t |
| * |
| * This function atomically adds to the supplied value. |
| * |
| * @param[in,out] augend Number to be added to |
| * @param[in] addend Number to add |
| * |
| * @return The value after addition. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline int16_t atomic_add_int16_t(int16_t *augend, int16_t addend) |
| { |
| return __atomic_add_fetch(augend, addend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline int16_t atomic_add_int16_t(int16_t *augend, int16_t addend) |
| { |
| return __sync_add_and_fetch(augend, addend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically increment an int16_t |
| * |
| * This function atomically adds 1 to the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value after increment. |
| */ |
| |
| static inline int16_t atomic_inc_int16_t(int16_t *var) |
| { |
| return atomic_add_int16_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically subtract from an int16_t |
| * |
| * This function atomically subtracts from the supplied value. |
| * |
| * @param[in,out] minuend Number to be subtracted from |
| * @param[in] subtrahend Number to subtract |
| * |
| * @return The value after subtraction. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline int16_t atomic_sub_int16_t(int16_t *minuend, int16_t subtrahend) |
| { |
| return __atomic_sub_fetch(minuend, subtrahend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline int16_t atomic_sub_int16_t(int16_t *minuend, int16_t subtrahend) |
| { |
| return __sync_sub_and_fetch(minuend, subtrahend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically decrement an int16_t |
| * |
| * This function atomically subtracts 1 from the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value after decrement. |
| */ |
| |
| static inline int16_t atomic_dec_int16_t(int16_t *var) |
| { |
| return atomic_sub_int16_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically add to a uint16_t |
| * |
| * This function atomically adds to the supplied value. |
| * |
| * @param[in,out] augend Number to be added to |
| * @param[in] addend Number to add |
| * |
| * @return The value after addition. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint16_t atomic_add_uint16_t(uint16_t *augend, uint16_t addend) |
| { |
| return __atomic_add_fetch(augend, addend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint16_t atomic_add_uint16_t(uint16_t *augend, uint16_t addend) |
| { |
| return __sync_add_and_fetch(augend, addend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically increment a uint16_t |
| * |
| * This function atomically adds 1 to the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value after increment. |
| */ |
| |
| static inline uint16_t atomic_inc_uint16_t(uint16_t *var) |
| { |
| return atomic_add_uint16_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically subtract from a uint16_t |
| * |
| * This function atomically subtracts from the supplied value. |
| * |
| * @param[in,out] minuend Number to be subtracted from |
| * @param[in] subtrahend Number to subtract |
| * |
| * @return The value after subtraction. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint16_t atomic_sub_uint16_t(uint16_t *minuend, |
| uint16_t subtrahend) |
| { |
| return __atomic_sub_fetch(minuend, subtrahend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint16_t atomic_sub_uint16_t(uint16_t *minuend, |
| uint16_t subtrahend) |
| { |
| return __sync_sub_and_fetch(minuend, subtrahend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically decrement a uint16_t |
| * |
| * This function atomically subtracts 1 from the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value after decrement. |
| */ |
| |
| static inline uint16_t atomic_dec_uint16_t(uint16_t *var) |
| { |
| return atomic_sub_uint16_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically add to an int8_t |
| * |
| * This function atomically adds to the supplied value. |
| * |
| * @param[in,out] augend Number to be added to |
| * @param[in] addend Number to add |
| * |
| * @return The value after addition. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline int8_t atomic_add_int8_t(int8_t *augend, int8_t addend) |
| { |
| return __atomic_add_fetch(augend, addend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline int8_t atomic_add_int8_t(int8_t *augend, int8_t addend) |
| { |
| return __sync_add_and_fetch(augend, addend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically increment an int8_t |
| * |
| * This function atomically adds 1 to the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value after increment. |
| */ |
| |
| static inline int8_t atomic_inc_int8_t(int8_t *var) |
| { |
| return atomic_add_int8_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically subtract from an int8_t |
| * |
| * This function atomically subtracts from the supplied value. |
| * |
| * @param[in,out] minuend Number to be subtracted from |
| * @param[in] subtrahend Number to subtract |
| * |
| * @return The value after subtraction. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline int8_t atomic_sub_int8_t(int8_t *minuend, int8_t subtrahend) |
| { |
| return __atomic_sub_fetch(minuend, subtrahend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline int8_t atomic_sub_int8_t(int8_t *minuend, int8_t subtrahend) |
| { |
| return __sync_sub_and_fetch(minuend, subtrahend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically decrement an int8_t |
| * |
| * This function atomically subtracts 1 from the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value after decrement. |
| */ |
| |
| static inline int8_t atomic_dec_int8_t(int8_t *var) |
| { |
| return atomic_sub_int8_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically add to a uint8_t |
| * |
| * This function atomically adds to the supplied value. |
| * |
| * @param[in,out] augend Number to be added to |
| * @param[in] addend Number to add |
| * |
| * @return The value after addition. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint8_t atomic_add_uint8_t(uint8_t *augend, int8_t addend) |
| { |
| return __atomic_add_fetch(augend, addend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint8_t atomic_add_uint8_t(uint8_t *augend, int8_t addend) |
| { |
| return __sync_add_and_fetch(augend, addend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically increment a uint8_t |
| * |
| * This function atomically adds 1 to the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value after increment. |
| */ |
| |
| static inline uint8_t atomic_inc_uint8_t(uint8_t *var) |
| { |
| return atomic_add_uint8_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically subtract from a uint8_t |
| * |
| * This function atomically subtracts from the supplied value. |
| * |
| * @param[in,out] minuend Number to be subtracted from |
| * @param[in] subtrahend Number to subtract |
| * |
| * @return The value after subtraction. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint8_t atomic_sub_uint8_t(uint8_t *minuend, uint8_t subtrahend) |
| { |
| return __atomic_sub_fetch(minuend, subtrahend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint8_t atomic_sub_uint8_t(uint8_t *minuend, uint8_t subtrahend) |
| { |
| return __sync_sub_and_fetch(minuend, subtrahend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically decrement a uint8_t |
| * |
| * This function atomically subtracts 1 from the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value after decrement. |
| */ |
| |
| static inline uint8_t atomic_dec_uint8_t(uint8_t *var) |
| { |
| return atomic_sub_uint8_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically add to a size_t |
| * |
| * This function atomically adds to the supplied value. |
| * |
| * @param[in,out] augend Number to be added to |
| * @param[in] addend Number to add |
| * |
| * @return The value after addition. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline size_t atomic_add_size_t(size_t *augend, size_t addend) |
| { |
| return __atomic_add_fetch(augend, addend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline size_t atomic_add_size_t(size_t *augend, size_t addend) |
| { |
| return __sync_add_and_fetch(augend, addend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically increment a size_t |
| * |
| * This function atomically adds 1 to the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value after increment. |
| */ |
| |
| static inline size_t atomic_inc_size_t(size_t *var) |
| { |
| return atomic_add_size_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically subtract from a size_t |
| * |
| * This function atomically subtracts from the supplied value. |
| * |
| * @param[in,out] minuend Number to be subtracted from |
| * @param[in] subtrahend Number to subtract |
| * |
| * @return The value after subtraction. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline size_t atomic_sub_size_t(size_t *minuend, size_t subtrahend) |
| { |
| return __atomic_sub_fetch(minuend, subtrahend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline size_t atomic_sub_size_t(size_t *minuend, size_t subtrahend) |
| { |
| return __sync_sub_and_fetch(minuend, subtrahend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically decrement a size_t |
| * |
| * This function atomically subtracts 1 from the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value after decrement. |
| */ |
| |
| static inline size_t atomic_dec_size_t(size_t *var) |
| { |
| return atomic_sub_size_t(var, 1); |
| } |
| |
| /* |
| * Postaddition, postsubtraction, postincrement, postdecrement (return the |
| * value before the operation, by analogy with the n++ postincrement |
| * operator.) |
| */ |
| |
| /** |
| * @brief Atomically add to an int64_t |
| * |
| * This function atomically adds to the supplied value. |
| * |
| * @param[in,out] augend Number to be added to |
| * @param[in] addend Number to add |
| * |
| * @return The value before addition. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline int64_t atomic_postadd_int64_t(int64_t *augend, uint64_t addend) |
| { |
| return __atomic_fetch_add(augend, addend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline int64_t atomic_postadd_int64_t(int64_t *augend, int64_t addend) |
| { |
| return __sync_fetch_and_add(augend, addend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically increment an int64_t |
| * |
| * This function atomically adds 1 to the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value before increment. |
| */ |
| |
| static inline int64_t atomic_postinc_int64_t(int64_t *var) |
| { |
| return atomic_postadd_int64_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically subtract from an int64_t |
| * |
| * This function atomically subtracts from the supplied value. |
| * |
| * @param[in,out] minuend Number to be subtracted from |
| * @param[in] subtrahend Number to subtract |
| * |
| * @return The value before subtraction. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline int64_t atomic_postsub_int64_t(int64_t *minuend, |
| int64_t subtrahend) |
| { |
| return __atomic_fetch_sub(minuend, subtrahend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline int64_t atomic_postsub_int64_t(int64_t *minuend, |
| int64_t subtrahend) |
| { |
| return __sync_fetch_and_sub(minuend, subtrahend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically decrement an int64_t |
| * |
| * This function atomically subtracts 1 from the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| */ |
| |
| static inline int64_t atomic_postdec_int64_t(int64_t *var) |
| { |
| return atomic_postsub_int64_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically add to an int64_t |
| * |
| * This function atomically adds to the supplied value. |
| * |
| * @param[in,out] augend Number to be added to |
| * @param[in] addend Number to add |
| * |
| * @return The value before addition. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint64_t atomic_postadd_uint64_t(uint64_t *augend, |
| uint64_t addend) |
| { |
| return __atomic_fetch_add(augend, addend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint64_t atomic_postadd_uint64_t(uint64_t *augend, |
| uint64_t addend) |
| { |
| return __sync_fetch_and_add(augend, addend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically increment a uint64_t |
| * |
| * This function atomically adds 1 to the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value before increment. |
| */ |
| |
| static inline uint64_t atomic_postinc_uint64_t(uint64_t *var) |
| { |
| return atomic_postadd_uint64_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically subtract from a uint64_t |
| * |
| * This function atomically subtracts from the supplied value. |
| * |
| * @param[in,out] minuend Number to be subtracted from |
| * @param[in] subtrahend Number to subtract |
| * |
| * @return The value before subtraction. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint64_t atomic_postsub_uint64_t(uint64_t *minuend, |
| uint64_t subtrahend) |
| { |
| return __atomic_fetch_sub(minuend, subtrahend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint64_t atomic_postsub_uint64_t(uint64_t *minuend, |
| uint64_t subtrahend) |
| { |
| return __sync_fetch_and_sub(minuend, subtrahend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically decrement a uint64_t |
| * |
| * This function atomically subtracts 1 from the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value before decrement. |
| */ |
| |
| static inline uint64_t atomic_postdec_uint64_t(uint64_t *var) |
| { |
| return atomic_postsub_uint64_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically add to an int32_t |
| * |
| * This function atomically adds to the supplied value. |
| * |
| * @param[in,out] augend Number to be added to |
| * @param[in] addend Number to add |
| * |
| * @return The value before addition. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline int32_t atomic_postadd_int32_t(int32_t *augend, int32_t addend) |
| { |
| return __atomic_fetch_add(augend, addend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline int32_t atomic_postadd_int32_t(int32_t *augend, int32_t addend) |
| { |
| return __sync_fetch_and_add(augend, addend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically increment an int32_t |
| * |
| * This function atomically adds 1 to the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value before increment. |
| */ |
| |
| static inline int32_t atomic_postinc_int32_t(int32_t *var) |
| { |
| return atomic_postadd_int32_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically subtract from an int32_t |
| * |
| * This function atomically subtracts from the supplied value. |
| * |
| * @param[in,out] minuend Number to be subtracted from |
| * @param[in] subtrahend Number to subtract |
| * |
| * @return The value before subtraction. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline int32_t atomic_postsub_int32_t(int32_t *minuend, |
| int32_t subtrahend) |
| { |
| return __atomic_fetch_sub(minuend, subtrahend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline int32_t atomic_postsub_int32_t(int32_t *minuend, |
| int32_t subtrahend) |
| { |
| return __sync_fetch_and_sub(minuend, subtrahend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically decrement an int32_t |
| * |
| * This function atomically subtracts 1 from the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value before decrement. |
| */ |
| |
| static inline int32_t atomic_postdec_int32_t(int32_t *var) |
| { |
| return atomic_postsub_int32_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically add to a uint32_t |
| * |
| * This function atomically adds to the supplied value. |
| * |
| * @param[in,out] augend Number to be added to |
| * @param[in] addend Number to add |
| * |
| * @return The value before addition. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint32_t atomic_postadd_uint32_t(uint32_t *augend, |
| uint32_t addend) |
| { |
| return __atomic_fetch_add(augend, addend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint32_t atomic_postadd_uint32_t(uint32_t *augend, |
| uint32_t addend) |
| { |
| return __sync_fetch_and_add(augend, addend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically increment a uint32_t |
| * |
| * This function atomically adds 1 to the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value before increment. |
| */ |
| |
| static inline uint32_t atomic_postinc_uint32_t(uint32_t *var) |
| { |
| return atomic_postadd_uint32_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically subtract from a uint32_t |
| * |
| * This function atomically subtracts from the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value before subtraction. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint32_t atomic_postsub_uint32_t(uint32_t *var, uint32_t sub) |
| { |
| return __atomic_fetch_sub(var, sub, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint32_t atomic_postsub_uint32_t(uint32_t *var, uint32_t sub) |
| { |
| return __sync_fetch_and_sub(var, sub); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically decrement a uint32_t |
| * |
| * This function atomically subtracts 1 from the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value before decrement. |
| */ |
| |
| static inline uint32_t atomic_postdec_uint32_t(uint32_t *var) |
| { |
| return atomic_postsub_uint32_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically add to an int16_t |
| * |
| * This function atomically adds to the supplied value. |
| * |
| * @param[in,out] augend Number to be added to |
| * @param[in] addend Number to add |
| * |
| * @return The value before addition. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline int16_t atomic_postadd_int16_t(int16_t *augend, int16_t addend) |
| { |
| return __atomic_fetch_add(augend, addend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline int16_t atomic_postadd_int16_t(int16_t *augend, int16_t addend) |
| { |
| return __sync_fetch_and_add(augend, addend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically increment an int16_t |
| * |
| * This function atomically adds 1 to the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value before increment. |
| */ |
| |
| static inline int16_t atomic_postinc_int16_t(int16_t *var) |
| { |
| return atomic_postadd_int16_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically subtract from an int16_t |
| * |
| * This function atomically subtracts from the supplied value. |
| * |
| * @param[in,out] minuend Number to be subtracted from |
| * @param[in] subtrahend Number to subtract |
| * |
| * @return The value before subtraction. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline int16_t atomic_postsub_int16_t(int16_t *minuend, |
| int16_t subtrahend) |
| { |
| return __atomic_fetch_sub(minuend, subtrahend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline int16_t atomic_postsub_int16_t(int16_t *minuend, |
| int16_t subtrahend) |
| { |
| return __sync_fetch_and_sub(minuend, subtrahend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically decrement an int16_t |
| * |
| * This function atomically subtracts 1 from the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value before decrement. |
| */ |
| |
| static inline int16_t atomic_postdec_int16_t(int16_t *var) |
| { |
| return atomic_postsub_int16_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically add to a uint16_t |
| * |
| * This function atomically adds to the supplied value. |
| * |
| * @param[in,out] augend Number to be added to |
| * @param[in] addend Number to add |
| * |
| * @return The value before addition. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint16_t atomic_postadd_uint16_t(uint16_t *augend, |
| uint16_t addend) |
| { |
| return __atomic_fetch_add(augend, addend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint16_t atomic_postadd_uint16_t(uint16_t *augend, |
| uint16_t addend) |
| { |
| return __sync_fetch_and_add(augend, addend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically increment a uint16_t |
| * |
| * This function atomically adds 1 to the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value before increment. |
| */ |
| |
| static inline uint16_t atomic_postinc_uint16_t(uint16_t *var) |
| { |
| return atomic_postadd_uint16_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically subtract from a uint16_t |
| * |
| * This function atomically subtracts from the supplied value. |
| * |
| * @param[in,out] minuend Number to be subtracted from |
| * @param[in] subtrahend Number to subtract |
| * |
| * @return The value before subtraction. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint16_t atomic_postsub_uint16_t(uint16_t *minuend, |
| uint16_t subtrahend) |
| { |
| return __atomic_fetch_sub(minuend, subtrahend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint16_t atomic_postsub_uint16_t(uint16_t *minuend, |
| uint16_t subtrahend) |
| { |
| return __sync_fetch_and_sub(minuend, subtrahend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically decrement a uint16_t |
| * |
| * This function atomically subtracts 1 from the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value before decrement. |
| */ |
| |
| static inline uint16_t atomic_postdec_uint16_t(uint16_t *var) |
| { |
| return atomic_postsub_uint16_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically add to an int8_t |
| * |
| * This function atomically adds to the supplied value. |
| * |
| * @param[in,out] augend Number to be added to |
| * @param[in] addend Number to add |
| * |
| * @return The value before addition. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline int8_t atomic_postadd_int8_t(int8_t *augend, int8_t addend) |
| { |
| return __atomic_fetch_add(augend, addend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline int8_t atomic_postadd_int8_t(int8_t *augend, int8_t addend) |
| { |
| return __sync_fetch_and_add(augend, addend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically increment an int8_t |
| * |
| * This function atomically adds 1 to the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value before increment. |
| */ |
| |
| static inline int8_t atomic_postinc_int8_t(int8_t *var) |
| { |
| return atomic_postadd_int8_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically subtract from an int8_t |
| * |
| * This function atomically subtracts from the supplied value. |
| * |
| * @param[in,out] minuend Number to be subtracted from |
| * @param[in] subtrahend Number to subtract |
| * |
| * @return The value before subtraction. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline int8_t atomic_postsub_int8_t(int8_t *minuend, int8_t subtrahend) |
| { |
| return __atomic_fetch_sub(minuend, subtrahend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline int8_t atomic_postsub_int8_t(int8_t *minuend, int8_t subtrahend) |
| { |
| return __sync_fetch_and_sub(minuend, subtrahend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically decrement an int8_t |
| * |
| * This function atomically subtracts 1 from the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value before decrement. |
| */ |
| |
| static inline int8_t atomic_postdec_int8_t(int8_t *var) |
| { |
| return atomic_postsub_int8_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically add to a uint8_t |
| * |
| * This function atomically adds to the supplied value. |
| * |
| * @param[in,out] augend Number to be added to |
| * @param[in] addend Number to add |
| * |
| * @return The value before addition. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint8_t atomic_postadd_uint8_t(uint8_t *augend, uint8_t addend) |
| { |
| return __atomic_fetch_add(augend, addend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint8_t atomic_postadd_uint8_t(uint8_t *augend, uint8_t addend) |
| { |
| return __sync_fetch_and_add(augend, addend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically increment a uint8_t |
| * |
| * This function atomically adds 1 to the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value before increment. |
| */ |
| |
| static inline uint8_t atomic_postinc_uint8_t(uint8_t *var) |
| { |
| return atomic_postadd_uint8_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically subtract from a uint8_t |
| * |
| * This function atomically subtracts from the supplied value. |
| * |
| * @param[in,out] minuend Number to be subtracted from |
| * @param[in] subtrahend Number to subtract |
| * |
| * @return The value before subtraction. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint8_t atomic_postsub_uint8_t(uint8_t *minuend, |
| uint8_t subtrahend) |
| { |
| return __atomic_fetch_sub(minuend, subtrahend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint8_t atomic_postsub_uint8_t(uint8_t *minuend, |
| uint8_t subtrahend) |
| { |
| return __sync_fetch_and_sub(minuend, subtrahend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically decrement a uint8_t |
| * |
| * This function atomically subtracts 1 from the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value before decrement. |
| */ |
| |
| static inline uint8_t atomic_postdec_uint8_t(uint8_t *var) |
| { |
| return atomic_postsub_uint8_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically add to a size_t |
| * |
| * This function atomically adds to the supplied value. |
| * |
| * @param[in,out] augend Number to be added to |
| * @param[in] addend Number to add |
| * |
| * @return The value before addition. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline size_t atomic_postadd_size_t(size_t *augend, size_t addend) |
| { |
| return __atomic_fetch_add(augend, addend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline size_t atomic_postadd_size_t(size_t *augend, size_t addend) |
| { |
| return __sync_fetch_and_add(augend, addend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically increment a size_t |
| * |
| * This function atomically adds 1 to the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value before increment. |
| */ |
| |
| static inline size_t atomic_postinc_size_t(size_t *var) |
| { |
| return atomic_postadd_size_t(var, 1); |
| } |
| |
| /** |
| * @brief Atomically subtract from a size_t |
| * |
| * This function atomically subtracts from the supplied value. |
| * |
| * @param[in,out] minuend Number to be subtracted from |
| * @param[in] subtrahend Number to subtract |
| * |
| * @return The value before subtraction. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline size_t atomic_postsub_size_t(size_t *minuend, size_t subtrahend) |
| { |
| return __atomic_fetch_sub(minuend, subtrahend, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline size_t atomic_postsub_size_t(size_t *minuend, size_t subtrahend) |
| { |
| return __sync_fetch_and_sub(minuend, subtrahend); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically decrement a size_t |
| * |
| * This function atomically subtracts 1 from the supplied value. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * |
| * @return The value before decrement. |
| */ |
| |
| static inline size_t atomic_postdec_size_t(size_t *var) |
| { |
| return atomic_postsub_size_t(var, 1); |
| } |
| |
| /* |
| * Preclear and preset bits (return the value after the operation, by |
| * analogy with the ++n preincrement operator.) |
| */ |
| |
| /** |
| * @brief Atomically clear bits in a uint64_t |
| * |
| * This function atomic clears the bits indicated. |
| * |
| * @param[in,out] var Pointer to the value to modify |
| * @param[in] bits Bits to clear |
| * |
| * @return The value after clearing. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint64_t atomic_clear_uint64_t_bits(uint64_t *var, uint64_t bits) |
| { |
| return __atomic_and_fetch(var, ~bits, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint64_t atomic_clear_uint64_t_bits(uint64_t *var, uint64_t bits) |
| { |
| return __sync_and_and_fetch(var, ~bits); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically set bits in a uint64_t |
| * |
| * This function atomic clears the bits indicated. |
| * |
| * @param[in,out] var Pointer to the value to modify |
| * @param[in] bits Bits to set |
| * |
| * @return The value after setting. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint64_t atomic_set_uint64_t_bits(uint64_t *var, uint64_t bits) |
| { |
| return __atomic_or_fetch(var, bits, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint64_t atomic_set_uint64_t_bits(uint64_t *var, uint64_t bits) |
| { |
| return __sync_or_and_fetch(var, bits); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically clear bits in a uint32_t |
| * |
| * This function atomic clears the bits indicated. |
| * |
| * @param[in,out] var Pointer to the value to modify |
| * @param[in] bits Bits to clear |
| * |
| * @return The value after clearing. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint32_t atomic_clear_uint32_t_bits(uint32_t *var, uint32_t bits) |
| { |
| return __atomic_and_fetch(var, ~bits, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint32_t atomic_clear_uint32_t_bits(uint32_t *var, uint32_t bits) |
| { |
| return __sync_and_and_fetch(var, ~bits); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically set bits in a uint32_t |
| * |
| * This function atomic clears the bits indicated. |
| * |
| * @param[in,out] var Pointer to the value to modify |
| * @param[in] bits Bits to set |
| * |
| * @return The value after setting. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint32_t atomic_set_uint32_t_bits(uint32_t *var, uint32_t bits) |
| { |
| return __atomic_or_fetch(var, bits, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint32_t atomic_set_uint32_t_bits(uint32_t *var, uint32_t bits) |
| { |
| return __sync_or_and_fetch(var, bits); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically clear bits in a uint16_t |
| * |
| * This function atomic clears the bits indicated. |
| * |
| * @param[in,out] var Pointer to the value to modify |
| * @param[in] bits Bits to clear |
| * |
| * @return The value after clearing. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint16_t atomic_clear_uint16_t_bits(uint16_t *var, uint16_t bits) |
| { |
| return __atomic_and_fetch(var, ~bits, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint16_t atomic_clear_uint16_t_bits(uint16_t *var, uint16_t bits) |
| { |
| return __sync_and_and_fetch(var, ~bits); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically set bits in a uint16_t |
| * |
| * This function atomic clears the bits indicated. |
| * |
| * @param[in,out] var Pointer to the value to modify |
| * @param[in] bits Bits to set |
| * |
| * @return The value after setting. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint16_t atomic_set_uint16_t_bits(uint16_t *var, uint16_t bits) |
| { |
| return __atomic_or_fetch(var, bits, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint16_t atomic_set_uint16_t_bits(uint16_t *var, uint16_t bits) |
| { |
| return __sync_or_and_fetch(var, bits); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically clear bits in a uint8_t |
| * |
| * This function atomic clears the bits indicated. |
| * |
| * @param[in,out] var Pointer to the value to modify |
| * @param[in] bits Bits to clear |
| * |
| * @return The value after clearing. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint8_t atomic_clear_uint8_t_bits(uint8_t *var, uint8_t bits) |
| { |
| return __atomic_and_fetch(var, ~bits, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint8_t atomic_clear_uint8_t_bits(uint8_t *var, uint8_t bits) |
| { |
| return __sync_and_and_fetch(var, ~bits); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically set bits in a uint8_t |
| * |
| * This function atomic clears the bits indicated. |
| * |
| * @param[in,out] var Pointer to the value to modify |
| * @param[in] bits Bits to set |
| * |
| * @return The value after setting. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint8_t atomic_set_uint8_t_bits(uint8_t *var, uint8_t bits) |
| { |
| return __atomic_or_fetch(var, bits, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint8_t atomic_set_uint8_t_bits(uint8_t *var, uint8_t bits) |
| { |
| return __sync_or_and_fetch(var, bits); |
| } |
| #endif |
| |
| /* |
| * Postclear and postset bits (return the value before the operation, |
| * by analogy with the n++ postincrement operator.) |
| */ |
| |
| /** |
| * @brief Atomically clear bits in a uint64_t |
| * |
| * This function atomic clears the bits indicated. |
| * |
| * @param[in,out] var Pointer to the value to modify |
| * @param[in] bits Bits to clear |
| * |
| * @return The value before clearing. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint64_t atomic_postclear_uint64_t_bits(uint64_t *var, |
| uint64_t bits) |
| { |
| return __atomic_fetch_and(var, ~bits, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint64_t atomic_postclear_uint64_t_bits(uint64_t *var, |
| uint64_t bits) |
| { |
| return __sync_fetch_and_and(var, ~bits); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically set bits in a uint64_t |
| * |
| * This function atomic clears the bits indicated. |
| * |
| * @param[in,out] var Pointer to the value to modify |
| * @param[in] bits Bits to set |
| * |
| * @return The value before setting. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint64_t atomic_postset_uint64_t_bits(uint64_t *var, |
| uint64_t bits) |
| { |
| return __atomic_fetch_or(var, bits, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint64_t atomic_postset_uint64_t_bits(uint64_t *var, |
| uint64_t bits) |
| { |
| return __sync_fetch_and_or(var, bits); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically clear bits in a uint32_t |
| * |
| * This function atomic clears the bits indicated. |
| * |
| * @param[in,out] var Pointer to the value to modify |
| * @param[in] bits Bits to clear |
| * |
| * @return The value before clearing. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint32_t atomic_postclear_uint32_t_bits(uint32_t *var, |
| uint32_t bits) |
| { |
| return __atomic_fetch_and(var, ~bits, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint32_t atomic_postclear_uint32_t_bits(uint32_t *var, |
| uint32_t bits) |
| { |
| return __sync_fetch_and_and(var, ~bits); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically set bits in a uint32_t |
| * |
| * This function atomic clears the bits indicated. |
| * |
| * @param[in,out] var Pointer to the value to modify |
| * @param[in] bits Bits to set |
| * |
| * @return The value before setting. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint32_t atomic_postset_uint32_t_bits(uint32_t *var, |
| uint32_t bits) |
| { |
| return __atomic_fetch_or(var, bits, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint32_t atomic_postset_uint32_t_bits(uint32_t *var, |
| uint32_t bits) |
| { |
| return __sync_fetch_and_or(var, bits); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically clear bits in a uint16_t |
| * |
| * This function atomic clears the bits indicated. |
| * |
| * @param[in,out] var Pointer to the value to modify |
| * @param[in] bits Bits to clear |
| * |
| * @return The value before clearing. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint16_t atomic_postclear_uint16_t_bits(uint16_t *var, |
| uint16_t bits) |
| { |
| return __atomic_fetch_and(var, ~bits, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint16_t atomic_postclear_uint16_t_bits(uint16_t *var, |
| uint16_t bits) |
| { |
| return __sync_fetch_and_and(var, ~bits); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically set bits in a uint16_t |
| * |
| * This function atomic clears the bits indicated. |
| * |
| * @param[in,out] var Pointer to the value to modify |
| * @param[in] bits Bits to set |
| * |
| * @return The value before setting. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint16_t atomic_postset_uint16_t_bits(uint16_t *var, |
| uint16_t bits) |
| { |
| return __atomic_fetch_or(var, bits, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint16_t atomic_postset_uint16_t_bits(uint16_t *var, |
| uint16_t bits) |
| { |
| return __sync_fetch_and_or(var, bits); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically clear bits in a uint8_t |
| * |
| * This function atomic clears the bits indicated. |
| * |
| * @param[in,out] var Pointer to the value to modify |
| * @param[in] bits Bits to clear |
| * |
| * @return The value before clearing. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint8_t atomic_postclear_uint8_t_bits(uint8_t *var, uint8_t bits) |
| { |
| return __atomic_fetch_and(var, ~bits, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint8_t atomic_postclear_uint8_t_bits(uint8_t *var, uint8_t bits) |
| { |
| return __sync_fetch_and_and(var, ~bits); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically set bits in a uint8_t |
| * |
| * This function atomic clears the bits indicated. |
| * |
| * @param[in,out] var Pointer to the value to modify |
| * @param[in] bits Bits to set |
| * |
| * @return The value before setting. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint8_t atomic_postset_uint8_t_bits(uint8_t *var, uint8_t bits) |
| { |
| return __atomic_fetch_or(var, bits, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint8_t atomic_postset_uint8_t_bits(uint8_t *var, uint8_t bits) |
| { |
| return __sync_fetch_and_or(var, bits); |
| } |
| #endif |
| |
| /* |
| * Fetch and store |
| */ |
| |
| /** |
| * @brief Atomically fetch a size_t |
| * |
| * This function atomically fetches the value indicated by the |
| * supplied pointer. |
| * |
| * @param[in,out] var Pointer to the variable to fetch |
| * |
| * @return the value pointed to by var. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline size_t atomic_fetch_size_t(size_t *var) |
| { |
| return __atomic_load_n(var, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline size_t atomic_fetch_size_t(size_t *var) |
| { |
| return __sync_fetch_and_add(var, 0); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically store a size_t |
| * |
| * This function atomically fetches the value indicated by the |
| * supplied pointer. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * @param[in] val The value to store |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline void atomic_store_size_t(size_t *var, size_t val) |
| { |
| __atomic_store_n(var, val, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline void atomic_store_size_t(size_t *var, size_t val) |
| { |
| (void)__sync_lock_test_and_set(var, val); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically fetch a ptrdiff_t |
| * |
| * This function atomically fetches the value indicated by the |
| * supplied pointer. |
| * |
| * @param[in,out] var Pointer to the variable to fetch |
| * |
| * @return the value pointed to by var. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline ptrdiff_t atomic_fetch_ptrdiff_t(ptrdiff_t *var) |
| { |
| return __atomic_load_n(var, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline ptrdiff_t atomic_fetch_ptrdiff_t(ptrdiff_t *var) |
| { |
| return __sync_fetch_and_add(var, 0); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically store a ptrdiff_t |
| * |
| * This function atomically fetches the value indicated by the |
| * supplied pointer. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * @param[in] val The value to store |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline void atomic_store_ptrdiff_t(ptrdiff_t *var, ptrdiff_t val) |
| { |
| __atomic_store_n(var, val, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline void atomic_store_ptrdiff_t(ptrdiff_t *var, ptrdiff_t val) |
| { |
| (void)__sync_lock_test_and_set(var, val); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically fetch a time_t |
| * |
| * This function atomically fetches the value indicated by the |
| * supplied pointer. |
| * |
| * @param[in,out] var Pointer to the variable to fetch |
| * |
| * @return the value pointed to by var. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline time_t atomic_fetch_time_t(time_t *var) |
| { |
| return __atomic_load_n(var, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline time_t atomic_fetch_time_t(time_t *var) |
| { |
| return __sync_fetch_and_add(var, 0); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically store a time_t |
| * |
| * This function atomically fetches the value indicated by the |
| * supplied pointer. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * @param[in] val The value to store |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline void atomic_store_time_t(time_t *var, time_t val) |
| { |
| __atomic_store_n(var, val, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline void atomic_store_time_t(time_t *var, time_t val) |
| { |
| (void)__sync_lock_test_and_set(var, val); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically fetch a uintptr_t |
| * |
| * This function atomically fetches the value indicated by the |
| * supplied pointer. |
| * |
| * @param[in,out] var Pointer to the variable to fetch |
| * |
| * @return the value pointed to by var. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uintptr_t atomic_fetch_uintptr_t(uintptr_t *var) |
| { |
| return __atomic_load_n(var, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uintptr_t atomic_fetch_uintptr_t(uintptr_t *var) |
| { |
| return __sync_fetch_and_add(var, 0); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically store a uintptr_t |
| * |
| * This function atomically fetches the value indicated by the |
| * supplied pointer. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * @param[in] val The value to store |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline void atomic_store_uintptr_t(uintptr_t *var, uintptr_t val) |
| { |
| __atomic_store_n(var, val, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline void atomic_store_uintptr_t(uintptr_t *var, uintptr_t val) |
| { |
| (void)__sync_lock_test_and_set(var, 0); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically fetch a void * |
| * |
| * This function atomically fetches the value indicated by the |
| * supplied pointer. |
| * |
| * @param[in,out] var Pointer to the variable to fetch |
| * |
| * @return the value pointed to by var. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline void *atomic_fetch_voidptr(void **var) |
| { |
| return __atomic_load_n(var, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline void *atomic_fetch_voidptr(void **var) |
| { |
| return __sync_fetch_and_add(var, 0); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically store a void * |
| * |
| * This function atomically stores the value indicated by the |
| * supplied pointer. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * @param[in] val The value to store |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline void atomic_store_voidptr(void **var, void *val) |
| { |
| __atomic_store_n(var, val, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline void atomic_store_voidptr(void **var, void *val) |
| { |
| (void)__sync_lock_test_and_set(var, val); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically fetch an int64_t |
| * |
| * This function atomically fetches the value indicated by the |
| * supplied pointer. |
| * |
| * @param[in,out] var Pointer to the variable to fetch |
| * |
| * @return the value pointed to by var. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline int64_t atomic_fetch_int64_t(int64_t *var) |
| { |
| return __atomic_load_n(var, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline int64_t atomic_fetch_int64_t(int64_t *var) |
| { |
| return __sync_fetch_and_add(var, 0); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically store an int64_t |
| * |
| * This function atomically fetches the value indicated by the |
| * supplied pointer. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * @param[in] val The value to store |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline void atomic_store_int64_t(int64_t *var, int64_t val) |
| { |
| __atomic_store_n(var, val, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline void atomic_store_int64_t(int64_t *var, int64_t val) |
| { |
| (void)__sync_lock_test_and_set(var, val); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically fetch a uint64_t |
| * |
| * This function atomically fetches the value indicated by the |
| * supplied pointer. |
| * |
| * @param[in,out] var Pointer to the variable to fetch |
| * |
| * @return the value pointed to by var. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint64_t atomic_fetch_uint64_t(uint64_t *var) |
| { |
| return __atomic_load_n(var, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint64_t atomic_fetch_uint64_t(uint64_t *var) |
| { |
| return __sync_fetch_and_add(var, 0); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically store a uint64_t |
| * |
| * This function atomically fetches the value indicated by the |
| * supplied pointer. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * @param[in] val The value to store |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline void atomic_store_uint64_t(uint64_t *var, uint64_t val) |
| { |
| __atomic_store_n(var, val, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline void atomic_store_uint64_t(uint64_t *var, uint64_t val) |
| { |
| (void)__sync_lock_test_and_set(var, val); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically fetch an int32_t |
| * |
| * This function atomically fetches the value indicated by the |
| * supplied pointer. |
| * |
| * @param[in,out] var Pointer to the variable to fetch |
| * |
| * @return the value pointed to by var. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline int32_t atomic_fetch_int32_t(int32_t *var) |
| { |
| return __atomic_load_n(var, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline int32_t atomic_fetch_int32_t(int32_t *var) |
| { |
| return __sync_fetch_and_add(var, 0); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically store an int32_t |
| * |
| * This function atomically fetches the value indicated by the |
| * supplied pointer. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * @param[in] val The value to store |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline void atomic_store_int32_t(int32_t *var, int32_t val) |
| { |
| __atomic_store_n(var, val, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline void atomic_store_int32_t(int32_t *var, int32_t val) |
| { |
| (void)__sync_lock_test_and_set(var, val); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically fetch a uint32_t |
| * |
| * This function atomically fetches the value indicated by the |
| * supplied pointer. |
| * |
| * @param[in,out] var Pointer to the variable to fetch |
| * |
| * @return the value pointed to by var. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint32_t atomic_fetch_uint32_t(uint32_t *var) |
| { |
| return __atomic_load_n(var, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint32_t atomic_fetch_uint32_t(uint32_t *var) |
| { |
| return __sync_fetch_and_add(var, 0); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically store a uint32_t |
| * |
| * This function atomically fetches the value indicated by the |
| * supplied pointer. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * @param[in] val The value to store |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline void atomic_store_uint32_t(uint32_t *var, uint32_t val) |
| { |
| __atomic_store_n(var, val, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline void atomic_store_uint32_t(uint32_t *var, uint32_t val) |
| { |
| (void)__sync_lock_test_and_set(var, val); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically fetch an int16_t |
| * |
| * This function atomically fetches the value indicated by the |
| * supplied pointer. |
| * |
| * @param[in,out] var Pointer to the variable to fetch |
| * |
| * @return the value pointed to by var. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline int16_t atomic_fetch_int16_t(int16_t *var) |
| { |
| return __atomic_load_n(var, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline int16_t atomic_fetch_int16_t(int16_t *var) |
| { |
| return __sync_fetch_and_add(var, 0); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically store an int16_t |
| * |
| * This function atomically fetches the value indicated by the |
| * supplied pointer. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * @param[in] val The value to store |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline void atomic_store_int16_t(int16_t *var, int16_t val) |
| { |
| __atomic_store_n(var, val, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline void atomic_store_int16_t(int16_t *var, int16_t val) |
| { |
| (void)__sync_lock_test_and_set(var, val); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically fetch a uint16_t |
| * |
| * This function atomically fetches the value indicated by the |
| * supplied pointer. |
| * |
| * @param[in,out] var Pointer to the variable to fetch |
| * |
| * @return the value pointed to by var. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint16_t atomic_fetch_uint16_t(uint16_t *var) |
| { |
| return __atomic_load_n(var, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint16_t atomic_fetch_uint16_t(uint16_t *var) |
| { |
| return __sync_fetch_and_add(var, 0); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically store a uint16_t |
| * |
| * This function atomically fetches the value indicated by the |
| * supplied pointer. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * @param[in] val The value to store |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline void atomic_store_uint16_t(uint16_t *var, uint16_t val) |
| { |
| __atomic_store_n(var, val, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline void atomic_store_uint16_t(uint16_t *var, uint16_t val) |
| { |
| (void)__sync_lock_test_and_set(var, val); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically fetch a int8_t |
| * |
| * This function atomically fetches the value indicated by the |
| * supplied pointer. |
| * |
| * @param[in,out] var Pointer to the variable to fetch |
| * |
| * @return the value pointed to by var. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline int8_t atomic_fetch_int8_t(int8_t *var) |
| { |
| return __atomic_load_n(var, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline int8_t atomic_fetch_int8_t(int8_t *var) |
| { |
| return __sync_fetch_and_add(var, 0); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically store a int8_t |
| * |
| * This function atomically fetches the value indicated by the |
| * supplied pointer. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * @param[in] val The value to store |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline void atomic_store_int8_t(int8_t *var, int8_t val) |
| { |
| __atomic_store_n(var, val, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline void atomic_store_int8_t(int8_t *var, int8_t val) |
| { |
| (void)__sync_lock_test_and_set(var, val); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically fetch a uint8_t |
| * |
| * This function atomically fetches the value indicated by the |
| * supplied pointer. |
| * |
| * @param[in,out] var Pointer to the variable to fetch |
| * |
| * @return the value pointed to by var. |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline uint8_t atomic_fetch_uint8_t(uint8_t *var) |
| { |
| return __atomic_load_n(var, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline uint8_t atomic_fetch_uint8_t(uint8_t *var) |
| { |
| return __sync_fetch_and_add(var, 0); |
| } |
| #endif |
| |
| /** |
| * @brief Atomically store a uint8_t |
| * |
| * This function atomically fetches the value indicated by the |
| * supplied pointer. |
| * |
| * @param[in,out] var Pointer to the variable to modify |
| * @param[in] val The value to store |
| */ |
| |
| #ifdef GCC_ATOMIC_FUNCTIONS |
| static inline void atomic_store_uint8_t(uint8_t *var, uint8_t val) |
| { |
| __atomic_store_n(var, val, __ATOMIC_SEQ_CST); |
| } |
| #elif defined(GCC_SYNC_FUNCTIONS) |
| static inline void atomic_store_uint8_t(uint8_t *var, uint8_t val) |
| { |
| (void)__sync_lock_test_and_set(var, val); |
| } |
| #endif |
| #endif /* !_ABSTRACT_ATOMIC_H */ |