Skip to content

Commit

Permalink
fixes to support including in c++ and fetch_add (#129)
Browse files Browse the repository at this point in the history
* fixes to support including in c++ and fetch_add

Signed-off-by: William Woodall <william@osrfoundation.org>

* style and bug in fetch_add macro

* give-up on interoperating with C++, improve error

Signed-off-by: William Woodall <william@osrfoundation.org>

* style
  • Loading branch information
wjwwood authored Nov 30, 2018
1 parent 670a3e3 commit 17d018b
Showing 1 changed file with 58 additions and 9 deletions.
67 changes: 58 additions & 9 deletions include/rcutils/stdatomic_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,45 @@
#ifndef RCUTILS__STDATOMIC_HELPER_H_
#define RCUTILS__STDATOMIC_HELPER_H_

#if !defined(_WIN32)
#include <stdbool.h>
#include <stdint.h>

#if defined(__GNUC__) && __GNUC__ <= 4 && __GNUC_MINOR__ <= 9
// If GCC and below GCC-4.9, use the compatability header.
#include "stdatomic_helper/gcc/stdatomic.h"
#elif defined(__clang__) && defined(__has_feature)
#if !__has_feature(c_atomic)
// If Clang and no c_atomics (true for some older versions), use the compatability header.
#include "stdatomic_helper/gcc/stdatomic.h"
// disable unused function warnings within this file, due to inline in a header
#if !defined(_WIN32)
# pragma GCC diagnostic push
# if defined(__clang__)
# pragma clang diagnostic ignored "-Wunused-function"
# endif
#endif

#if !defined(_WIN32)

// The my__has_feature avoids a preprocessor error when you check for it and
// use it on the same line below.
#if defined(__has_feature)
#define my__has_feature(...) __has_feature(__VAR_ARGS__)
#else
#include <stdatomic.h>
#define my__has_feature(...) 0
#endif

#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ <= 4 && __GNUC_MINOR__ <= 9
// If GCC and below GCC-4.9, use the compatability header.
# include "stdatomic_helper/gcc/stdatomic.h"
#else // !defined(__clang__) && defined(__GNUC__) && __GNUC__ <= 4 && __GNUC_MINOR__ <= 9
# if __cplusplus
// NOLINTNEXTLINE
# error "cannot be used with C++ due to a conflict with the C++ <atomic> header, see: p0943r1"
// See: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0943r1.html"
# else
# if defined(__has_feature) && !my__has_feature(c_atomic)
// If Clang and no c_atomics (true for some older versions), use the compatability header.
# include "stdatomic_helper/gcc/stdatomic.h"
# else
# include <stdatomic.h>
# endif
# endif
#endif // !defined(__clang__) && defined(__GNUC__) && __GNUC__ <= 4 && __GNUC_MINOR__ <= 9

#define rcutils_atomic_load(object, out) (out) = atomic_load(object)

#define rcutils_atomic_compare_exchange_strong(object, out, expected, desired) \
Expand All @@ -38,6 +63,8 @@

#define rcutils_atomic_store(object, desired) atomic_store(object, desired)

#define rcutils_atomic_fetch_add(object, out, arg) (out) = atomic_fetch_add(object, arg)

#else // !defined(_WIN32)

#include "./stdatomic_helper/win32/stdatomic.h"
Expand All @@ -52,6 +79,8 @@

#define rcutils_atomic_store(object, desired) rcutils_win32_atomic_store(object, desired)

#define rcutils_atomic_fetch_add(object, out, arg) rcutils_win32_atomic_fetch_add(object, out, arg)

#endif // !defined(_WIN32)

static inline bool
Expand Down Expand Up @@ -91,7 +120,15 @@ rcutils_atomic_compare_exchange_strong_uint_least64_t(
atomic_uint_least64_t * a_uint_least64_t, uint64_t * expected, uint64_t desired)
{
bool result;
#if defined(__clang__)
# pragma clang diagnostic push
// we know it's a gnu feature, but clang supports it, so suppress pedantic warning
# pragma clang diagnostic ignored "-Wgnu-statement-expression"
#endif
rcutils_atomic_compare_exchange_strong(a_uint_least64_t, result, expected, desired);
#if defined(__clang__)
# pragma clang diagnostic pop
#endif
return result;
}

Expand Down Expand Up @@ -127,4 +164,16 @@ rcutils_atomic_exchange_uintptr_t(atomic_uintptr_t * a_uintptr_t, uintptr_t desi
return result;
}

static inline uint64_t
rcutils_atomic_fetch_add_uint64_t(atomic_uint_least64_t * a_uint64_t, uint64_t arg)
{
uint64_t result;
rcutils_atomic_fetch_add(a_uint64_t, result, arg);
return result;
}

#if !defined(_WIN32)
# pragma GCC diagnostic pop
#endif

#endif // RCUTILS__STDATOMIC_HELPER_H_

0 comments on commit 17d018b

Please sign in to comment.