1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
/*
* compiler.h - compiler specific macros
*
* This file is Copyright 2010 by the GPSD project
* SPDX-License-Identifier: BSD-2-clause
*
* Calling file needs to have previously included "gpsd_config.h"
*/
#ifndef _GPSD_COMPILER_H_
#define _GPSD_COMPILER_H_
#ifndef GPSD_CONFIG_H
#error "Missing GPSD_CONFIG_H"
#endif
/*
* Tell GCC that we want thread-safe behavior with _REENTRANT;
* in particular, errno must be thread-local.
* Tell POSIX-conforming implementations with _POSIX_THREAD_SAFE_FUNCTIONS.
* See http://www.unix.org/whitepapers/reentrant.html
*/
#ifndef _REENTRANT
#define _REENTRANT
#endif
#ifndef _POSIX_THREAD_SAFE_FUNCTIONS
#define _POSIX_THREAD_SAFE_FUNCTIONS
#endif
// Macro for declaring function with printf-like arguments.
# if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
#define PRINTF_FUNC(format_index, arg_index) \
__attribute__((__format__(__printf__, format_index, arg_index)))
#else
#define PRINTF_FUNC(format_index, arg_indx)
#endif
// Macro for declaring function arguments unused.
#if defined(__GNUC__) || defined(__clang__)
#define UNUSED __attribute__((unused))
#else
#define UNUSED
#endif
// Macro to suppress FALLTHROUGH warnings
#if defined(__GNUC__) && __GNUC__ >= 7
#define FALLTHROUGH __attribute__((fallthrough));
// At least one Clang 6 version advertises fallthrough and then chokes on it
#elif defined(__clang__) && __clang_major__ > 6
#ifndef __has_attribute // For backwards compatibility
#define __has_attribute(x) 0
#endif
#if __has_attribute(fallthrough)
#define FALLTHROUGH __attribute__((fallthrough));
#endif
#endif
#ifndef FALLTHROUGH
#define FALLTHROUGH
#endif
/*
* Macro for compile-time checking if argument is an array.
* It expands to constant expression with int value 0.
*/
#if defined(__GNUC__)
#define COMPILE_CHECK_IS_ARRAY(arr) ( \
0 * (int) sizeof(({ \
struct { \
int unused_int; \
__typeof__(arr) unused_arr; \
} zero_init = {0}; \
__typeof__(arr) arg_is_not_array UNUSED = { \
zero_init.unused_arr[0], \
}; \
1; \
})) \
)
#else
#define COMPILE_CHECK_IS_ARRAY(arr) 0
#endif
// Needed because 4.x versions of GCC are really annoying
// FIXME: in 20202, do we care about gcc 4?
#define ignore_return(funcall) \
do { \
UNUSED ssize_t locresult = (funcall); \
assert(locresult != -23); \
} while (0)
#ifdef __COVERITY__
// do nothing
#elif defined(__cplusplus)
// we are C++
#if __cplusplus >= 201103L
/* C++ before C++11 can not handle stdatomic.h or atomic
* atomic is just C++ for stdatomic.h */
#include <atomic>
#endif
#elif defined(HAVE_STDATOMIC_H)
// we are C and atomics are in C98 and newer
#include <stdatomic.h>
#elif defined(HAVE_OSATOMIC_H)
// do it the OS X way
#include <libkern/OSAtomic.h>
#endif // HAVE_OSATOMIC_H
// prevent instruction reordering across any call to this function
static inline void memory_barrier(void)
{
#ifdef __COVERITY__
// do nothing
#elif defined(__cplusplus)
// we are C++
#if __cplusplus >= 201103L
// C++11 and later has atomics, earlier do not
std::atomic_thread_fence(std::memory_order_seq_cst);
#endif
#elif defined HAVE_STDATOMIC_H
// we are C and atomics are in C98 and newer
atomic_thread_fence(memory_order_seq_cst);
#elif defined(HAVE_OSATOMIC_H)
// do it the OS X way
OSMemoryBarrier();
#elif defined(__GNUC__)
__asm__ __volatile__ ("" : : : "memory");
#endif
}
/* likely(), unlikely(), branch optimization
* https://kernelnewbies.org/FAQ/LikelyUnlikely
*/
#if defined(__GNUC__)
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#else
#define likely(x) (x)
#define unlikely(x) (x)
#endif
#endif // _GPSD_COMPILER_H_
// vim: set expandtab shiftwidth=4
|