1#ifndef LIBCLOD_ATOMIC_H
2#define LIBCLOD_ATOMIC_H
10static_assert(__GCC_ATOMIC_INT_LOCK_FREE == 2,
"Locking alternatives are not portable across languages.");
12static inline uint32_t atomic_beu32_load(
const uint8_t *ptr) {
13 assert((uintptr_t)ptr % 4 == 0);
14 uint32_t val = __atomic_load_n((uint32_t*)ptr, __ATOMIC_SEQ_CST);
15 return beu32_dec((uint8_t*)&val);
18static inline void atomic_beu32_store(uint8_t *ptr, uint32_t val) {
19 assert((uintptr_t)ptr % 4 == 0);
21 beu32_enc((uint8_t*)&be, val);
22 __atomic_store_n((uint32_t*)ptr, be, __ATOMIC_SEQ_CST);
25static inline bool atomic_beu32_cas(uint8_t *ptr, uint32_t *expected, uint32_t desired) {
26 assert((uintptr_t)ptr % 4 == 0);
27 uint32_t expected_be, desired_be;
28 beu32_enc((uint8_t*)&expected_be, *expected);
29 beu32_enc((uint8_t*)&desired_be, desired);
30 const bool success = __atomic_compare_exchange_n((uint32_t*)ptr, &expected_be, desired_be,
false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
32 *expected = beu32_dec((uint8_t*)&expected_be);
37static inline uint32_t atomic_beu32_add(uint8_t *ptr, uint32_t delta) {
38 assert((uintptr_t)ptr % 4 == 0);
39 uint32_t val = atomic_beu32_load(ptr);
40 while (!atomic_beu32_cas(ptr, &val, val + delta)) {}
44static inline uint32_t atomic_beu32_sub(uint8_t *ptr, uint32_t delta) {
45 assert((uintptr_t)ptr % 4 == 0);
46 uint32_t val = atomic_beu32_load(ptr);
47 while (!atomic_beu32_cas(ptr, &val, val - delta)) {}
52#error "Atomic methods not implemented for this compiler"