136 #ifndef ATOMIC_UTILS_H 137 #define ATOMIC_UTILS_H 142 #include "atomic_utils_arch.h" 150 #if !defined(HAS_ATOMIC_BIT) || defined(DOXYGEN) 217 static inline uint8_t
atomic_load_u8(
const volatile uint8_t *var);
250 static inline void atomic_store_u8(
volatile uint8_t *dest, uint8_t val);
330 uint16_t subtrahend);
339 uint32_t subtrahend);
348 uint64_t subtrahend);
626 uint16_t subtrahend);
635 uint32_t subtrahend);
644 uint64_t subtrahend);
777 #define CONCAT(a, b) a ## b 782 #define CONCAT4(a, b, c, d) a ## b ## c ## d 791 #define ATOMIC_LOAD_IMPL(name, type) \ 792 static inline type CONCAT(atomic_load_, name)(const volatile type *var) \ 794 unsigned state = irq_disable(); \ 795 type result = *var; \ 796 irq_restore(state); \ 800 #ifndef HAS_ATOMIC_LOAD_U8 803 #ifndef HAS_ATOMIC_LOAD_U16 806 #ifndef HAS_ATOMIC_LOAD_U32 809 #ifndef HAS_ATOMIC_LOAD_U64 820 #define ATOMIC_STORE_IMPL(name, type) \ 821 static inline void CONCAT(atomic_store_, name) \ 822 (volatile type *dest, type val) \ 824 unsigned state = irq_disable(); \ 826 irq_restore(state); \ 829 #ifndef HAS_ATOMIC_STORE_U8 832 #ifndef HAS_ATOMIC_STORE_U16 835 #ifndef HAS_ATOMIC_STORE_U32 838 #ifndef HAS_ATOMIC_STORE_U64 851 #define ATOMIC_FETCH_OP_IMPL(opname, op, name, type) \ 852 static inline type CONCAT4(atomic_fetch_, opname, _, name) \ 853 (volatile type *dest, type val) \ 855 unsigned state = irq_disable(); \ 856 const type result = *dest; \ 857 *dest = result op val; \ 858 irq_restore(state); \ 862 #ifndef HAS_ATOMIC_FETCH_ADD_U8 865 #ifndef HAS_ATOMIC_FETCH_ADD_U16 868 #ifndef HAS_ATOMIC_FETCH_ADD_U32 871 #ifndef HAS_ATOMIC_FETCH_ADD_U64 875 #ifndef HAS_ATOMIC_FETCH_SUB_U8 878 #ifndef HAS_ATOMIC_FETCH_SUB_U16 881 #ifndef HAS_ATOMIC_FETCH_SUB_U32 884 #ifndef HAS_ATOMIC_FETCH_SUB_U64 888 #ifndef HAS_ATOMIC_FETCH_OR_U8 891 #ifndef HAS_ATOMIC_FETCH_OR_U16 894 #ifndef HAS_ATOMIC_FETCH_OR_U32 897 #ifndef HAS_ATOMIC_FETCH_OR_U64 901 #ifndef HAS_ATOMIC_FETCH_XOR_U8 904 #ifndef HAS_ATOMIC_FETCH_XOR_U16 907 #ifndef HAS_ATOMIC_FETCH_XOR_U32 910 #ifndef HAS_ATOMIC_FETCH_XOR_U64 914 #ifndef HAS_ATOMIC_FETCH_AND_U8 917 #ifndef HAS_ATOMIC_FETCH_AND_U16 920 #ifndef HAS_ATOMIC_FETCH_AND_U32 923 #ifndef HAS_ATOMIC_FETCH_AND_U64 927 #ifndef HAS_ATOMIC_BIT 999 #if defined(HAS_ATOMIC_FETCH_ADD_U8) || !defined(HAS_ATOMIC_STORE_U8) 1015 #if defined(HAS_ATOMIC_FETCH_ADD_U16) || !defined(HAS_ATOMIC_STORE_U16) 1031 #if defined(HAS_ATOMIC_FETCH_ADD_U32) || !defined(HAS_ATOMIC_STORE_U32) 1047 #if defined(HAS_ATOMIC_FETCH_ADD_U64) || !defined(HAS_ATOMIC_STORE_U64) 1062 #if defined(HAS_ATOMIC_FETCH_SUB_U8) || !defined(HAS_ATOMIC_STORE_U8) 1078 #if defined(HAS_ATOMIC_FETCH_SUB_U16) || !defined(HAS_ATOMIC_STORE_U16) 1094 #if defined(HAS_ATOMIC_FETCH_SUB_U32) || !defined(HAS_ATOMIC_STORE_U32) 1110 #if defined(HAS_ATOMIC_FETCH_SUB_U64) || !defined(HAS_ATOMIC_STORE_U64) 1127 #if defined(HAS_ATOMIC_FETCH_OR_U8) || !defined(HAS_ATOMIC_STORE_U8) 1143 #if defined(HAS_ATOMIC_FETCH_OR_U16) || !defined(HAS_ATOMIC_STORE_U16) 1159 #if defined(HAS_ATOMIC_FETCH_OR_U32) || !defined(HAS_ATOMIC_STORE_U32) 1175 #if defined(HAS_ATOMIC_FETCH_OR_U64) || !defined(HAS_ATOMIC_STORE_U64) 1192 #if defined(HAS_ATOMIC_FETCH_XOR_U8) || !defined(HAS_ATOMIC_STORE_U8) 1208 #if defined(HAS_ATOMIC_FETCH_XOR_U16) || !defined(HAS_ATOMIC_STORE_U16) 1224 #if defined(HAS_ATOMIC_FETCH_XOR_U32) || !defined(HAS_ATOMIC_STORE_U32) 1240 #if defined(HAS_ATOMIC_FETCH_XOR_U64) || !defined(HAS_ATOMIC_STORE_U64) 1257 #if defined(HAS_ATOMIC_FETCH_AND_U8) || !defined(HAS_ATOMIC_STORE_U8) 1273 #if defined(HAS_ATOMIC_FETCH_AND_U16) || !defined(HAS_ATOMIC_STORE_U16) 1289 #if defined(HAS_ATOMIC_FETCH_AND_U32) || !defined(HAS_ATOMIC_STORE_U32) 1305 #if defined(HAS_ATOMIC_FETCH_AND_U64) || !defined(HAS_ATOMIC_STORE_U64) static uint32_t atomic_fetch_or_u32(volatile uint32_t *dest, uint32_t val)
Atomic version of *dest |= val
Type specifying a bit in an uint16_t
static atomic_bit_u16_t atomic_bit_u16(volatile uint16_t *dest, uint8_t bit)
Create a reference to a bit in an uint16_t
static uint16_t atomic_load_u16(const volatile uint16_t *var)
Load an uint16_t atomically.
Type specifying a bit in an uint8_t
static void atomic_store_u16(volatile uint16_t *dest, uint16_t val)
Store an uint16_t atomically.
volatile uint8_t * dest
Memory containing the bit to set/clear.
static void atomic_clear_bit_u32(atomic_bit_u32_t bit)
Atomic version of *dest &= ~(1 << bit)
static uint64_t semi_atomic_fetch_sub_u64(volatile uint64_t *dest, uint64_t subtrahend)
Semi-atomically subtract a value from a given value.
volatile uint16_t * dest
Memory containing the bit to set/clear.
static void atomic_set_bit_u32(atomic_bit_u32_t bit)
Atomic version of *dest |= (1 << bit)
uint8_t mask
Bitmask used for setting the bit.
static uint32_t atomic_fetch_xor_u32(volatile uint32_t *dest, uint32_t val)
Atomic version of *dest ^= val
static uint64_t atomic_fetch_sub_u64(volatile uint64_t *dest, uint64_t subtrahend)
Atomically subtract a value from a given value.
static uint64_t semi_atomic_fetch_and_u64(volatile uint64_t *dest, uint64_t val)
Semi-atomic version of *dest &= val
static uint16_t semi_atomic_fetch_add_u16(volatile uint16_t *dest, uint16_t summand)
Semi-atomically add a value onto a given value.
static void atomic_store_u32(volatile uint32_t *dest, uint32_t val)
Store an uint32_t atomically.
static void atomic_store_u8(volatile uint8_t *dest, uint8_t val)
Store an uint8_t atomically.
static atomic_bit_u64_t atomic_bit_u64(volatile uint64_t *dest, uint8_t bit)
Create a reference to a bit in an uint64_t
static uint8_t atomic_fetch_and_u8(volatile uint8_t *dest, uint8_t val)
Atomic version of *dest &= val
static uint16_t semi_atomic_fetch_or_u16(volatile uint16_t *dest, uint16_t val)
Semi-atomic version of *dest |= val
Type specifying a bit in an uint32_t
static uint8_t semi_atomic_fetch_add_u8(volatile uint8_t *dest, uint8_t summand)
Semi-atomically add a value onto a given value.
static uint64_t semi_atomic_fetch_add_u64(volatile uint64_t *dest, uint64_t summand)
Semi-atomically add a value onto a given value.
static uint32_t atomic_load_u32(const volatile uint32_t *var)
Load an uint32_t atomically.
#define ATOMIC_FETCH_OP_IMPL(opname, op, name, type)
Generates a static inline function implementing atomic_fecth_<op>_u<width>()
static uint32_t semi_atomic_fetch_xor_u32(volatile uint32_t *dest, uint32_t val)
Semi-atomic version of *dest ^= val
uint32_t mask
Bitmask used for setting the bit.
static uint16_t semi_atomic_fetch_xor_u16(volatile uint16_t *dest, uint16_t val)
Semi-atomic version of *dest ^= val
static void atomic_set_bit_u8(atomic_bit_u8_t bit)
Atomic version of *dest |= (1 << bit)
static uint8_t semi_atomic_fetch_xor_u8(volatile uint8_t *dest, uint8_t val)
Semi-atomic version of *dest ^= val
static atomic_bit_u8_t atomic_bit_u8(volatile uint8_t *dest, uint8_t bit)
Create a reference to a bit in an uint8_t
volatile uint64_t * dest
Memory containing the bit to set/clear.
static uint16_t atomic_fetch_sub_u16(volatile uint16_t *dest, uint16_t subtrahend)
Atomically subtract a value from a given value.
static uint64_t atomic_fetch_add_u64(volatile uint64_t *dest, uint64_t summand)
Atomically add a value onto a given value.
static uint16_t atomic_fetch_xor_u16(volatile uint16_t *dest, uint16_t val)
Atomic version of *dest ^= val
volatile uint32_t * dest
Memory containing the bit to set/clear.
uint16_t mask
Bitmask used for setting the bit.
static uint8_t semi_atomic_fetch_sub_u8(volatile uint8_t *dest, uint8_t subtrahend)
Semi-atomically subtract a value from a given value.
static uint16_t semi_atomic_fetch_sub_u16(volatile uint16_t *dest, uint16_t subtrahend)
Semi-atomically subtract a value from a given value.
Type specifying a bit in an uint64_t
static uint8_t atomic_load_u8(const volatile uint8_t *var)
Load an uint8_t atomically.
static uint16_t atomic_fetch_add_u16(volatile uint16_t *dest, uint16_t summand)
Atomically add a value onto a given value.
static void atomic_clear_bit_u8(atomic_bit_u8_t bit)
Atomic version of *dest &= ~(1 << bit)
static uint16_t atomic_fetch_and_u16(volatile uint16_t *dest, uint16_t val)
Atomic version of *dest &= val
static uint8_t atomic_fetch_sub_u8(volatile uint8_t *dest, uint8_t subtrahend)
Atomically subtract a value from a given value.
static uint8_t atomic_fetch_xor_u8(volatile uint8_t *dest, uint8_t val)
Atomic version of *dest ^= val
static uint32_t atomic_fetch_and_u32(volatile uint32_t *dest, uint32_t val)
Atomic version of *dest &= val
static uint64_t semi_atomic_fetch_or_u64(volatile uint64_t *dest, uint64_t val)
Semi-atomic version of *dest |= val
static uint32_t semi_atomic_fetch_or_u32(volatile uint32_t *dest, uint32_t val)
Semi-atomic version of *dest |= val
#define ATOMIC_STORE_IMPL(name, type)
Generates a static inline function implementing atomic_store_u<width>()
static uint64_t semi_atomic_fetch_xor_u64(volatile uint64_t *dest, uint64_t val)
Semi-atomic version of *dest ^= val
static uint64_t atomic_load_u64(const volatile uint64_t *var)
Load an uint64_t atomically.
static uint64_t atomic_fetch_and_u64(volatile uint64_t *dest, uint64_t val)
Atomic version of *dest &= val
static void atomic_store_u64(volatile uint64_t *dest, uint64_t val)
Store an uint64_t atomically.
uint64_t mask
Bitmask used for setting the bit.
static void atomic_set_bit_u16(atomic_bit_u16_t bit)
Atomic version of *dest |= (1 << bit)
static void atomic_clear_bit_u64(atomic_bit_u64_t bit)
Atomic version of *dest &= ~(1 << bit)
static uint32_t atomic_fetch_add_u32(volatile uint32_t *dest, uint32_t summand)
Atomically add a value onto a given value.
static uint32_t semi_atomic_fetch_sub_u32(volatile uint32_t *dest, uint32_t subtrahend)
Semi-atomically subtract a value from a given value.
static uint8_t semi_atomic_fetch_or_u8(volatile uint8_t *dest, uint8_t val)
Semi-atomic version of *dest |= val
static uint32_t atomic_fetch_sub_u32(volatile uint32_t *dest, uint32_t subtrahend)
Atomically subtract a value from a given value.
static uint8_t semi_atomic_fetch_and_u8(volatile uint8_t *dest, uint8_t val)
Semi-atomic version of *dest &= val
static uint64_t atomic_fetch_or_u64(volatile uint64_t *dest, uint64_t val)
Atomic version of *dest |= val
#define ATOMIC_LOAD_IMPL(name, type)
Generates a static inline function implementing atomic_load_u<width>()
static uint32_t semi_atomic_fetch_and_u32(volatile uint32_t *dest, uint32_t val)
Semi-atomic version of *dest &= val
static void atomic_clear_bit_u16(atomic_bit_u16_t bit)
Atomic version of *dest &= ~(1 << bit)
static uint64_t atomic_fetch_xor_u64(volatile uint64_t *dest, uint64_t val)
Atomic version of *dest ^= val
static uint16_t semi_atomic_fetch_and_u16(volatile uint16_t *dest, uint16_t val)
Semi-atomic version of *dest &= val
static uint8_t atomic_fetch_add_u8(volatile uint8_t *dest, uint8_t summand)
Atomically add a value onto a given value.
static uint32_t semi_atomic_fetch_add_u32(volatile uint32_t *dest, uint32_t summand)
Semi-atomically add a value onto a given value.
static void atomic_set_bit_u64(atomic_bit_u64_t bit)
Atomic version of *dest |= (1 << bit)
static uint8_t atomic_fetch_or_u8(volatile uint8_t *dest, uint8_t val)
Atomic version of *dest |= val
static atomic_bit_u32_t atomic_bit_u32(volatile uint32_t *dest, uint8_t bit)
Create a reference to a bit in an uint32_t
static uint16_t atomic_fetch_or_u16(volatile uint16_t *dest, uint16_t val)
Atomic version of *dest |= val