librfn
An ad-hoc utility library
atomic.h
Go to the documentation of this file.
1 /*
2  * atomic.h
3  *
4  * Part of librfn (a general utility library from redfelineninja.org.uk)
5  *
6  * Copyright (C) 2013 Daniel Thompson <daniel@redfelineninja.org.uk>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as published
10  * by the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  */
13 
22 #ifndef RF_ATOMIC_H_
23 #define RF_ATOMIC_H_
24 
25 #include <stdint.h>
26 
27 /*
28  * Atomic is deliberately not presented as a doxygen module. It should be
29  * considered as a bit of portability glue, not a module.
30  */
31 
32 #ifdef __STDC_NO_ATOMICS__
33 
34 #define _Atomic
35 
36 #define ATOMIC_VAR_INIT(c) c
37 
38 #define atomic_init(p, c) do { *(p) = (c); } while(0)
39 
40 #define memory_order_relaxed __ATOMIC_RELAXED
41 #define memory_order_consume __ATOMIC_CONSUME
42 #define memory_order_acquire __ATOMIC_ACQUIRE
43 #define memory_order_release __ATOMIC_RELEASE
44 #define memory_order_acq_rel __ATOMIC_ACQ_REL
45 #define memory_order_seq_cst __ATOMIC_SEQ_CST
46 
47 #define atomic_thread_fence(order) \
48  __atomic_thread_fence(order)
49 #define atomic_signal_fence(order) \
50  __atomic_signal_fence(order)
51 
52 typedef _Bool atomic_flag;
53 typedef char atomic_char;
54 typedef signed char atomic_schar;
55 typedef unsigned char atomic_uchar;
56 typedef int atomic_int;
57 typedef unsigned int atomic_uint;
58 
59 #define atomic_store(object, desired) \
60  __atomic_store_n(object, desired, __ATOMIC_SEQ_CST)
61 #define atomic_store_explicit(object, desired, order) \
62  __atomic_store_n(object, desired, order)
63 
64 #define atomic_load(object) \
65  __atomic_load_n(object, __ATOMIC_SEQ_CST)
66 #define atomic_load_explicit(object, order) \
67  __atomic_load_n(object, order)
68 
69 #define atomic_exchange(object, desired) \
70  __atomic_exchange_n(object, desired, __ATOMIC_SEQ_CST)
71 #define atomic_exchange_explicit(object, desired, order) \
72  __atomic_exchange_n(object, desired, order)
73 
74 #define atomic_compare_exchange_strong(object, expected, desired) \
75  __atomic_compare_exchange_n(object, expected, desired, false, \
76  __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
77 #define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
78  __atomic_compare_exchange_n(object, expected, desired, false, \
79  success, failure)
80 
81 #define atomic_compare_exchange_weak(object, expected, desired) \
82  __atomic_compare_exchange_n(object, expected, desired, true, \
83  __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
84 #define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
85  __atomic_compare_exchange_n(object, expected, desired, true, \
86  success, failure)
87 
88 #define atomic_fetch_add(object, operand) \
89  __atomic_fetch_add(object, operand, __ATOMIC_SEQ_CST)
90 #define atomic_fetch_add_explicit(object, operand, order) \
91  _atomic_fetch_add(object, operand, order)
92 
93 #define atomic_fetch_sub(object, operand) \
94  __atomic_fetch_sub(object, operand, __ATOMIC_SEQ_CST)
95 #define atomic_fetch_sub_explicit(object, operand, order) \
96  __atomic_fetch_sub(object, operand, order)
97 
98 #define atomic_fetch_or(object, operand) \
99  __atomic_fetch_or(object, operand, __ATOMIC_SEQ_CST)
100 #define atomic_fetch_or_explicit(object, operand, order) \
101  __atomic_fetch_or(object, operand, order)
102 
103 #define atomic_fetch_xor(object, operand) \
104  __atomic_fetch_xor(object, operand, __ATOMIC_SEQ_CST)
105 #define atomic_fetch_xor_explicit(object, operand, order) \
106  __atomic_fetch_xor(object, operand, order)
107 
108 #define atomic_fetch_and(object, operand) \
109  __atomic_fetch_and(object, operand, __ATOMIC_SEQ_CST)
110 #define atomic_fetch_and_explicit(object, operand, order) \
111  __atomic_fetch_and(object, operand, order)
112 
113 #define atomic_flag_test_and_set(object) \
114  __atomic_test_and_set(object, __ATOMIC_SEQ_CST)
115 #define atomic_flag_test_and_set_explicit(object, order) \
116  __atomic_test_and_set(object, order)
117 
118 #define atomic_flag_clear(object) \
119  __atomic_clear(object, __ATOMIC_SEQ_CST)
120 #define atomic_flag_clear_explicit(object, order) \
121  __atomic_clear(object, order)
122 
123 #else /* __STDC_NO_ATOMICS__ */
124 
125 #ifndef __cplusplus
126 #include <stdatomic.h>
127 #else
128 /*
129  * libgcc's stdatomic.h (as of 4.9) doesn't work from C++. This workaround is a
130  * hack and isn't anything like as portable as it looks (because it confuses
131  * size and alignment). However for most systems it is enough to allow C++ to
132  * pack structures containing atomics the same way as the C compiler. This
133  * makes it possible to use APIs linked to the structures from C++.
134  */
135 typedef char atomic_uchar __attribute__((aligned(SIZEOF_ATOMIC_UCHAR)));
136 typedef unsigned int atomic_uint __attribute__((aligned(SIZEOF_ATOMIC_UINT)));
137 #endif /* __cplusplus */
138 
139 #endif /* __STDC_NO_ATOMICS__ */
140 
141 #endif // RF_ATOMIC_H_
struct output_task __attribute__