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_
76 #pragma warning(disable : 5105)
87 #define _Atomic(T) struct { T __val; }
93 #define ATOMIC_VAR_INIT(value) {.__val = (value)}
94 #define atomic_init(obj, value) do { \
95 (obj)->__val = (value); \
104 #ifndef __ATOMIC_RELAXED
105 #define __ATOMIC_RELAXED 0
107 #ifndef __ATOMIC_CONSUME
108 #define __ATOMIC_CONSUME 1
110 #ifndef __ATOMIC_ACQUIRE
111 #define __ATOMIC_ACQUIRE 2
113 #ifndef __ATOMIC_RELEASE
114 #define __ATOMIC_RELEASE 3
116 #ifndef __ATOMIC_ACQ_REL
117 #define __ATOMIC_ACQ_REL 4
119 #ifndef __ATOMIC_SEQ_CST
120 #define __ATOMIC_SEQ_CST 5
146 #define atomic_thread_fence(order) MemoryBarrier()
147 #define atomic_signal_fence(order) _ReadWriteBarrier()
153 #define atomic_is_lock_free(obj) (sizeof((obj)->__val) <= sizeof(void *))
159 typedef _Atomic (_Bool) atomic_bool;
160 typedef _Atomic (
char) atomic_char;
161 typedef _Atomic (
signed char) atomic_schar;
162 typedef _Atomic (
unsigned char) atomic_uchar;
163 typedef _Atomic (
short) atomic_short;
164 typedef _Atomic (
unsigned short) atomic_ushort;
165 typedef _Atomic (
int) atomic_int;
166 typedef _Atomic (
unsigned int) atomic_uint;
167 typedef _Atomic (
long) atomic_long;
168 typedef _Atomic (
unsigned long) atomic_ulong;
169 typedef _Atomic (
long long) atomic_llong;
170 typedef _Atomic (
unsigned long long) atomic_ullong;
172 typedef _Atomic (char16_t) atomic_char16_t;
173 typedef _Atomic (char32_t) atomic_char32_t;
174 typedef _Atomic (
wchar_t) atomic_wchar_t;
175 typedef _Atomic (int_least8_t) atomic_int_least8_t;
176 typedef _Atomic (uint_least8_t) atomic_uint_least8_t;
178 typedef _Atomic (int_least16_t) atomic_int_least16_t;
179 typedef _Atomic (uint_least16_t) atomic_uint_least16_t;
180 typedef _Atomic (int_least32_t) atomic_int_least32_t;
181 typedef _Atomic (uint_least32_t) atomic_uint_least32_t;
182 typedef _Atomic (int_least64_t) atomic_int_least64_t;
183 typedef _Atomic (uint_least64_t) atomic_uint_least64_t;
185 typedef _Atomic (int_fast8_t) atomic_int_fast8_t;
186 typedef _Atomic (uint_fast8_t) atomic_uint_fast8_t;
188 typedef _Atomic (int_fast16_t) atomic_int_fast16_t;
189 typedef _Atomic (uint_fast16_t) atomic_uint_fast16_t;
190 typedef _Atomic (int_fast32_t) atomic_int_fast32_t;
191 typedef _Atomic (uint_fast32_t) atomic_uint_fast32_t;
192 typedef _Atomic (int_fast64_t) atomic_int_fast64_t;
193 typedef _Atomic (uint_fast64_t) atomic_uint_fast64_t;
194 typedef _Atomic (intptr_t) atomic_intptr_t;
195 typedef _Atomic (uintptr_t) atomic_uintptr_t;
196 typedef _Atomic (
size_t) atomic_size_t;
197 typedef _Atomic (ptrdiff_t) atomic_ptrdiff_t;
198 typedef _Atomic (intmax_t) atomic_intmax_t;
199 typedef _Atomic (uintmax_t) atomic_uintmax_t;
201 #ifdef ROS_PACKAGE_NAME
202 #define _RCUTILS_PACKAGE_NAME ROS_PACKAGE_NAME
204 #define _RCUTILS_PACKAGE_NAME "<Unknown Package>"
215 #define rcutils_win32_atomic_compare_exchange_strong(object, out, expected, desired) \
216 __pragma(warning(push)) \
217 __pragma(warning(disable: 4244)) \
218 __pragma(warning(disable: 4047)) \
219 __pragma(warning(disable: 4024)) \
221 switch (sizeof(out)) { \
222 case sizeof(uint64_t): \
223 out = InterlockedCompareExchange64((LONGLONG *) object, desired, *expected); \
225 case sizeof(uint32_t): \
226 out = _InterlockedCompareExchange((LONG *) object, desired, *expected); \
228 case sizeof(uint16_t): \
229 out = _InterlockedCompareExchange16((SHORT *) object, desired, *expected); \
231 case sizeof(uint8_t): \
232 out = _InterlockedCompareExchange8((char *) object, desired, *expected); \
235 RCUTILS_LOG_ERROR_NAMED( \
236 _RCUTILS_PACKAGE_NAME, "Unsupported integer type in atomic_compare_exchange_strong"); \
241 __pragma(warning(pop))
243 #define rcutils_win32_atomic_compare_exchange_weak(object, out, expected, desired) \
244 rcutils_win32_atomic_compare_exchange_strong(object, out, expected, desired)
246 #define rcutils_win32_atomic_exchange(object, out, desired) \
247 __pragma(warning(push)) \
248 __pragma(warning(disable: 4244)) \
249 __pragma(warning(disable: 4047)) \
250 __pragma(warning(disable: 4024)) \
252 switch (sizeof(out)) { \
253 case sizeof(uint64_t): \
254 out = InterlockedExchange64((LONGLONG *) object, desired); \
256 case sizeof(uint32_t): \
257 out = _InterlockedExchange((LONG *) object, desired); \
259 case sizeof(uint16_t): \
260 out = _InterlockedExchange16((SHORT *) object, desired); \
262 case sizeof(uint8_t): \
263 out = _InterlockedExchange8((char *) object, desired); \
266 RCUTILS_LOG_ERROR_NAMED( \
267 _RCUTILS_PACKAGE_NAME, "Unsupported integer type in atomic_exchange_strong"); \
272 __pragma(warning(pop))
274 #define rcutils_win32_atomic_fetch_add(object, out, operand) \
275 __pragma(warning(push)) \
276 __pragma(warning(disable: 4244)) \
277 __pragma(warning(disable: 4047)) \
278 __pragma(warning(disable: 4024)) \
280 switch (sizeof(out)) { \
281 case sizeof(uint64_t): \
282 out = InterlockedExchangeAdd64((LONGLONG *) object, operand); \
284 case sizeof(uint32_t): \
285 out = _InterlockedExchangeAdd((LONG *) object, operand); \
287 case sizeof(uint16_t): \
288 out = _InterlockedExchangeAdd16((SHORT *) object, operand); \
290 case sizeof(uint8_t): \
291 out = _InterlockedExchangeAdd8((char *) object, operand); \
294 RCUTILS_LOG_ERROR_NAMED( \
295 _RCUTILS_PACKAGE_NAME, "Unsupported integer type in atomic_fetch_add"); \
300 __pragma(warning(pop))
302 #define rcutils_win32_atomic_fetch_and(object, out, operand) \
303 __pragma(warning(push)) \
304 __pragma(warning(disable: 4244)) \
305 __pragma(warning(disable: 4047)) \
306 __pragma(warning(disable: 4024)) \
308 switch (sizeof(out)) { \
309 case sizeof(uint64_t): \
310 out = InterlockedAnd64((LONGLONG *) object, operand); \
312 case sizeof(uint32_t): \
313 out = _InterlockedAnd((LONG *) object, operand); \
315 case sizeof(uint16_t): \
316 out = _InterlockedAnd16((SHORT *) object, operand); \
318 case sizeof(uint8_t): \
319 out = _InterlockedAnd8((char *) object, operand); \
322 RCUTILS_LOG_ERROR_NAMED( \
323 _RCUTILS_PACKAGE_NAME, "Unsupported integer type in atomic_fetch_and"); \
328 __pragma(warning(pop))
330 #define rcutils_win32_atomic_fetch_or(object, out, operand) \
331 __pragma(warning(push)) \
332 __pragma(warning(disable: 4244)) \
333 __pragma(warning(disable: 4047)) \
334 __pragma(warning(disable: 4024)) \
336 switch (sizeof(out)) { \
337 case sizeof(uint64_t): \
338 out = InterlockedOr64((LONGLONG *) object, operand); \
340 case sizeof(uint32_t): \
341 out = _InterlockedOr((LONG *) object, operand); \
343 case sizeof(uint16_t): \
344 out = _InterlockedOr16((SHORT *) object, operand); \
346 case sizeof(uint8_t): \
347 out = _InterlockedOr8((char *) object, operand); \
350 RCUTILS_LOG_ERROR_NAMED( \
351 _RCUTILS_PACKAGE_NAME, "Unsupported integer type in atomic_fetch_or"); \
356 __pragma(warning(pop))
358 #define rcutils_win32_atomic_fetch_sub(object, out, operand) \
359 rcutils_win32_atomic_fetch_add(object, out, -(operand))
361 #define rcutils_win32_atomic_fetch_xor(object, out, operand) \
362 __pragma(warning(push)) \
363 __pragma(warning(disable: 4244)) \
364 __pragma(warning(disable: 4047)) \
365 __pragma(warning(disable: 4024)) \
367 switch (sizeof(out)) { \
368 case sizeof(uint64_t): \
369 out = InterlockedXor64((LONGLONG *) object, operand); \
371 case sizeof(uint32_t): \
372 out = _InterlockedXor((LONG *) object, operand); \
374 case sizeof(uint16_t): \
375 out = _InterlockedXor16((SHORT *) object, operand); \
377 case sizeof(uint8_t): \
378 out = _InterlockedXor8((char *) object, operand); \
381 RCUTILS_LOG_ERROR_NAMED( \
382 _RCUTILS_PACKAGE_NAME, "Unsupported integer type in atomic_fetch_xor"); \
387 __pragma(warning(pop))
389 #define rcutils_win32_atomic_load(object, out) \
390 __pragma(warning(push)) \
391 __pragma(warning(disable: 4244)) \
392 __pragma(warning(disable: 4047)) \
393 __pragma(warning(disable: 4024)) \
395 switch (sizeof(out)) { \
396 case sizeof(uint64_t): \
397 out = InterlockedExchangeAdd64((LONGLONG *) object, 0); \
399 case sizeof(uint32_t): \
400 out = _InterlockedExchangeAdd((LONG *) object, 0); \
402 case sizeof(uint16_t): \
403 out = _InterlockedExchangeAdd16((SHORT *) object, 0); \
405 case sizeof(uint8_t): \
406 out = _InterlockedExchangeAdd8((char *) object, 0); \
409 RCUTILS_LOG_ERROR_NAMED( \
410 _RCUTILS_PACKAGE_NAME, "Unsupported integer type in atomic_load"); \
415 __pragma(warning(pop))
419 #define rcutils_win32_atomic_store(object, desired) \
422 (object)->__val = (desired); \
444 #endif // RCUTILS__STDATOMIC_HELPER__WIN32__STDATOMIC_H_