You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

compiler.h 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /*
  2. * compiler.h - compiler specific macros
  3. *
  4. * This software is distributed under a BSD-style license. See the
  5. * file "COPYING" in the toop-level directory of the distribution for details.
  6. */
  7. #ifndef _GPSD_COMPILER_H_
  8. #define _GPSD_COMPILER_H_
  9. /*
  10. * Tell GCC that we want thread-safe behavior with _REENTRANT;
  11. * in particular, errno must be thread-local.
  12. * Tell POSIX-conforming implementations with _POSIX_THREAD_SAFE_FUNCTIONS.
  13. * See http://www.unix.org/whitepapers/reentrant.html
  14. */
  15. #ifndef _REENTRANT
  16. #define _REENTRANT
  17. #endif
  18. #ifndef _POSIX_THREAD_SAFE_FUNCTIONS
  19. #define _POSIX_THREAD_SAFE_FUNCTIONS
  20. #endif
  21. #include "gpsd_config.h" /* is HAVE_STDATOMIC defined? */
  22. /* Macro for declaring function with printf-like arguments. */
  23. # if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
  24. #define PRINTF_FUNC(format_index, arg_index) \
  25. __attribute__((__format__(__printf__, format_index, arg_index)))
  26. # else
  27. #define PRINTF_FUNC(format_index, arg_indx)
  28. #endif
  29. /* Macro for declaring function arguments unused. */
  30. #if defined(__GNUC__) || defined(__clang__)
  31. #define UNUSED __attribute__((unused))
  32. #else
  33. #define UNUSED
  34. #endif
  35. /*
  36. * Macro for compile-time checking if argument is an array.
  37. * It expands to constant expression with int value 0.
  38. */
  39. #if defined(__GNUC__)
  40. #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  41. 0 * (int) sizeof(({ \
  42. struct { \
  43. int unused_int; \
  44. __typeof__(arr) unused_arr; \
  45. } zero_init = {0}; \
  46. __typeof__(arr) arg_is_not_array UNUSED = { \
  47. zero_init.unused_arr[0], \
  48. }; \
  49. 1; \
  50. })) \
  51. )
  52. #else
  53. #define COMPILE_CHECK_IS_ARRAY(arr) 0
  54. #endif
  55. /* Needed because 4.x versions of GCC are really annoying */
  56. #define ignore_return(funcall) \
  57. do { \
  58. UNUSED ssize_t locresult = (funcall); \
  59. assert(locresult != -23); \
  60. } while (0)
  61. #ifdef __COVERITY__
  62. /* do nothing */
  63. #elif defined(__cplusplus)
  64. /* we are C++ */
  65. #if __cplusplus >= 201103L
  66. /* C++ before C++11 can not handle stdatomic.h or atomic */
  67. /* atomic is just C++ for stdatomic.h */
  68. #include <atomic>
  69. #endif
  70. #elif defined(HAVE_STDATOMIC_H)
  71. /* we are C and atomics are in C98 and newer */
  72. #include <stdatomic.h>
  73. #elif defined(HAVE_OSATOMIC_H)
  74. /* do it the OS X way */
  75. #include <libkern/OSAtomic.h>
  76. #endif /* HAVE_OSATOMIC_H */
  77. static inline void memory_barrier(void)
  78. /* prevent instruction reordering across any call to this function */
  79. {
  80. #ifdef __COVERITY__
  81. /* do nothing */
  82. #elif defined(__cplusplus)
  83. /* we are C++ */
  84. #if __cplusplus >= 201103L
  85. /* C++11 and later has atomics, earlier do not */
  86. std::atomic_thread_fence(std::memory_order_seq_cst);
  87. #endif
  88. #elif defined HAVE_STDATOMIC_H
  89. /* we are C and atomics are in C98 and newer */
  90. atomic_thread_fence(memory_order_seq_cst);
  91. #elif defined(HAVE_OSATOMIC_H)
  92. /* do it the OS X way */
  93. OSMemoryBarrier();
  94. #elif defined(__GNUC__)
  95. __asm__ __volatile__ ("" : : : "memory");
  96. #endif
  97. }
  98. #endif /* _GPSD_COMPILER_H_ */