1#pragma once
2
3/*
4 * Miscellaneous helper macros
5 */
6
7#include <limits.h>
8#include <stdatomic.h>
9
10#ifdef __cplusplus
11extern "C" {
12#endif
13
14#define PW_LENGTH(array) (sizeof(array) / sizeof((array)[0]))
15/*
16 * Get array length
17 */
18
19static inline unsigned _pw_atomic_load(atomic_uint* p)
20{
21 return atomic_load_explicit(p, memory_order_relaxed);
22}
23
24static inline void _pw_atomic_store(atomic_uint* p, unsigned v)
25{
26 atomic_store_explicit(p, v, memory_order_relaxed);
27}
28
29#define _pw_atomic_add(p, v) \
30 __extension__ \
31 ({ \
32 unsigned prev = atomic_fetch_add_explicit((p), (v), memory_order_relaxed); \
33 if ((prev > UINT_MAX - (v))) { \
34 pw_panic("atomic_uint overflow %s:%u p=%p v=%u prev=%u\n", __FILE__, __LINE__, (void*) (p), prev, (v)); \
35 } \
36 prev; \
37 })
38
39#define _pw_atomic_sub(p, v) \
40 __extension__ \
41 ({ \
42 unsigned prev = atomic_fetch_sub_explicit((p), (v), memory_order_relaxed); \
43 if (prev < (v)) { \
44 pw_panic("atomic_uint underflow %s:%u p=%p v=%u prev=%u\n", __FILE__, __LINE__, (void*) (p), prev, (v)); \
45 } \
46 prev; \
47 })
48
49#ifdef __cplusplus
50}
51#endif