blob: 22c356a5f62b18d5ae863c6b2b46dc481e53fdc5 [file] [log] [blame]
/*
* 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 */