rcutils  master
C API providing common utilities and data structures.
stdatomic_helper.h
Go to the documentation of this file.
1 // Copyright 2015 Open Source Robotics Foundation, Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef RCUTILS__STDATOMIC_HELPER_H_
16 #define RCUTILS__STDATOMIC_HELPER_H_
17 
18 #include <stdbool.h>
19 #include <stddef.h>
20 #include <stdint.h>
21 
22 // disable unused function warnings within this file, due to inline in a header
23 #if !defined(_WIN32)
24 # pragma GCC diagnostic push
25 # if defined(__clang__)
26 # pragma clang diagnostic ignored "-Wunused-function"
27 # endif
28 #endif
29 
30 #if !defined(_WIN32)
31 
32 // The my__has_feature avoids a preprocessor error when you check for it and
33 // use it on the same line below.
34 #if defined(__has_feature)
35 #define my__has_feature(...) __has_feature(__VAR_ARGS__)
36 #else
37 #define my__has_feature(...) 0
38 #endif
39 
40 #if !defined(__clang__) && defined(__GNUC__) && __GNUC__ <= 4 && __GNUC_MINOR__ <= 9
41 // If GCC and below GCC-4.9, use the compatability header.
43 #else // !defined(__clang__) && defined(__GNUC__) && __GNUC__ <= 4 && __GNUC_MINOR__ <= 9
44 # if __cplusplus
45 // NOLINTNEXTLINE
46 # error "cannot be used with C++ due to a conflict with the C++ <atomic> header, see: p0943r1"
47 // See: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0943r1.html"
48 # else
49 # if defined(__has_feature) && !my__has_feature(c_atomic)
50 // If Clang and no c_atomics (true for some older versions), use the compatability header.
52 # else
53 # include <stdatomic.h>
54 # endif
55 # endif
56 #endif // !defined(__clang__) && defined(__GNUC__) && __GNUC__ <= 4 && __GNUC_MINOR__ <= 9
57 
58 #define rcutils_atomic_load(object, out) (out) = atomic_load(object)
59 
60 #define rcutils_atomic_compare_exchange_strong(object, out, expected, desired) \
61  (out) = atomic_compare_exchange_strong(object, expected, desired)
62 
63 #define rcutils_atomic_exchange(object, out, desired) (out) = atomic_exchange(object, desired)
64 
65 #define rcutils_atomic_store(object, desired) atomic_store(object, desired)
66 
67 #define rcutils_atomic_fetch_add(object, out, arg) (out) = atomic_fetch_add(object, arg)
68 
69 #else // !defined(_WIN32)
70 
72 
73 #define rcutils_atomic_load(object, out) rcutils_win32_atomic_load(object, out)
74 
75 #define rcutils_atomic_compare_exchange_strong(object, out, expected, desired) \
76  rcutils_win32_atomic_compare_exchange_strong(object, out, expected, desired)
77 
78 #define rcutils_atomic_exchange(object, out, desired) \
79  rcutils_win32_atomic_exchange(object, out, desired)
80 
81 #define rcutils_atomic_store(object, desired) rcutils_win32_atomic_store(object, desired)
82 
83 #define rcutils_atomic_fetch_add(object, out, arg) rcutils_win32_atomic_fetch_add(object, out, arg)
84 
85 #endif // !defined(_WIN32)
86 
87 static inline bool
88 rcutils_atomic_load_bool(atomic_bool * a_bool)
89 {
90  bool result = false;
91  rcutils_atomic_load(a_bool, result);
92  return result;
93 }
94 
95 static inline int64_t
96 rcutils_atomic_load_int64_t(atomic_int_least64_t * a_int64_t)
97 {
98  int64_t result = 0;
99  rcutils_atomic_load(a_int64_t, result);
100  return result;
101 }
102 
103 static inline uint64_t
104 rcutils_atomic_load_uint64_t(atomic_uint_least64_t * a_uint64_t)
105 {
106  uint64_t result = 0;
107  rcutils_atomic_load(a_uint64_t, result);
108  return result;
109 }
110 
111 static inline uintptr_t
112 rcutils_atomic_load_uintptr_t(atomic_uintptr_t * a_uintptr_t)
113 {
114  uintptr_t result = 0;
115  rcutils_atomic_load(a_uintptr_t, result);
116  return result;
117 }
118 
119 static inline bool
120 rcutils_atomic_compare_exchange_strong_uint_least64_t(
121  atomic_uint_least64_t * a_uint_least64_t, uint64_t * expected, uint64_t desired)
122 {
123  bool result;
124 #if defined(__clang__)
125 # pragma clang diagnostic push
126  // we know it's a gnu feature, but clang supports it, so suppress pedantic warning
127 # pragma clang diagnostic ignored "-Wgnu-statement-expression"
128 #endif
129  rcutils_atomic_compare_exchange_strong(a_uint_least64_t, result, expected, desired);
130 #if defined(__clang__)
131 # pragma clang diagnostic pop
132 #endif
133  return result;
134 }
135 
136 static inline bool
137 rcutils_atomic_exchange_bool(atomic_bool * a_bool, bool desired)
138 {
139  bool result;
140  rcutils_atomic_exchange(a_bool, result, desired);
141  return result;
142 }
143 
144 static inline int64_t
145 rcutils_atomic_exchange_int64_t(atomic_int_least64_t * a_int64_t, int64_t desired)
146 {
147  int64_t result;
148  rcutils_atomic_exchange(a_int64_t, result, desired);
149  return result;
150 }
151 
152 static inline uint64_t
153 rcutils_atomic_exchange_uint64_t(atomic_uint_least64_t * a_uint64_t, uint64_t desired)
154 {
155  uint64_t result;
156  rcutils_atomic_exchange(a_uint64_t, result, desired);
157  return result;
158 }
159 
160 static inline uintptr_t
161 rcutils_atomic_exchange_uintptr_t(atomic_uintptr_t * a_uintptr_t, uintptr_t desired)
162 {
163  uintptr_t result;
164  rcutils_atomic_exchange(a_uintptr_t, result, desired);
165  return result;
166 }
167 
168 static inline uint64_t
169 rcutils_atomic_fetch_add_uint64_t(atomic_uint_least64_t * a_uint64_t, uint64_t arg)
170 {
171  uint64_t result;
172  rcutils_atomic_fetch_add(a_uint64_t, result, arg);
173  return result;
174 }
175 
176 #if !defined(_WIN32)
177 # pragma GCC diagnostic pop
178 #endif
179 
180 #endif // RCUTILS__STDATOMIC_HELPER_H_
#define rcutils_atomic_fetch_add(object, out, arg)
Definition: stdatomic_helper.h:67
#define rcutils_atomic_exchange(object, out, desired)
Definition: stdatomic_helper.h:63
#define rcutils_atomic_compare_exchange_strong(object, out, expected, desired)
Definition: stdatomic_helper.h:60
#define rcutils_atomic_load(object, out)
Definition: stdatomic_helper.h:58