60 #error "this stdatomic.h does not support your compiler"
61 #endif // !defined(_WIN32)
63 #ifndef RCUTILS__STDATOMIC_HELPER__WIN32__STDATOMIC_H_
64 #define RCUTILS__STDATOMIC_HELPER__WIN32__STDATOMIC_H_
75 #define _Atomic(T) struct { T __val; }
81 #define ATOMIC_VAR_INIT(value) {.__val = (value)}
82 #define atomic_init(obj, value) do { \
83 (obj)->__val = (value); \
92 #ifndef __ATOMIC_RELAXED
93 #define __ATOMIC_RELAXED 0
95 #ifndef __ATOMIC_CONSUME
96 #define __ATOMIC_CONSUME 1
98 #ifndef __ATOMIC_ACQUIRE
99 #define __ATOMIC_ACQUIRE 2
101 #ifndef __ATOMIC_RELEASE
102 #define __ATOMIC_RELEASE 3
104 #ifndef __ATOMIC_ACQ_REL
105 #define __ATOMIC_ACQ_REL 4
107 #ifndef __ATOMIC_SEQ_CST
108 #define __ATOMIC_SEQ_CST 5
134 #define atomic_thread_fence(order) MemoryBarrier()
135 #define atomic_signal_fence(order) _ReadWriteBarrier()
141 #define atomic_is_lock_free(obj) (sizeof((obj)->__val) <= sizeof(void *))
147 typedef _Atomic (_Bool) atomic_bool;
148 typedef _Atomic (
char) atomic_char;
149 typedef _Atomic (
signed char) atomic_schar;
150 typedef _Atomic (
unsigned char) atomic_uchar;
151 typedef _Atomic (
short) atomic_short;
152 typedef _Atomic (
unsigned short) atomic_ushort;
153 typedef _Atomic (
int) atomic_int;
154 typedef _Atomic (
unsigned int) atomic_uint;
155 typedef _Atomic (
long) atomic_long;
156 typedef _Atomic (
unsigned long) atomic_ulong;
157 typedef _Atomic (
long long) atomic_llong;
158 typedef _Atomic (
unsigned long long) atomic_ullong;
160 typedef _Atomic (char16_t) atomic_char16_t;
161 typedef _Atomic (char32_t) atomic_char32_t;
162 typedef _Atomic (
wchar_t) atomic_wchar_t;
163 typedef _Atomic (int_least8_t) atomic_int_least8_t;
164 typedef _Atomic (uint_least8_t) atomic_uint_least8_t;
166 typedef _Atomic (int_least16_t) atomic_int_least16_t;
167 typedef _Atomic (uint_least16_t) atomic_uint_least16_t;
168 typedef _Atomic (int_least32_t) atomic_int_least32_t;
169 typedef _Atomic (uint_least32_t) atomic_uint_least32_t;
170 typedef _Atomic (int_least64_t) atomic_int_least64_t;
171 typedef _Atomic (uint_least64_t) atomic_uint_least64_t;
173 typedef _Atomic (int_fast8_t) atomic_int_fast8_t;
174 typedef _Atomic (uint_fast8_t) atomic_uint_fast8_t;
176 typedef _Atomic (int_fast16_t) atomic_int_fast16_t;
177 typedef _Atomic (uint_fast16_t) atomic_uint_fast16_t;
178 typedef _Atomic (int_fast32_t) atomic_int_fast32_t;
179 typedef _Atomic (uint_fast32_t) atomic_uint_fast32_t;
180 typedef _Atomic (int_fast64_t) atomic_int_fast64_t;
181 typedef _Atomic (uint_fast64_t) atomic_uint_fast64_t;
182 typedef _Atomic (intptr_t) atomic_intptr_t;
183 typedef _Atomic (uintptr_t) atomic_uintptr_t;
184 typedef _Atomic (
size_t) atomic_size_t;
185 typedef _Atomic (ptrdiff_t) atomic_ptrdiff_t;
186 typedef _Atomic (intmax_t) atomic_intmax_t;
187 typedef _Atomic (uintmax_t) atomic_uintmax_t;
189 #ifdef ROS_PACKAGE_NAME
190 #define _RCUTILS_PACKAGE_NAME ROS_PACKAGE_NAME
192 #define _RCUTILS_PACKAGE_NAME "<Unknown Package>"
203 #define rcutils_win32_atomic_compare_exchange_strong(object, out, expected, desired) \
204 __pragma(warning(push)) \
205 __pragma(warning(disable: 4244)) \
206 __pragma(warning(disable: 4047)) \
207 __pragma(warning(disable: 4024)) \
209 switch (sizeof(out)) { \
210 case sizeof(uint64_t): \
211 out = InterlockedCompareExchange64((LONGLONG *) object, desired, *expected); \
213 case sizeof(uint32_t): \
214 out = _InterlockedCompareExchange((LONG *) object, desired, *expected); \
216 case sizeof(uint16_t): \
217 out = _InterlockedCompareExchange16((SHORT *) object, desired, *expected); \
219 case sizeof(uint8_t): \
220 out = _InterlockedCompareExchange8((char *) object, desired, *expected); \
223 RCUTILS_LOG_ERROR_NAMED( \
224 _RCUTILS_PACKAGE_NAME, "Unsupported integer type in atomic_compare_exchange_strong"); \
229 __pragma(warning(pop))
231 #define rcutils_win32_atomic_compare_exchange_weak(object, out, expected, desired) \
232 rcutils_win32_atomic_compare_exchange_strong(object, out, expected, desired)
234 #define rcutils_win32_atomic_exchange(object, out, desired) \
235 __pragma(warning(push)) \
236 __pragma(warning(disable: 4244)) \
237 __pragma(warning(disable: 4047)) \
238 __pragma(warning(disable: 4024)) \
240 switch (sizeof(out)) { \
241 case sizeof(uint64_t): \
242 out = InterlockedExchange64((LONGLONG *) object, desired); \
244 case sizeof(uint32_t): \
245 out = _InterlockedExchange((LONG *) object, desired); \
247 case sizeof(uint16_t): \
248 out = _InterlockedExchange16((SHORT *) object, desired); \
250 case sizeof(uint8_t): \
251 out = _InterlockedExchange8((char *) object, desired); \
254 RCUTILS_LOG_ERROR_NAMED( \
255 _RCUTILS_PACKAGE_NAME, "Unsupported integer type in atomic_exchange_strong"); \
260 __pragma(warning(pop))
262 #define rcutils_win32_atomic_fetch_add(object, out, operand) \
263 __pragma(warning(push)) \
264 __pragma(warning(disable: 4244)) \
265 __pragma(warning(disable: 4047)) \
266 __pragma(warning(disable: 4024)) \
268 switch (sizeof(out)) { \
269 case sizeof(uint64_t): \
270 out = InterlockedExchangeAdd64((LONGLONG *) object, operand); \
272 case sizeof(uint32_t): \
273 out = _InterlockedExchangeAdd((LONG *) object, operand); \
275 case sizeof(uint16_t): \
276 out = _InterlockedExchangeAdd16((SHORT *) object, operand); \
278 case sizeof(uint8_t): \
279 out = _InterlockedExchangeAdd8((char *) object, operand); \
282 RCUTILS_LOG_ERROR_NAMED( \
283 _RCUTILS_PACKAGE_NAME, "Unsupported integer type in atomic_fetch_add"); \
288 __pragma(warning(pop))
290 #define rcutils_win32_atomic_fetch_and(object, out, operand) \
291 __pragma(warning(push)) \
292 __pragma(warning(disable: 4244)) \
293 __pragma(warning(disable: 4047)) \
294 __pragma(warning(disable: 4024)) \
296 switch (sizeof(out)) { \
297 case sizeof(uint64_t): \
298 out = InterlockedAnd64((LONGLONG *) object, operand); \
300 case sizeof(uint32_t): \
301 out = _InterlockedAnd((LONG *) object, operand); \
303 case sizeof(uint16_t): \
304 out = _InterlockedAnd16((SHORT *) object, operand); \
306 case sizeof(uint8_t): \
307 out = _InterlockedAnd8((char *) object, operand); \
310 RCUTILS_LOG_ERROR_NAMED( \
311 _RCUTILS_PACKAGE_NAME, "Unsupported integer type in atomic_fetch_and"); \
316 __pragma(warning(pop))
318 #define rcutils_win32_atomic_fetch_or(object, out, operand) \
319 __pragma(warning(push)) \
320 __pragma(warning(disable: 4244)) \
321 __pragma(warning(disable: 4047)) \
322 __pragma(warning(disable: 4024)) \
324 switch (sizeof(out)) { \
325 case sizeof(uint64_t): \
326 out = InterlockedOr64((LONGLONG *) object, operand); \
328 case sizeof(uint32_t): \
329 out = _InterlockedOr((LONG *) object, operand); \
331 case sizeof(uint16_t): \
332 out = _InterlockedOr16((SHORT *) object, operand); \
334 case sizeof(uint8_t): \
335 out = _InterlockedOr8((char *) object, operand); \
338 RCUTILS_LOG_ERROR_NAMED( \
339 _RCUTILS_PACKAGE_NAME, "Unsupported integer type in atomic_fetch_or"); \
344 __pragma(warning(pop))
346 #define rcutils_win32_atomic_fetch_sub(object, out, operand) \
347 rcutils_win32_atomic_fetch_add(object, out, -(operand))
349 #define rcutils_win32_atomic_fetch_xor(object, out, operand) \
350 __pragma(warning(push)) \
351 __pragma(warning(disable: 4244)) \
352 __pragma(warning(disable: 4047)) \
353 __pragma(warning(disable: 4024)) \
355 switch (sizeof(out)) { \
356 case sizeof(uint64_t): \
357 out = InterlockedXor64((LONGLONG *) object, operand); \
359 case sizeof(uint32_t): \
360 out = _InterlockedXor((LONG *) object, operand); \
362 case sizeof(uint16_t): \
363 out = _InterlockedXor16((SHORT *) object, operand); \
365 case sizeof(uint8_t): \
366 out = _InterlockedXor8((char *) object, operand); \
369 RCUTILS_LOG_ERROR_NAMED( \
370 _RCUTILS_PACKAGE_NAME, "Unsupported integer type in atomic_fetch_xor"); \
375 __pragma(warning(pop))
377 #define rcutils_win32_atomic_load(object, out) \
378 __pragma(warning(push)) \
379 __pragma(warning(disable: 4244)) \
380 __pragma(warning(disable: 4047)) \
381 __pragma(warning(disable: 4024)) \
383 switch (sizeof(out)) { \
384 case sizeof(uint64_t): \
385 out = InterlockedExchangeAdd64((LONGLONG *) object, 0); \
387 case sizeof(uint32_t): \
388 out = _InterlockedExchangeAdd((LONG *) object, 0); \
390 case sizeof(uint16_t): \
391 out = _InterlockedExchangeAdd16((SHORT *) object, 0); \
393 case sizeof(uint8_t): \
394 out = _InterlockedExchangeAdd8((char *) object, 0); \
397 RCUTILS_LOG_ERROR_NAMED( \
398 _RCUTILS_PACKAGE_NAME, "Unsupported integer type in atomic_load"); \
403 __pragma(warning(pop))
407 #define rcutils_win32_atomic_store(object, desired) \
410 (object)->__val = (desired); \
432 #endif // RCUTILS__STDATOMIC_HELPER__WIN32__STDATOMIC_H_