ARGOBOTS  1.1
abtu.h
Go to the documentation of this file.
1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2 /*
3  * See COPYRIGHT in top-level directory.
4  */
5 
6 #ifndef ABTU_H_INCLUDED
7 #define ABTU_H_INCLUDED
8 
9 #include <stdlib.h>
10 #include <string.h>
11 #include <assert.h>
12 #include "abt_config.h"
13 
14 /* Basic math functions */
15 static inline int ABTU_max_int(int a, int b)
16 {
17  return a > b ? a : b;
18 }
19 
20 static inline int32_t ABTU_max_int32(int32_t a, int32_t b)
21 {
22  return a > b ? a : b;
23 }
24 
25 static inline uint32_t ABTU_max_uint32(uint32_t a, uint32_t b)
26 {
27  return a > b ? a : b;
28 }
29 
30 static inline int64_t ABTU_max_int64(int64_t a, int64_t b)
31 {
32  return a > b ? a : b;
33 }
34 
35 static inline uint64_t ABTU_max_uint64(uint64_t a, uint64_t b)
36 {
37  return a > b ? a : b;
38 }
39 
40 static inline size_t ABTU_max_size(size_t a, size_t b)
41 {
42  return a > b ? a : b;
43 }
44 
45 static inline int ABTU_min_int(int a, int b)
46 {
47  return a < b ? a : b;
48 }
49 
50 static inline int32_t ABTU_min_int32(int32_t a, int32_t b)
51 {
52  return a < b ? a : b;
53 }
54 
55 static inline uint32_t ABTU_min_uint32(uint32_t a, uint32_t b)
56 {
57  return a < b ? a : b;
58 }
59 
60 static inline int64_t ABTU_min_int64(int64_t a, int64_t b)
61 {
62  return a < b ? a : b;
63 }
64 
65 static inline uint64_t ABTU_min_uint64(uint64_t a, uint64_t b)
66 {
67  return a < b ? a : b;
68 }
69 
70 static inline size_t ABTU_min_size(size_t a, size_t b)
71 {
72  return a < b ? a : b;
73 }
74 
75 static inline uint32_t ABTU_roundup_uint32(uint32_t val, uint32_t multiple)
76 {
77  if ((multiple & (multiple - 1)) == 0) {
78  /* If multiple is a power of two. */
79  return (val + multiple - 1) & (~(multiple - 1));
80  } else {
81  return ((val + multiple - 1) / multiple) * multiple;
82  }
83 }
84 
85 static inline uint64_t ABTU_roundup_uint64(uint64_t val, uint64_t multiple)
86 {
87  if ((multiple & (multiple - 1)) == 0) {
88  /* If multiple is a power of two. */
89  return (val + multiple - 1) & (~(multiple - 1));
90  } else {
91  return ((val + multiple - 1) / multiple) * multiple;
92  }
93 }
94 
95 static inline size_t ABTU_roundup_size(size_t val, size_t multiple)
96 {
97  if ((multiple & (multiple - 1)) == 0) {
98  /* If multiple is a power of two. */
99  return (val + multiple - 1) & (~(multiple - 1));
100  } else {
101  return ((val + multiple - 1) / multiple) * multiple;
102  }
103 }
104 
105 /* Utility feature */
106 
107 #ifdef HAVE___BUILTIN_EXPECT
108 #define ABTU_likely(cond) __builtin_expect(!!(cond), 1)
109 #define ABTU_unlikely(cond) __builtin_expect(!!(cond), 0)
110 #else
111 #define ABTU_likely(cond) (cond)
112 #define ABTU_unlikely(cond) (cond)
113 #endif
114 
115 #ifdef HAVE_FUNC_ATTRIBUTE_NORETURN
116 #define ABTU_noreturn __attribute__((noreturn))
117 #else
118 #define ABTU_noreturn
119 #endif
120 
121 #ifdef HAVE___BUILTIN_UNREACHABLE
122 #define ABTU_unreachable() __builtin_unreachable()
123 #else
124 /* abort is better than entering an unknown area. First assert(0), which shows
125  * something if assert() is enabled. If assert() is disabled, let's abort(). */
126 static inline ABTU_noreturn void ABTU_unreachable(void)
127 {
128  assert(0);
129  abort();
130 }
131 #endif
132 
133 #ifdef ABT_CONFIG_HAVE_ALIGNOF_GCC
134 #define ABTU_alignof(type) (__alignof__(type))
135 #elif defined(ABT_CONFIG_HAVE_ALIGNOF_C11)
136 #define ABTU_alignof(type) (alignof(type))
137 #else
138 #define ABTU_alignof(type) 16 /* 16 bytes would be a good guess. */
139 #endif
140 #define ABTU_MAX_ALIGNMENT \
141  ABTU_max_size(ABTU_alignof(long double), ABTU_alignof(long long))
142 
143 #ifdef HAVE_FUNC_ATTRIBUTE_WARN_UNUSED_RESULT
144 #define ABTU_ret_err __attribute__((warn_unused_result))
145 #else
146 #define ABTU_ret_err
147 #endif
148 
149 /*
150  * An attribute to hint an alignment of a member variable.
151  * Usage:
152  * struct X {
153  * void *obj_1;
154  * ABTU_align_member_var(64)
155  * void *obj_2;
156  * };
157  */
158 #ifndef __SUNPRO_C
159 #define ABTU_align_member_var(size) __attribute__((aligned(size)))
160 #else
161 /* Sun Studio does not support it. */
162 #define ABTU_align_member_var(size)
163 #endif
164 
165 /*
166  * An attribute to suppress address sanitizer warning.
167  */
168 #if defined(__GNUC__) && defined(__SANITIZE_ADDRESS__)
169 /*
170  * Older GCC cannot combine no_sanitize_address + always_inline (e.g., builtin
171  * memcpy on some platforms), which causes *a compilation error*. Let's accept
172  * false-positive warning if used GCC is old. This issue seems fixed between
173  * GCC 7.4.0 and GCC 8.3.0 as far as I checked.
174  * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59600
175  */
176 #if __GNUC__ >= 8
177 #define ABTU_no_sanitize_address __attribute__((no_sanitize_address))
178 #endif
179 #elif __clang__
180 #if defined(__has_feature)
181 #if __has_feature(address_sanitizer)
182 #if __clang_major__ >= 4 || (__clang_major__ >= 3 && __clang_minor__ >= 7)
183 /* >= Clang 3.7.0 */
184 #define ABTU_no_sanitize_address __attribute__((no_sanitize("address")))
185 #elif (__clang_major__ >= 3 && __clang_minor__ >= 3)
186 /* >= Clang 3.3.0 */
187 #define ABTU_no_sanitize_address __attribute__((no_sanitize_address))
188 #elif (__clang_major__ >= 3 && __clang_minor__ >= 1)
189 /* >= Clang 3.1.0 */
190 #define ABTU_no_sanitize_address __attribute__((no_address_safety_analysis))
191 #else /* Too old clang. */
192 #define ABTU_no_sanitize_address
193 #endif
194 #endif /* __has_feature(address_sanitizer) */
195 #endif /* defined(__has_feature) */
196 #endif
197 
198 #ifndef ABTU_no_sanitize_address
199 /* We do not support other address sanitizers. */
200 #define ABTU_no_sanitize_address
201 #endif
202 
203 /* Utility Functions */
204 
205 ABTU_ret_err static inline int ABTU_memalign(size_t alignment, size_t size,
206  void **p_ptr)
207 {
208  void *ptr;
209  int ret = posix_memalign(&ptr, alignment, size);
210  if (ABTI_IS_ERROR_CHECK_ENABLED && ret != 0) {
211  return ABT_ERR_MEM;
212  }
213  *p_ptr = ptr;
214  return ABT_SUCCESS;
215 }
216 
217 static inline void ABTU_free(void *ptr)
218 {
219  free(ptr);
220 }
221 
222 #ifdef ABT_CONFIG_USE_ALIGNED_ALLOC
223 
224 ABTU_ret_err static inline int ABTU_malloc(size_t size, void **p_ptr)
225 {
226  /* Round up to the smallest multiple of ABT_CONFIG_STATIC_CACHELINE_SIZE
227  * which is greater than or equal to size in order to avoid any
228  * false-sharing. */
230  return ABTU_memalign(ABT_CONFIG_STATIC_CACHELINE_SIZE, size, p_ptr);
231 }
232 
233 ABTU_ret_err static inline int ABTU_calloc(size_t num, size_t size,
234  void **p_ptr)
235 {
236  void *ptr;
237  int ret = ABTU_malloc(num * size, &ptr);
239  return ABT_ERR_MEM;
240  }
241  memset(ptr, 0, num * size);
242  *p_ptr = ptr;
243  return ABT_SUCCESS;
244 }
245 
246 ABTU_ret_err static inline int ABTU_realloc(size_t old_size, size_t new_size,
247  void **p_ptr)
248 {
249  void *new_ptr, *old_ptr = *p_ptr;
250  int ret = ABTU_malloc(new_size, &new_ptr);
252  return ABT_ERR_MEM;
253  }
254  memcpy(new_ptr, old_ptr, ABTU_min_size(old_size, new_size));
255  ABTU_free(old_ptr);
256  *p_ptr = new_ptr;
257  return ABT_SUCCESS;
258 }
259 
260 #else /* ABT_CONFIG_USE_ALIGNED_ALLOC */
261 
262 ABTU_ret_err static inline int ABTU_malloc(size_t size, void **p_ptr)
263 {
264  void *ptr = malloc(size);
265  if (ABTI_IS_ERROR_CHECK_ENABLED && ptr == NULL) {
266  return ABT_ERR_MEM;
267  }
268  *p_ptr = ptr;
269  return ABT_SUCCESS;
270 }
271 
272 ABTU_ret_err static inline int ABTU_calloc(size_t num, size_t size,
273  void **p_ptr)
274 {
275  void *ptr = calloc(num, size);
276  if (ABTI_IS_ERROR_CHECK_ENABLED && ptr == NULL) {
277  return ABT_ERR_MEM;
278  }
279  *p_ptr = ptr;
280  return ABT_SUCCESS;
281 }
282 
283 ABTU_ret_err static inline int ABTU_realloc(size_t old_size, size_t new_size,
284  void **p_ptr)
285 {
286  (void)old_size;
287  void *ptr = realloc(*p_ptr, new_size);
288  if (ABTI_IS_ERROR_CHECK_ENABLED && ptr == NULL) {
289  return ABT_ERR_MEM;
290  }
291  *p_ptr = ptr;
292  return ABT_SUCCESS;
293 }
294 
295 #endif /* !ABT_CONFIG_USE_ALIGNED_ALLOC */
296 
298  ABTU_MEM_LARGEPAGE_MALLOC, /* ABTU_malloc(). */
299  ABTU_MEM_LARGEPAGE_MEMALIGN, /* memalign() */
300  ABTU_MEM_LARGEPAGE_MMAP, /* normal private memory obtained by mmap() */
301  ABTU_MEM_LARGEPAGE_MMAP_HUGEPAGE, /* hugepage obtained by mmap() */
303 
304 /* Returns 1 if a given large page type is supported. */
305 int ABTU_is_supported_largepage_type(size_t size, size_t alignment_hint,
306  ABTU_MEM_LARGEPAGE_TYPE requested);
307 ABTU_ret_err int
308 ABTU_alloc_largepage(size_t size, size_t alignment_hint,
309  const ABTU_MEM_LARGEPAGE_TYPE *requested_types,
310  int num_requested_types, ABTU_MEM_LARGEPAGE_TYPE *p_actual,
311  void **p_ptr);
312 void ABTU_free_largepage(void *ptr, size_t size, ABTU_MEM_LARGEPAGE_TYPE type);
313 
314 /* String-to-integer functions. */
315 ABTU_ret_err int ABTU_atoi(const char *str, int *p_val, ABT_bool *p_overflow);
316 ABTU_ret_err int ABTU_atoui32(const char *str, uint32_t *p_val,
317  ABT_bool *p_overflow);
318 ABTU_ret_err int ABTU_atoui64(const char *str, uint64_t *p_val,
319  ABT_bool *p_overflow);
320 ABTU_ret_err int ABTU_atosz(const char *str, size_t *p_val,
321  ABT_bool *p_overflow);
322 
323 #endif /* ABTU_H_INCLUDED */
ABTU_max_size
static size_t ABTU_max_size(size_t a, size_t b)
Definition: abtu.h:40
ABTU_min_int
static int ABTU_min_int(int a, int b)
Definition: abtu.h:45
ABT_bool
int ABT_bool
Boolean type.
Definition: abt.h:1001
ABTU_max_int64
static int64_t ABTU_max_int64(int64_t a, int64_t b)
Definition: abtu.h:30
ABTU_max_uint64
static uint64_t ABTU_max_uint64(uint64_t a, uint64_t b)
Definition: abtu.h:35
ABTU_realloc
static ABTU_ret_err int ABTU_realloc(size_t old_size, size_t new_size, void **p_ptr)
Definition: abtu.h:283
ABTU_max_int
static int ABTU_max_int(int a, int b)
Definition: abtu.h:15
ABTU_is_supported_largepage_type
int ABTU_is_supported_largepage_type(size_t size, size_t alignment_hint, ABTU_MEM_LARGEPAGE_TYPE requested)
Definition: largepage.c:59
ABTU_roundup_size
static size_t ABTU_roundup_size(size_t val, size_t multiple)
Definition: abtu.h:95
ABTU_noreturn
#define ABTU_noreturn
Definition: abtu.h:118
ABTU_min_size
static size_t ABTU_min_size(size_t a, size_t b)
Definition: abtu.h:70
ABTU_memalign
static ABTU_ret_err int ABTU_memalign(size_t alignment, size_t size, void **p_ptr)
Definition: abtu.h:205
ABTU_alloc_largepage
ABTU_ret_err int ABTU_alloc_largepage(size_t size, size_t alignment_hint, const ABTU_MEM_LARGEPAGE_TYPE *requested_types, int num_requested_types, ABTU_MEM_LARGEPAGE_TYPE *p_actual, void **p_ptr)
Definition: largepage.c:90
ABTU_free_largepage
void ABTU_free_largepage(void *ptr, size_t size, ABTU_MEM_LARGEPAGE_TYPE type)
Definition: largepage.c:132
ABTU_MEM_LARGEPAGE_MMAP
@ ABTU_MEM_LARGEPAGE_MMAP
Definition: abtu.h:300
ABTU_max_int32
static int32_t ABTU_max_int32(int32_t a, int32_t b)
Definition: abtu.h:20
ABTU_min_uint64
static uint64_t ABTU_min_uint64(uint64_t a, uint64_t b)
Definition: abtu.h:65
ABTI_IS_ERROR_CHECK_ENABLED
#define ABTI_IS_ERROR_CHECK_ENABLED
Definition: abti.h:20
ABTU_max_uint32
static uint32_t ABTU_max_uint32(uint32_t a, uint32_t b)
Definition: abtu.h:25
ABTU_atoui64
ABTU_ret_err int ABTU_atoui64(const char *str, uint64_t *p_val, ABT_bool *p_overflow)
Definition: atoi.c:65
ABTU_MEM_LARGEPAGE_MMAP_HUGEPAGE
@ ABTU_MEM_LARGEPAGE_MMAP_HUGEPAGE
Definition: abtu.h:301
ABTU_malloc
static ABTU_ret_err int ABTU_malloc(size_t size, void **p_ptr)
Definition: abtu.h:262
ABTU_roundup_uint64
static uint64_t ABTU_roundup_uint64(uint64_t val, uint64_t multiple)
Definition: abtu.h:85
ABT_ERR_MEM
#define ABT_ERR_MEM
Error code: Memory allocation failure.
Definition: abt.h:104
abt_config.h
ABTU_calloc
static ABTU_ret_err int ABTU_calloc(size_t num, size_t size, void **p_ptr)
Definition: abtu.h:272
ABTU_MEM_LARGEPAGE_TYPE
ABTU_MEM_LARGEPAGE_TYPE
Definition: abtu.h:297
ABT_CONFIG_STATIC_CACHELINE_SIZE
#define ABT_CONFIG_STATIC_CACHELINE_SIZE
Definition: abt_config.h:72
ABT_SUCCESS
#define ABT_SUCCESS
Error code: the routine returns successfully.
Definition: abt.h:92
ABTU_atoui32
ABTU_ret_err int ABTU_atoui32(const char *str, uint32_t *p_val, ABT_bool *p_overflow)
Definition: atoi.c:39
ABTU_MEM_LARGEPAGE_MALLOC
@ ABTU_MEM_LARGEPAGE_MALLOC
Definition: abtu.h:298
ABTU_ret_err
#define ABTU_ret_err
Definition: abtu.h:146
ABTU_min_int32
static int32_t ABTU_min_int32(int32_t a, int32_t b)
Definition: abtu.h:50
ABTU_atoi
ABTU_ret_err int ABTU_atoi(const char *str, int *p_val, ABT_bool *p_overflow)
Definition: atoi.c:11
ABTU_free
static void ABTU_free(void *ptr)
Definition: abtu.h:217
ABTU_MEM_LARGEPAGE_MEMALIGN
@ ABTU_MEM_LARGEPAGE_MEMALIGN
Definition: abtu.h:299
ABTU_atosz
ABTU_ret_err int ABTU_atosz(const char *str, size_t *p_val, ABT_bool *p_overflow)
Definition: atoi.c:85
ABTU_min_int64
static int64_t ABTU_min_int64(int64_t a, int64_t b)
Definition: abtu.h:60
ABTU_unreachable
static ABTU_noreturn void ABTU_unreachable(void)
Definition: abtu.h:126
ABTU_min_uint32
static uint32_t ABTU_min_uint32(uint32_t a, uint32_t b)
Definition: abtu.h:55
ABTU_roundup_uint32
static uint32_t ABTU_roundup_uint32(uint32_t val, uint32_t multiple)
Definition: abtu.h:75