1 /* 2 * Copyright (C) by Argonne National Laboratory 3 * See COPYRIGHT in top-level directory 4 */ 5 6 #ifndef MPL_BASE_H_INCLUDED 7 #define MPL_BASE_H_INCLUDED 8 9 /* this file splits off the base functionality in MPL, which does not 10 * depend on any of the exposed features. */ 11 12 #include "mplconfig.h" 13 14 #include <stdio.h> 15 #include <stdlib.h> 16 #include <string.h> 17 #include <stdarg.h> 18 #include <stdint.h> 19 20 #if defined MPL_HAVE_CTYPE_H 21 #include <ctype.h> 22 #endif /* MPL_HAVE_CTYPE_H */ 23 24 #if defined(MPL_HAVE_INTTYPES_H) 25 #include <inttypes.h> 26 #endif /* MPL_HAVE_INTTYPES_H */ 27 28 #if defined MPL_HAVE_IFADDRS_H 29 #include <ifaddrs.h> 30 #endif /* MPL_HAVE_IFADDRS_H */ 31 32 #if defined MPL_HAVE_ARPA_INET_H 33 #include <arpa/inet.h> 34 #endif /* MPL_HAVE_ARPA_INET_H */ 35 36 #if !defined ATTRIBUTE 37 #if defined MPL_HAVE_GCC_ATTRIBUTE 38 #define ATTRIBUTE(a_) __attribute__(a_) 39 #else /* MPL_HAVE_GCC_ATTRIBUTE */ 40 #define ATTRIBUTE(a_) 41 #endif /* MPL_HAVE_GCC_ATTRIBUTE */ 42 #endif /* ATTRIBUTE */ 43 44 #define MPL_UNUSED ATTRIBUTE((unused)) 45 #ifdef MPL_ENABLE_ALWAYS_INLINE 46 #define MPL_STATIC_INLINE_PREFIX ATTRIBUTE((always_inline)) static inline 47 #define MPL_STATIC_INLINE_SUFFIX ATTRIBUTE((always_inline)) 48 #else 49 #define MPL_STATIC_INLINE_PREFIX static inline 50 #define MPL_STATIC_INLINE_SUFFIX 51 #endif 52 53 #ifdef MPL_HAVE_FUNC_ATTRIBUTE_FALLTHROUGH 54 #define MPL_FALLTHROUGH __attribute__((fallthrough)) 55 #else 56 #define MPL_FALLTHROUGH 57 #endif 58 59 #ifdef MPL_HAVE_VAR_ATTRIBUTE_ALIGNED 60 #define MPL_ATTR_ALIGNED(x) __attribute__((aligned(x))) 61 #else 62 #define MPL_ATTR_ALIGNED(x) 63 #endif 64 65 #ifdef MPL_HAVE_VAR_ATTRIBUTE_USED 66 #define MPL_USED __attribute__((used)) 67 #else 68 #define MPL_USED 69 #endif 70 71 /* These likely/unlikely macros provide static branch prediction hints to the 72 * compiler, if such hints are available. Simply wrap the relevant expression in 73 * the macro, like this: 74 * 75 * if (unlikely(ptr == NULL)) { 76 * // ... some unlikely code path ... 77 * } 78 * 79 * They should be used sparingly, especially in upper-level code. It's easy to 80 * incorrectly estimate branching likelihood, while the compiler can often do a 81 * decent job if left to its own devices. 82 * 83 * These macros are not namespaced because the namespacing is cumbersome. 84 */ 85 #ifdef MPL_HAVE_BUILTIN_EXPECT 86 #define unlikely(x_) __builtin_expect(!!(x_),0) 87 #define likely(x_) __builtin_expect(!!(x_),1) 88 #else 89 #define unlikely(x_) (x_) 90 #define likely(x_) (x_) 91 #endif 92 93 #ifdef MPL_HAVE_C11__STATIC_ASSERT 94 #define MPL_static_assert(cond_,msg_) _Static_assert(cond_,msg_) 95 #else 96 /* A hack: 97 When cond_ is false, result in compile-time duplicated case error. 98 When cond_ is true, compiler should optimize it away. 99 Since it is compile time error, we don't care (much) about how the error message look. 100 */ 101 #define MPL_static_assert(cond_,msg_) \ 102 do { switch(0) { case 0: case (cond_): default: break; } } while (0) 103 #endif 104 105 #define MPL_COMPILE_TIME_ASSERT(cond_) MPL_static_assert(cond_, "MPL_COMPILE_TIME_ASSERT failure") 106 107 #define MPL_QUOTE(A) MPL_QUOTE2(A) 108 #define MPL_QUOTE2(A) #A 109 110 #define MPL_MAX(a,b) (((a) > (b)) ? (a) : (b)) 111 #define MPL_MIN(a,b) (((a) < (b)) ? (a) : (b)) 112 113 /* Use this macro for each parameter to a function that is not referenced in 114 the body of the function */ 115 #ifdef MPL_HAVE_WINDOWS_H 116 #define MPL_UNREFERENCED_ARG(a) a 117 #else 118 #define MPL_UNREFERENCED_ARG(a) 119 #endif 120 121 /* macro for finding the enclosing structure of an element */ 122 #define MPL_container_of(ptr, type, member) (type *)((char *)(ptr) - offsetof(type,member)) 123 124 /* This macro is used to silence warnings from the Mac OS X linker when 125 * an object file "has no symbols". The unused attribute prevents a 126 * warning about the unused dummy variable while the used attribute 127 * prevents the compiler from discarding the symbol altogether. This 128 * macro should be used at the top of any file that might not define any 129 * other variables or functions (perhaps due to conditional compilation 130 * via the preprocessor). A semicolon is expected after each invocation 131 * of this macro. */ 132 #define MPL_SUPPRESS_OSX_HAS_NO_SYMBOLS_WARNING \ 133 static int MPL_UNIQUE_SYMBOL_NAME(dummy) ATTRIBUTE((unused)) MPL_USED = 0 134 135 /* we jump through a couple of extra macro hoops to append the line 136 * number to the variable name in order to reduce the chance of a name 137 * collision with headers that might be included in the translation 138 * unit */ 139 #define MPL_UNIQUE_SYMBOL_NAME(prefix_) MPL_UNIQUE_IMPL1_(prefix_##_unique_L,__LINE__) 140 #define MPL_UNIQUE_IMPL1_(prefix_,line_) MPL_UNIQUE_IMPL2_(prefix_,line_) 141 #define MPL_UNIQUE_IMPL2_(prefix_,line_) MPL_UNIQUE_IMPL3_(prefix_,line_) 142 #define MPL_UNIQUE_IMPL3_(prefix_,line_) prefix_##line_ 143 144 #ifdef MPL_HAVE_STDBOOL_H 145 #include <stdbool.h> 146 #else 147 #ifndef MPL_HAVE__BOOL 148 #ifdef __cplusplus 149 typedef bool _Bool; 150 #else 151 #define _Bool signed char 152 #endif 153 #endif 154 #define bool _Bool 155 #define false 0 156 #define true 1 157 #define __bool_true_false_are_defined 1 158 #endif 159 160 #define MPL_ROUND_UP_ALIGN(a, alignment) (((a) + ((alignment) - 1)) & (~((alignment) - 1))) 161 #define MPL_ROUND_DOWN_ALIGN(a, alignment) ((a) & (~((alignment) - 1))) 162 163 #endif /* MPL_BASE_H_INCLUDED */ 164