UCX 1.19
Unified Communication X
Loading...
Searching...
No Matches
compiler_def.h
1
10#ifndef UCS_COMPILER_DEF_H
11#define UCS_COMPILER_DEF_H
12
13/* Note: Place "@file <file name>.h" after BEGIN_C_DECS
14 * to avoid bugs in a documentation */
15#ifdef __cplusplus
16# define BEGIN_C_DECLS extern "C" {
17# define END_C_DECLS }
18#else
19# define BEGIN_C_DECLS
20# define END_C_DECLS
21#endif
22
23/*
24 * Assertions which are checked in compile-time
25 *
26 * Usage: UCS_STATIC_ASSERT(condition)
27 */
28#define UCS_STATIC_ASSERT(_cond) \
29 switch(0) {case 0:case (_cond):;}
30
31/* Maximal allocation size for on-stack buffers */
32#define UCS_ALLOCA_MAX_SIZE 1200
33
34/* Aliasing structure */
35#define UCS_S_MAY_ALIAS __attribute__((may_alias))
36
37/* A function without side effects */
38#define UCS_F_PURE __attribute__((pure))
39
40/* A function which does not return */
41#define UCS_F_NORETURN __attribute__((noreturn))
42
43/* Packed structure */
44#define UCS_S_PACKED __attribute__((packed))
45
46/* Avoid inlining the function */
47#define UCS_F_NOINLINE __attribute__ ((noinline))
48
49/* Shared library constructor and destructor */
50#define UCS_F_CTOR __attribute__((constructor))
51#define UCS_F_DTOR __attribute__((destructor))
52
53/* Silence "defined but not used" error for static function,
54 * remove it by linker if it's not used at all.
55 */
56#define UCS_F_MAYBE_UNUSED __attribute__((unused))
57
58/* Non-null return */
59#define UCS_F_NON_NULL __attribute__((nonnull))
60
61/* Always inline the function */
62#ifdef __GNUC__
63#define UCS_F_ALWAYS_INLINE inline __attribute__ ((always_inline))
64#else
65#define UCS_F_ALWAYS_INLINE inline
66#endif
67
68/* Silence "uninitialized variable" for stupid compilers (gcc 4.1)
69 * which can't optimize properly.
70 */
71#if (((__GNUC__ == 4) && (__GNUC_MINOR__ == 1)) || !defined(__OPTIMIZE__))
72# define UCS_V_INITIALIZED(_v) (_v = (ucs_typeof(_v))0)
73#else
74# define UCS_V_INITIALIZED(_v) ((void)0)
75#endif
76
77/* The i-th bit */
78#define UCS_BIT(i) (1ul << (i))
79
80/* Mask of bits 0..i-1 */
81#define UCS_MASK(_i) (((_i) >= 64) ? ~0 : (UCS_BIT(_i) - 1))
82
83/* The i-th bit */
84#define UCS_BIT_GET(_value, _i) (!!((_value) & UCS_BIT(_i)))
85
86/*
87 * Enable compiler checks for printf-like formatting.
88 *
89 * @param fmtargN number of formatting argument
90 * @param vargN number of variadic argument
91 */
92#define UCS_F_PRINTF(fmtargN, vargN) __attribute__((format(printf, fmtargN, vargN)))
93
94/* Unused variable */
95#define UCS_V_UNUSED __attribute__((unused))
96
97/* Aligned variable */
98#define UCS_V_ALIGNED(_align) __attribute__((aligned(_align)))
99
100/* Disable address sanitizer */
101#ifdef __SANITIZE_ADDRESS__
102# define UCS_F_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
103#else
104# define UCS_F_NO_SANITIZE_ADDRESS
105#endif
106
107/* Used for labels */
108#define UCS_EMPTY_STATEMENT {}
109
110/* Helper macro for address arithmetic in bytes */
111#define UCS_PTR_BYTE_OFFSET(_ptr, _offset) \
112 ((void *)((intptr_t)(_ptr) + (intptr_t)(_offset)))
113
114/* Helper macro to calculate an address with offset equal to size of _type */
115#define UCS_PTR_TYPE_OFFSET(_ptr, _type) \
116 ((void *)((ucs_typeof(_type) *)(_ptr) + 1))
117
118/* Helper macro to calculate ptr difference (_end - _start) */
119#define UCS_PTR_BYTE_DIFF(_start, _end) \
120 ((ptrdiff_t)((uintptr_t)(_end) - (uintptr_t)(_start)))
121
122
126#define ucs_static_array_size(_array) \
127 (sizeof(_array) / sizeof((_array)[0]))
128
129
133#define ucs_offsetof(_type, _member) \
134 ((unsigned long)&( ((_type*)0)->_member ))
135
136
146#define ucs_container_of(_ptr, _type, _member) \
147 ( (_type*)( (char*)(void*)(_ptr) - ucs_offsetof(_type, _member) ) )
148
149
157#define ucs_typeof(_type) \
158 __typeof__(_type)
159
160
166#define ucs_derived_of(_ptr, _type) \
167 ({\
168 UCS_STATIC_ASSERT(offsetof(_type, super) == 0) \
169 ucs_container_of(_ptr, _type, super); \
170 })
171
178#define ucs_field_sizeof(_type, _field) \
179 sizeof(((_type*)0)->_field)
180
187#define ucs_field_type(_type, _field) \
188 ucs_typeof(((_type*)0)->_field)
189
195#define ucs_is_unsigned_type(_type) \
196 ((_type)(-1) > (_type)(0))
197
201#define ucs_compiler_fence() asm volatile(""::: "memory")
202
206#define ucs_read_prefetch(p) __builtin_prefetch(p, 0, 3)
207#define ucs_write_prefetch(p) __builtin_prefetch(p, 1, 3)
208
209#define ucs_nt_read_prefetch(p) __builtin_prefetch(p, 0, 0)
210#define ucs_nt_write_prefetch(p) __builtin_prefetch(p, 1, 0)
211
212/* Branch prediction */
213#define ucs_likely(x) __builtin_expect(x, 1)
214#define ucs_unlikely(x) __builtin_expect(x, 0)
215
216/* Check if an expression is a compile-time constant */
217#define ucs_is_constant(expr) __builtin_constant_p(expr)
218
219/*
220 * Define code which runs at global constructor phase
221 */
222#define UCS_STATIC_INIT \
223 static void UCS_F_CTOR UCS_PP_APPEND_UNIQUE_ID(ucs_initializer_ctor)()
224
225/*
226 * Define code which runs at global destructor phase
227 */
228#define UCS_STATIC_CLEANUP \
229 static void UCS_F_DTOR UCS_PP_APPEND_UNIQUE_ID(ucs_initializer_dtor)()
230
231/*
232 * Check if the two types are the same
233 */
234#define ucs_same_type(_type1, _type2) \
235 __builtin_types_compatible_p(_type1, _type2)
236
237/*
238 * Iterate over all elements of a C-array
239 */
240#define ucs_carray_for_each(_elem, _array, _length) \
241 for ((_elem) = (_array); (_elem) < ((_array) + (_length)); ++(_elem))
242
243/*
244 * Swap two variables values
245 */
246#define ucs_swap(_a, _b) \
247 { \
248 ucs_typeof(*(_a)) __tmp; \
249 \
250 UCS_STATIC_ASSERT(ucs_same_type(ucs_typeof(*(_a)), ucs_typeof(*(_b)))); \
251 __tmp = *(_a); \
252 *(_a) = *(_b); \
253 *(_b) = __tmp; \
254 }
255
256#endif /* UCS_COMPILER_DEF_H */