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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
#ifndef _AL_ATOMIC_H
#define _AL_ATOMIC_H
#include "lib.h"
#include <c89atomic.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 AL_PASTER_EVALUATOR(X, Y) X##_##Y
#define AL_PASTER(X, Y) AL_PASTER_EVALUATOR(X, Y)
#define atomic(T) AL_PASTER(_al_atomic, T)
#define atomic_load(T) AL_PASTER(_al_atomic_load, T)
#define atomic_store(T) AL_PASTER(_al_atomic_store, T)
#define atomic_add(T) AL_PASTER(_al_atomic_add, T)
#define atomic_compare_and_swap(T) AL_PASTER(_al_atomic_compare_and_swap, T)
#define atomic_sub(T) AL_PASTER(_al_atomic_sub, 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 atomic_load(T)(atomic(T) *a, s32 order) \
{ \
return c89atomic_load_explicit_##S(a, order); \
} \
static inline void atomic_store(T)(atomic(T) *a, T value, s32 order) \
{ \
c89atomic_store_explicit_##S(a, value, order); \
} \
static inline T atomic_compare_and_swap(T)(atomic(T) *a, T expected, T desired) \
{ \
return c89atomic_compare_and_swap_##S(a, expected, desired); \
}
#define AL_ATOMIC_DEFINE_EXT(T, C, S) \
static inline T atomic_add(T)(atomic(T) *a, T value, s32 order) \
{ \
return c89atomic_fetch_add_explicit_##S(a, value, order); \
} \
static inline T atomic_sub(T)(atomic(T) *a, T value, s32 order) \
{ \
return c89atomic_fetch_sub_explicit_##S(a, value, order); \
}
#if defined C89ATOMIC_64BIT
AL_ATOMIC_DEFINE(size_t, uint64, 64)
AL_ATOMIC_DEFINE(ptrdiff_t, int64, i64)
#elif defined C89ATOMIC_32BIT
AL_ATOMIC_DEFINE(size_t, uint32, 32)
AL_ATOMIC_DEFINE(ptrdiff_t, int32, i32)
#endif
AL_ATOMIC_DEFINE(u64, uint64, 64);
AL_ATOMIC_DEFINE_EXT(u64, uint64, 64);
AL_ATOMIC_DEFINE(s64, int64, i64);
AL_ATOMIC_DEFINE(u32, uint32, 32);
AL_ATOMIC_DEFINE_EXT(u32, uint32, 32);
AL_ATOMIC_DEFINE(s32, int32, i32);
AL_ATOMIC_DEFINE_EXT(s32, int32, i32);
AL_ATOMIC_DEFINE(u16, uint16, 16);
AL_ATOMIC_DEFINE_EXT(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);
AL_ATOMIC_DEFINE(bool, bool, 32);
static inline f32 _al_atomic_add_f32(atomic(f32) *a, f32 value, s32 order)
{
(void)a;
(void)value;
(void)order;
al_assert_and_return(0.f);
}
static inline f32 _al_atomic_sub_f32(atomic(f32) *a, f32 value, s32 order)
{
(void)a;
(void)value;
(void)order;
al_assert_and_return(0.f);
}
#endif // _AL_ATOMIC_H
|