1 /** 2 * Copyright (C) Mellanox Technologies Ltd. 2001-2017. ALL RIGHTS RESERVED. 3 * Copyright (C) UT-Battelle, LLC. 2015. ALL RIGHTS RESERVED. 4 * 5 * See file LICENSE for terms. 6 */ 7 8 #ifndef UCS_COMPILER_DEF_H 9 #define UCS_COMPILER_DEF_H 10 11 /* Note: Place "@file <file name>.h" after BEGIN_C_DECS 12 * to avoid bugs in a documentation */ 13 #ifdef __cplusplus 14 # define BEGIN_C_DECLS extern "C" { 15 # define END_C_DECLS } 16 #else 17 # define BEGIN_C_DECLS 18 # define END_C_DECLS 19 #endif 20 21 /* 22 * Assertions which are checked in compile-time 23 * 24 * Usage: UCS_STATIC_ASSERT(condition) 25 */ 26 #define UCS_STATIC_ASSERT(_cond) \ 27 switch(0) {case 0:case (_cond):;} 28 29 /* Aliasing structure */ 30 #define UCS_S_MAY_ALIAS __attribute__((may_alias)) 31 32 /* A function without side effects */ 33 #define UCS_F_PURE __attribute__((pure)) 34 35 /* A function which does not return */ 36 #define UCS_F_NORETURN __attribute__((noreturn)) 37 38 /* Packed structure */ 39 #define UCS_S_PACKED __attribute__((packed)) 40 41 /* Avoid inlining the function */ 42 #define UCS_F_NOINLINE __attribute__ ((noinline)) 43 44 /* Shared library constructor and destructor */ 45 #define UCS_F_CTOR __attribute__((constructor)) 46 #define UCS_F_DTOR __attribute__((destructor)) 47 48 /* Silence "defined but not used" error for static function */ 49 #define UCS_F_MAYBE_UNUSED __attribute__((used)) 50 51 /* Non-null return */ 52 #define UCS_F_NON_NULL __attribute__((nonnull)) 53 54 /* Always inline the function */ 55 #ifdef __GNUC__ 56 #define UCS_F_ALWAYS_INLINE inline __attribute__ ((always_inline)) 57 #else 58 #define UCS_F_ALWAYS_INLINE inline 59 #endif 60 61 /* Silence "uninitialized variable" for stupid compilers (gcc 4.1) 62 * which can't optimize properly. 63 */ 64 #if (((__GNUC__ == 4) && (__GNUC_MINOR__ == 1)) || !defined(__OPTIMIZE__)) 65 # define UCS_V_INITIALIZED(_v) (_v = (typeof(_v))0) 66 #else 67 # define UCS_V_INITIALIZED(_v) ((void)0) 68 #endif 69 70 /* The i-th bit */ 71 #define UCS_BIT(i) (1ul << (i)) 72 73 /* Mask of bits 0..i-1 */ 74 #define UCS_MASK(i) (UCS_BIT(i) - 1) 75 76 /* 77 * Enable compiler checks for printf-like formatting. 78 * 79 * @param fmtargN number of formatting argument 80 * @param vargN number of variadic argument 81 */ 82 #define UCS_F_PRINTF(fmtargN, vargN) __attribute__((format(printf, fmtargN, vargN))) 83 84 /* Unused variable */ 85 #define UCS_V_UNUSED __attribute__((unused)) 86 87 /* Aligned variable */ 88 #define UCS_V_ALIGNED(_align) __attribute__((aligned(_align))) 89 90 /* Used for labels */ 91 #define UCS_EMPTY_STATEMENT {} 92 93 /* Helper macro for address arithmetic in bytes */ 94 #define UCS_PTR_BYTE_OFFSET(_ptr, _offset) \ 95 ((void *)((intptr_t)(_ptr) + (intptr_t)(_offset))) 96 97 /* Helper macro to calculate an address with offset equal to size of _type */ 98 #define UCS_PTR_TYPE_OFFSET(_ptr, _type) \ 99 ((void *)((typeof(_type) *)(_ptr) + 1)) 100 101 /* Helper macro to calculate ptr difference (_end - _start) */ 102 #define UCS_PTR_BYTE_DIFF(_start, _end) \ 103 ((ptrdiff_t)((uintptr_t)(_end) - (uintptr_t)(_start))) 104 105 106 /** 107 * Size of statically-declared array 108 */ 109 #define ucs_static_array_size(_array) \ 110 ({ \ 111 UCS_STATIC_ASSERT((void*)&(_array) == (void*)&((_array)[0])); \ 112 ( sizeof(_array) / sizeof((_array)[0]) ); \ 113 }) 114 115 /** 116 * @return count of elements in const-size array 117 */ 118 #define ucs_array_size(_array) \ 119 (sizeof(_array) / sizeof((_array)[0])) 120 121 /** 122 * @return Offset of _member in _type. _type is a structure type. 123 */ 124 #define ucs_offsetof(_type, _member) \ 125 ((unsigned long)&( ((_type*)0)->_member )) 126 127 /** 128 * Get a pointer to a struct containing a member. 129 * 130 * @param __ptr Pointer to the member. 131 * @param type Container type. 132 * @param member Element member inside the container. 133 134 * @return Address of the container structure. 135 */ 136 #define ucs_container_of(_ptr, _type, _member) \ 137 ( (_type*)( (char*)(void*)(_ptr) - ucs_offsetof(_type, _member) ) ) 138 139 140 /** 141 * @return Address of a derived structure. It must have a "super" member at offset 0. 142 * NOTE: we use the built-in offsetof here because we can't use ucs_offsetof() in 143 * a constant expression. 144 */ 145 #define ucs_derived_of(_ptr, _type) \ 146 ({\ 147 UCS_STATIC_ASSERT(offsetof(_type, super) == 0) \ 148 ucs_container_of(_ptr, _type, super); \ 149 }) 150 151 /** 152 * @param _type Structure type. 153 * @param _field Field of structure. 154 * 155 * @return Size of _field in _type. 156 */ 157 #define ucs_field_sizeof(_type, _field) \ 158 sizeof(((_type*)0)->_field) 159 160 /** 161 * @param _type Structure type. 162 * @param _field Field of structure. 163 * 164 * @return Type of _field in _type. 165 */ 166 #define ucs_field_type(_type, _field) \ 167 typeof(((_type*)0)->_field) 168 169 /** 170 * Prevent compiler from reordering instructions 171 */ 172 #define ucs_compiler_fence() asm volatile(""::: "memory") 173 174 /** 175 * Prefetch cache line 176 */ 177 #define ucs_prefetch(p) __builtin_prefetch(p) 178 179 /* Branch prediction */ 180 #define ucs_likely(x) __builtin_expect(x, 1) 181 #define ucs_unlikely(x) __builtin_expect(x, 0) 182 183 /* Check if an expression is a compile-time constant */ 184 #define ucs_is_constant(expr) __builtin_constant_p(expr) 185 186 /* 187 * Define code which runs at global constructor phase 188 */ 189 #define UCS_STATIC_INIT \ 190 static void UCS_F_CTOR UCS_PP_APPEND_UNIQUE_ID(ucs_initializer_ctor)() 191 192 /* 193 * Define code which runs at global destructor phase 194 */ 195 #define UCS_STATIC_CLEANUP \ 196 static void UCS_F_DTOR UCS_PP_APPEND_UNIQUE_ID(ucs_initializer_dtor)() 197 198 #endif /* UCS_COMPILER_DEF_H */ 199