summaryrefslogtreecommitdiff
path: root/include/al/atomic.h
blob: 594413ccfbfcf99c2818d467d39a8d98417ee4e1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#ifndef _AL_ATOMIC_H
#define _AL_ATOMIC_H

#include <c89atomic.h>

#include "types.h"

#define AL_ATOMIC_RELAXED c89atomic_memory_order_relaxed
#define AL_ATOMIC_CONSUME c89atomic_memory_order_consume
#define AL_ATOMIC_ACQUIRE c89atomic_memory_order_acquire
#define AL_ATOMIC_RELEASE c89atomic_memory_order_release
#define AL_ATOMIC_ACQ_REL c89atomic_memory_order_acq_rel
#define AL_ATOMIC_SEQ_CST c89atomic_memory_order_seq_cst

#define atomic(T) _al_atomic_##T

#define al_atomic_load(T) _al_atomic_load_##T
#define al_atomic_store(T) _al_atomic_store_##T
#define al_atomic_add(T) _al_atomic_add_##T
#define al_atomic_sub(T) _al_atomic_sub_##T
#define al_atomic_compare_and_swap(T) _al_atomic_compare_and_swap_##T

// Special case for pointers.
#define _al_atomic_load_void(p, order) c89atomic_load_explicit_ptr((volatile void **)p, order)
#define _al_atomic_store_void(p, v, order) c89atomic_store_explicit_ptr((volatile void **)p, (void *)v, order)

// c89atomic compat.
typedef f64 c89atomic_f64;
typedef f32 c89atomic_f32;

#define AL_ATOMIC_DEFINE(T, C, S) \
    typedef c89atomic_##C atomic(T); \
    static inline T al_atomic_load(T)(atomic(T) *a, int order) \
    { \
        return c89atomic_load_explicit_##S(a, order); \
    } \
    static inline void al_atomic_store(T)(atomic(T) *a, T value, int order) \
    { \
        c89atomic_store_explicit_##S(a, value, order); \
    } \
    static inline T al_atomic_add(T)(atomic(T) *a, T value, int order) \
    { \
        return c89atomic_fetch_add_explicit_##S(a, value, order); \
    } \
    static inline T al_atomic_sub(T)(atomic(T) *a, T value, int order) \
    { \
        return c89atomic_fetch_sub_explicit_##S(a, value, order); \
    } \
    static inline T al_atomic_compare_and_swap(T)(atomic(T) *a, T expected, T desired) \
    { \
        return c89atomic_compare_and_swap_##S(a, expected, desired); \
    }

#if defined C89ATOMIC_64BIT
AL_ATOMIC_DEFINE(size_t, uint64, 64)
#elif defined C89ATOMIC_32BIT
AL_ATOMIC_DEFINE(size_t, uint32, 32)
#endif
AL_ATOMIC_DEFINE(u64, uint64, 64);
AL_ATOMIC_DEFINE(s64, int64, i64);
AL_ATOMIC_DEFINE(u32, uint32, 32);
AL_ATOMIC_DEFINE(s32, int32, i32);
AL_ATOMIC_DEFINE(u16, uint16, 16);
AL_ATOMIC_DEFINE(s16, int16, i16);
AL_ATOMIC_DEFINE(u8, uint8, 8);
AL_ATOMIC_DEFINE(s8, int8, i8);
AL_ATOMIC_DEFINE(f64, f64, f64);
AL_ATOMIC_DEFINE(f32, f32, f32);

#endif // _AL_ATOMIC_H