ARGOBOTS  1.1b1
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___BUILTIN_UNREACHABLE
116 #define ABTU_unreachable() __builtin_unreachable()
117 #else
118 #define ABTU_unreachable()
119 #endif
120 
121 #ifdef HAVE_FUNC_ATTRIBUTE_NORETURN
122 #define ABTU_noreturn __attribute__((noreturn))
123 #else
124 #define ABTU_noreturn
125 #endif
126 
127 #ifdef ABT_CONFIG_HAVE_ALIGNOF_GCC
128 #define ABTU_alignof(type) (__alignof__(type))
129 #elif defined(ABT_CONFIG_HAVE_ALIGNOF_C11)
130 #define ABTU_alignof(type) (alignof(type))
131 #else
132 #define ABTU_alignof(type) 16 /* 16 bytes would be a good guess. */
133 #endif
134 #define ABTU_MAX_ALIGNMENT \
135  ABTU_max_size(ABTU_alignof(long double), ABTU_alignof(long long))
136 
137 #ifdef HAVE_FUNC_ATTRIBUTE_WARN_UNUSED_RESULT
138 #define ABTU_ret_err __attribute__((warn_unused_result))
139 #else
140 #define ABTU_ret_err
141 #endif
142 
143 /*
144  * An attribute to hint an alignment of a member variable.
145  * Usage:
146  * struct X {
147  * void *obj_1;
148  * ABTU_align_member_var(64)
149  * void *obj_2;
150  * };
151  */
152 #ifndef __SUNPRO_C
153 #define ABTU_align_member_var(size) __attribute__((aligned(size)))
154 #else
155 /* Sun Studio does not support it. */
156 #define ABTU_align_member_var(size)
157 #endif
158 
159 /*
160  * An attribute to suppress address sanitizer warning.
161  */
162 #if defined(__GNUC__) && defined(__SANITIZE_ADDRESS__)
163 /*
164  * Older GCC cannot combine no_sanitize_address + always_inline (e.g., builtin
165  * memcpy on some platforms), which causes *a compilation error*. Let's accept
166  * false-positive warning if used GCC is old. This issue seems fixed between
167  * GCC 7.4.0 and GCC 8.3.0 as far as I checked.
168  * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59600
169  */
170 #if __GNUC__ >= 8
171 #define ABTU_no_sanitize_address __attribute__((no_sanitize_address))
172 #endif
173 #elif __clang__
174 #if defined(__has_feature)
175 #if __has_feature(address_sanitizer)
176 #if __clang_major__ >= 4 || (__clang_major__ >= 3 && __clang_minor__ >= 7)
177 /* >= Clang 3.7.0 */
178 #define ABTU_no_sanitize_address __attribute__((no_sanitize("address")))
179 #elif (__clang_major__ >= 3 && __clang_minor__ >= 3)
180 /* >= Clang 3.3.0 */
181 #define ABTU_no_sanitize_address __attribute__((no_sanitize_address))
182 #elif (__clang_major__ >= 3 && __clang_minor__ >= 1)
183 /* >= Clang 3.1.0 */
184 #define ABTU_no_sanitize_address __attribute__((no_address_safety_analysis))
185 #else /* Too old clang. */
186 #define ABTU_no_sanitize_address
187 #endif
188 #endif /* __has_feature(address_sanitizer) */
189 #endif /* defined(__has_feature) */
190 #endif
191 
192 #ifndef ABTU_no_sanitize_address
193 /* We do not support other address sanitizers. */
194 #define ABTU_no_sanitize_address
195 #endif
196 
197 /* Utility Functions */
198 
199 ABTU_ret_err static inline int ABTU_memalign(size_t alignment, size_t size,
200  void **p_ptr)
201 {
202  void *ptr;
203  int ret = posix_memalign(&ptr, alignment, size);
204  if (ABTI_IS_ERROR_CHECK_ENABLED && ret != 0) {
205  return ABT_ERR_MEM;
206  }
207  *p_ptr = ptr;
208  return ABT_SUCCESS;
209 }
210 
211 static inline void ABTU_free(void *ptr)
212 {
213  free(ptr);
214 }
215 
216 #ifdef ABT_CONFIG_USE_ALIGNED_ALLOC
217 
218 ABTU_ret_err static inline int ABTU_malloc(size_t size, void **p_ptr)
219 {
220  /* Round up to the smallest multiple of ABT_CONFIG_STATIC_CACHELINE_SIZE
221  * which is greater than or equal to size in order to avoid any
222  * false-sharing. */
224  return ABTU_memalign(ABT_CONFIG_STATIC_CACHELINE_SIZE, size, p_ptr);
225 }
226 
227 ABTU_ret_err static inline int ABTU_calloc(size_t num, size_t size,
228  void **p_ptr)
229 {
230  void *ptr;
231  int ret = ABTU_malloc(num * size, &ptr);
233  return ABT_ERR_MEM;
234  }
235  memset(ptr, 0, num * size);
236  *p_ptr = ptr;
237  return ABT_SUCCESS;
238 }
239 
240 ABTU_ret_err static inline int ABTU_realloc(size_t old_size, size_t new_size,
241  void **p_ptr)
242 {
243  void *new_ptr, *old_ptr = *p_ptr;
244  int ret = ABTU_malloc(new_size, &new_ptr);
246  return ABT_ERR_MEM;
247  }
248  memcpy(new_ptr, old_ptr, ABTU_min_size(old_size, new_size));
249  ABTU_free(old_ptr);
250  *p_ptr = new_ptr;
251  return ABT_SUCCESS;
252 }
253 
254 #else /* ABT_CONFIG_USE_ALIGNED_ALLOC */
255 
256 ABTU_ret_err static inline int ABTU_malloc(size_t size, void **p_ptr)
257 {
258  void *ptr = malloc(size);
259  if (ABTI_IS_ERROR_CHECK_ENABLED && ptr == NULL) {
260  return ABT_ERR_MEM;
261  }
262  *p_ptr = ptr;
263  return ABT_SUCCESS;
264 }
265 
266 ABTU_ret_err static inline int ABTU_calloc(size_t num, size_t size,
267  void **p_ptr)
268 {
269  void *ptr = calloc(num, size);
270  if (ABTI_IS_ERROR_CHECK_ENABLED && ptr == NULL) {
271  return ABT_ERR_MEM;
272  }
273  *p_ptr = ptr;
274  return ABT_SUCCESS;
275 }
276 
277 ABTU_ret_err static inline int ABTU_realloc(size_t old_size, size_t new_size,
278  void **p_ptr)
279 {
280  (void)old_size;
281  void *ptr = realloc(*p_ptr, new_size);
282  if (ABTI_IS_ERROR_CHECK_ENABLED && ptr == NULL) {
283  return ABT_ERR_MEM;
284  }
285  *p_ptr = ptr;
286  return ABT_SUCCESS;
287 }
288 
289 #endif /* !ABT_CONFIG_USE_ALIGNED_ALLOC */
290 
292  ABTU_MEM_LARGEPAGE_MALLOC, /* ABTU_malloc(). */
293  ABTU_MEM_LARGEPAGE_MEMALIGN, /* memalign() */
294  ABTU_MEM_LARGEPAGE_MMAP, /* normal private memory obtained by mmap() */
295  ABTU_MEM_LARGEPAGE_MMAP_HUGEPAGE, /* hugepage obtained by mmap() */
297 
298 /* Returns 1 if a given large page type is supported. */
299 int ABTU_is_supported_largepage_type(size_t size, size_t alignment_hint,
300  ABTU_MEM_LARGEPAGE_TYPE requested);
301 ABTU_ret_err int
302 ABTU_alloc_largepage(size_t size, size_t alignment_hint,
303  const ABTU_MEM_LARGEPAGE_TYPE *requested_types,
304  int num_requested_types, ABTU_MEM_LARGEPAGE_TYPE *p_actual,
305  void **p_ptr);
306 void ABTU_free_largepage(void *ptr, size_t size, ABTU_MEM_LARGEPAGE_TYPE type);
307 
308 /* String-to-integer functions. */
309 ABTU_ret_err int ABTU_atoi(const char *str, int *p_val, ABT_bool *p_overflow);
310 ABTU_ret_err int ABTU_atoui32(const char *str, uint32_t *p_val,
311  ABT_bool *p_overflow);
312 ABTU_ret_err int ABTU_atoui64(const char *str, uint64_t *p_val,
313  ABT_bool *p_overflow);
314 ABTU_ret_err int ABTU_atosz(const char *str, size_t *p_val,
315  ABT_bool *p_overflow);
316 
317 #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:999
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:240
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_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:199
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:294
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:295
ABTU_malloc
static ABTU_ret_err int ABTU_malloc(size_t size, void **p_ptr)
Definition: abtu.h:218
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:227
ABTU_MEM_LARGEPAGE_TYPE
ABTU_MEM_LARGEPAGE_TYPE
Definition: abtu.h:291
ABT_CONFIG_STATIC_CACHELINE_SIZE
#define ABT_CONFIG_STATIC_CACHELINE_SIZE
Definition: abt_config.h:69
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:292
ABTU_ret_err
#define ABTU_ret_err
Definition: abtu.h:138
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:211
ABTU_MEM_LARGEPAGE_MEMALIGN
@ ABTU_MEM_LARGEPAGE_MEMALIGN
Definition: abtu.h:293
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_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