File: compiler.h

package info (click to toggle)
gpsd 3.27-1.1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 44,056 kB
  • sloc: ansic: 74,438; python: 16,521; sh: 890; cpp: 848; php: 225; makefile: 197; perl: 111; javascript: 26; xml: 11
file content (143 lines) | stat: -rw-r--r-- 4,035 bytes parent folder | download | duplicates (2)
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