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