UCX  1.18
Unified Communication X
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 */