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