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 <stdint.h>
20 
21 // disable unused function warnings within this file, due to inline in a header
22 #if !defined(_WIN32)
23 # pragma GCC diagnostic push
24 # if defined(__clang__)
25 # pragma clang diagnostic ignored "-Wunused-function"
26 # endif
27 #endif
28 
29 #if !defined(_WIN32)
30 
31 // The my__has_feature avoids a preprocessor error when you check for it and
32 // use it on the same line below.
33 #if defined(__has_feature)
34 #define my__has_feature(...) __has_feature(__VAR_ARGS__)
35 #else
36 #define my__has_feature(...) 0
37 #endif
38 
39 #if !defined(__clang__) && defined(__GNUC__) && __GNUC__ <= 4 && __GNUC_MINOR__ <= 9
40 // If GCC and below GCC-4.9, use the compatability header.
42 #else // !defined(__clang__) && defined(__GNUC__) && __GNUC__ <= 4 && __GNUC_MINOR__ <= 9
43 # if __cplusplus
44 // NOLINTNEXTLINE
45 # error "cannot be used with C++ due to a conflict with the C++ <atomic> header, see: p0943r1"
46 // See: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0943r1.html"
47 # else
48 # if defined(__has_feature) && !my__has_feature(c_atomic)
49 // If Clang and no c_atomics (true for some older versions), use the compatability header.
51 # else
52 # include <stdatomic.h>
53 # endif
54 # endif
55 #endif // !defined(__clang__) && defined(__GNUC__) && __GNUC__ <= 4 && __GNUC_MINOR__ <= 9
56 
57 #define rcutils_atomic_load(object, out) (out) = atomic_load(object)
58 
59 #define rcutils_atomic_compare_exchange_strong(object, out, expected, desired) \
60  (out) = atomic_compare_exchange_strong(object, expected, desired)
61 
62 #define rcutils_atomic_exchange(object, out, desired) (out) = atomic_exchange(object, desired)
63 
64 #define rcutils_atomic_store(object, desired) atomic_store(object, desired)
65 
66 #define rcutils_atomic_fetch_add(object, out, arg) (out) = atomic_fetch_add(object, arg)
67 
68 #else // !defined(_WIN32)
69 
71 
72 #define rcutils_atomic_load(object, out) rcutils_win32_atomic_load(object, out)
73 
74 #define rcutils_atomic_compare_exchange_strong(object, out, expected, desired) \
75  rcutils_win32_atomic_compare_exchange_strong(object, out, expected, desired)
76 
77 #define rcutils_atomic_exchange(object, out, desired) \
78  rcutils_win32_atomic_exchange(object, out, desired)
79 
80 #define rcutils_atomic_store(object, desired) rcutils_win32_atomic_store(object, desired)
81 
82 #define rcutils_atomic_fetch_add(object, out, arg) rcutils_win32_atomic_fetch_add(object, out, arg)
83 
84 #endif // !defined(_WIN32)
85 
86 static inline bool
87 rcutils_atomic_load_bool(atomic_bool * a_bool)
88 {
89  bool result = false;
90  rcutils_atomic_load(a_bool, result);
91  return result;
92 }
93 
94 static inline int64_t
95 rcutils_atomic_load_int64_t(atomic_int_least64_t * a_int64_t)
96 {
97  int64_t result = 0;
98  rcutils_atomic_load(a_int64_t, result);
99  return result;
100 }
101 
102 static inline uint64_t
103 rcutils_atomic_load_uint64_t(atomic_uint_least64_t * a_uint64_t)
104 {
105  uint64_t result = 0;
106  rcutils_atomic_load(a_uint64_t, result);
107  return result;
108 }
109 
110 static inline uintptr_t
111 rcutils_atomic_load_uintptr_t(atomic_uintptr_t * a_uintptr_t)
112 {
113  uintptr_t result = 0;
114  rcutils_atomic_load(a_uintptr_t, result);
115  return result;
116 }
117 
118 static inline bool
119 rcutils_atomic_compare_exchange_strong_uint_least64_t(
120  atomic_uint_least64_t * a_uint_least64_t, uint64_t * expected, uint64_t desired)
121 {
122  bool result;
123 #if defined(__clang__)
124 # pragma clang diagnostic push
125  // we know it's a gnu feature, but clang supports it, so suppress pedantic warning
126 # pragma clang diagnostic ignored "-Wgnu-statement-expression"
127 #endif
128  rcutils_atomic_compare_exchange_strong(a_uint_least64_t, result, expected, desired);
129 #if defined(__clang__)
130 # pragma clang diagnostic pop
131 #endif
132  return result;
133 }
134 
135 static inline bool
136 rcutils_atomic_exchange_bool(atomic_bool * a_bool, bool desired)
137 {
138  bool result;
139  rcutils_atomic_exchange(a_bool, result, desired);
140  return result;
141 }
142 
143 static inline int64_t
144 rcutils_atomic_exchange_int64_t(atomic_int_least64_t * a_int64_t, int64_t desired)
145 {
146  int64_t result;
147  rcutils_atomic_exchange(a_int64_t, result, desired);
148  return result;
149 }
150 
151 static inline uint64_t
152 rcutils_atomic_exchange_uint64_t(atomic_uint_least64_t * a_uint64_t, uint64_t desired)
153 {
154  uint64_t result;
155  rcutils_atomic_exchange(a_uint64_t, result, desired);
156  return result;
157 }
158 
159 static inline uintptr_t
160 rcutils_atomic_exchange_uintptr_t(atomic_uintptr_t * a_uintptr_t, uintptr_t desired)
161 {
162  uintptr_t result;
163  rcutils_atomic_exchange(a_uintptr_t, result, desired);
164  return result;
165 }
166 
167 static inline uint64_t
168 rcutils_atomic_fetch_add_uint64_t(atomic_uint_least64_t * a_uint64_t, uint64_t arg)
169 {
170  uint64_t result;
171  rcutils_atomic_fetch_add(a_uint64_t, result, arg);
172  return result;
173 }
174 
175 #if !defined(_WIN32)
176 # pragma GCC diagnostic pop
177 #endif
178 
179 #endif // RCUTILS__STDATOMIC_HELPER_H_
#define rcutils_atomic_fetch_add(object, out, arg)
Definition: stdatomic_helper.h:66
#define rcutils_atomic_exchange(object, out, desired)
Definition: stdatomic_helper.h:62
#define rcutils_atomic_compare_exchange_strong(object, out, expected, desired)
Definition: stdatomic_helper.h:59
#define rcutils_atomic_load(object, out)
Definition: stdatomic_helper.h:57