ARGOBOTS  7496202f85916e93d6d143320764c2aba5026d93
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
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 /* Utility feature */
15 
16 #ifdef HAVE___BUILTIN_EXPECT
17 #define ABTU_likely(cond) __builtin_expect(!!(cond), 1)
18 #define ABTU_unlikely(cond) __builtin_expect(!!(cond), 0)
19 #else
20 #define ABTU_likely(cond) (cond)
21 #define ABTU_unlikely(cond) (cond)
22 #endif
23 
24 #ifdef HAVE___BUILTIN_UNREACHABLE
25 #define ABTU_unreachable() __builtin_unreachable()
26 #else
27 #define ABTU_unreachable()
28 #endif
29 
30 #ifdef HAVE_FUNC_ATTRIBUTE_NORETURN
31 #define ABTU_noreturn __attribute__((noreturn))
32 #else
33 #define ABTU_noreturn
34 #endif
35 
36 #ifdef ABT_CONFIG_HAVE_ALIGNOF_GCC
37 #define ABTU_alignof(type) (__alignof__(type))
38 #elif defined(ABT_CONFIG_HAVE_ALIGNOF_C11)
39 #define ABTU_alignof(type) (alignof(type))
40 #else
41 #define ABTU_alignof(type) 16 /* 16 bytes would be a good guess. */
42 #endif
43 #define ABTU_MAX_ALIGNMENT \
44  (ABTU_alignof(long double) > ABTU_alignof(long long) \
45  ? ABTU_alignof(long double) \
46  : ABTU_alignof(long long))
47 
48 #ifdef HAVE_FUNC_ATTRIBUTE_WARN_UNUSED_RESULT
49 #define ABTU_ret_err __attribute__((warn_unused_result))
50 #else
51 #define ABTU_ret_err
52 #endif
53 
54 /*
55  * An attribute to hint an alignment of a member variable.
56  * Usage:
57  * struct X {
58  * void *obj_1;
59  * ABTU_align_member_var(64)
60  * void *obj_2;
61  * };
62  */
63 #ifndef __SUNPRO_C
64 #define ABTU_align_member_var(size) __attribute__((aligned(size)))
65 #else
66 /* Sun Studio does not support it. */
67 #define ABTU_align_member_var(size)
68 #endif
69 
70 /*
71  * An attribute to suppress address sanitizer warning.
72  */
73 #if defined(__GNUC__) && defined(__SANITIZE_ADDRESS__)
74 /*
75  * Older GCC cannot combine no_sanitize_address + always_inline (e.g., builtin
76  * memcpy on some platforms), which causes *a compilation error*. Let's accept
77  * false-positive warning if used GCC is old. This issue seems fixed between
78  * GCC 7.4.0 and GCC 8.3.0 as far as I checked.
79  * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59600
80  */
81 #if __GNUC__ >= 8
82 #define ABTU_no_sanitize_address __attribute__((no_sanitize_address))
83 #endif
84 #elif __clang__
85 #if defined(__has_feature)
86 #if __has_feature(address_sanitizer)
87 #if __clang_major__ >= 4 || (__clang_major__ >= 3 && __clang_minor__ >= 7)
88 /* >= Clang 3.7.0 */
89 #define ABTU_no_sanitize_address __attribute__((no_sanitize("address")))
90 #elif (__clang_major__ >= 3 && __clang_minor__ >= 3)
91 /* >= Clang 3.3.0 */
92 #define ABTU_no_sanitize_address __attribute__((no_sanitize_address))
93 #elif (__clang_major__ >= 3 && __clang_minor__ >= 1)
94 /* >= Clang 3.1.0 */
95 #define ABTU_no_sanitize_address __attribute__((no_address_safety_analysis))
96 #else /* Too old clang. */
97 #define ABTU_no_sanitize_address
98 #endif
99 #endif /* __has_feature(address_sanitizer) */
100 #endif /* defined(__has_feature) */
101 #endif
102 
103 #ifndef ABTU_no_sanitize_address
104 /* We do not support other address sanitizers. */
105 #define ABTU_no_sanitize_address
106 #endif
107 
108 /* Utility Functions */
109 
110 #if defined(__ibmxl__) || defined(__xlc__)
111 
112 /* XL C/C++ compilers fail to compile these static functions correctly.
113  * See https://github.com/pmodels/argobots/issues/244 for details. */
114 
115 ABTU_ret_err int ABTU_memalign(size_t alignment, size_t size, void **p_ptr);
116 void ABTU_free(void *ptr);
117 ABTU_ret_err int ABTU_malloc(size_t size, void **p_ptr);
118 ABTU_ret_err int ABTU_calloc(size_t num, size_t size, void **p_ptr);
119 ABTU_ret_err int ABTU_realloc(size_t old_size, size_t new_size, void **p_ptr);
120 
121 #else /* !(defined(__ibmxl__) || defined(__xlc__)) */
122 
123 ABTU_ret_err static inline int ABTU_memalign(size_t alignment, size_t size,
124  void **p_ptr)
125 {
126  void *ptr;
127  int ret = posix_memalign(&ptr, alignment, size);
128  if (ABTI_IS_ERROR_CHECK_ENABLED && ret != 0) {
129  return ABT_ERR_MEM;
130  }
131  *p_ptr = ptr;
132  return ABT_SUCCESS;
133 }
134 
135 static inline void ABTU_free(void *ptr)
136 {
137  free(ptr);
138 }
139 
140 #ifdef ABT_CONFIG_USE_ALIGNED_ALLOC
141 
142 ABTU_ret_err static inline int ABTU_malloc(size_t size, void **p_ptr)
143 {
144  /* Round up to the smallest multiple of ABT_CONFIG_STATIC_CACHELINE_SIZE
145  * which is greater than or equal to size in order to avoid any
146  * false-sharing. */
147  size = (size + ABT_CONFIG_STATIC_CACHELINE_SIZE - 1) &
149  return ABTU_memalign(ABT_CONFIG_STATIC_CACHELINE_SIZE, size, p_ptr);
150 }
151 
152 ABTU_ret_err static inline int ABTU_calloc(size_t num, size_t size,
153  void **p_ptr)
154 {
155  void *ptr;
156  int ret = ABTU_malloc(num * size, &ptr);
158  return ABT_ERR_MEM;
159  }
160  memset(ptr, 0, num * size);
161  *p_ptr = ptr;
162  return ABT_SUCCESS;
163 }
164 
165 ABTU_ret_err static inline int ABTU_realloc(size_t old_size, size_t new_size,
166  void **p_ptr)
167 {
168  void *new_ptr, *old_ptr = *p_ptr;
169  int ret = ABTU_malloc(new_size, &new_ptr);
171  return ABT_ERR_MEM;
172  }
173  memcpy(new_ptr, old_ptr, (old_size < new_size) ? old_size : new_size);
174  ABTU_free(old_ptr);
175  *p_ptr = new_ptr;
176  return ABT_SUCCESS;
177 }
178 
179 #else /* ABT_CONFIG_USE_ALIGNED_ALLOC */
180 
181 ABTU_ret_err static inline int ABTU_malloc(size_t size, void **p_ptr)
182 {
183  void *ptr = malloc(size);
184  if (ABTI_IS_ERROR_CHECK_ENABLED && ptr == NULL) {
185  return ABT_ERR_MEM;
186  }
187  *p_ptr = ptr;
188  return ABT_SUCCESS;
189 }
190 
191 ABTU_ret_err static inline int ABTU_calloc(size_t num, size_t size,
192  void **p_ptr)
193 {
194  void *ptr = calloc(num, size);
195  if (ABTI_IS_ERROR_CHECK_ENABLED && ptr == NULL) {
196  return ABT_ERR_MEM;
197  }
198  *p_ptr = ptr;
199  return ABT_SUCCESS;
200 }
201 
202 ABTU_ret_err static inline int ABTU_realloc(size_t old_size, size_t new_size,
203  void **p_ptr)
204 {
205  (void)old_size;
206  void *ptr = realloc(*p_ptr, new_size);
207  if (ABTI_IS_ERROR_CHECK_ENABLED && ptr == NULL) {
208  return ABT_ERR_MEM;
209  }
210  *p_ptr = ptr;
211  return ABT_SUCCESS;
212 }
213 
214 #endif /* !ABT_CONFIG_USE_ALIGNED_ALLOC */
215 
216 #endif /* !(defined(__ibmxl__) || defined(__xlc__)) */
217 
219  ABTU_MEM_LARGEPAGE_MALLOC, /* ABTU_malloc(). */
220  ABTU_MEM_LARGEPAGE_MEMALIGN, /* memalign() */
221  ABTU_MEM_LARGEPAGE_MMAP, /* normal private memory obtained by mmap() */
222  ABTU_MEM_LARGEPAGE_MMAP_HUGEPAGE, /* hugepage obtained by mmap() */
224 
225 /* Returns 1 if a given large page type is supported. */
226 int ABTU_is_supported_largepage_type(size_t size, size_t alignment_hint,
227  ABTU_MEM_LARGEPAGE_TYPE requested);
228 ABTU_ret_err int
229 ABTU_alloc_largepage(size_t size, size_t alignment_hint,
230  const ABTU_MEM_LARGEPAGE_TYPE *requested_types,
231  int num_requested_types, ABTU_MEM_LARGEPAGE_TYPE *p_actual,
232  void **p_ptr);
233 void ABTU_free_largepage(void *ptr, size_t size, ABTU_MEM_LARGEPAGE_TYPE type);
234 
235 #endif /* ABTU_H_INCLUDED */
#define ABT_CONFIG_STATIC_CACHELINE_SIZE
Definition: abt_config.h:57
static ABTU_ret_err int ABTU_malloc(size_t size, void **p_ptr)
Definition: abtu.h:142
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
static ABTU_ret_err int ABTU_realloc(size_t old_size, size_t new_size, void **p_ptr)
Definition: abtu.h:165
static ABTU_ret_err int ABTU_memalign(size_t alignment, size_t size, void **p_ptr)
Definition: abtu.h:123
int ABTU_is_supported_largepage_type(size_t size, size_t alignment_hint, ABTU_MEM_LARGEPAGE_TYPE requested)
Definition: largepage.c:59
#define ABT_ERR_MEM
Definition: abt.h:66
#define ABT_SUCCESS
Definition: abt.h:64
void ABTU_free_largepage(void *ptr, size_t size, ABTU_MEM_LARGEPAGE_TYPE type)
Definition: largepage.c:132
ABTU_MEM_LARGEPAGE_TYPE
Definition: abtu.h:218
#define ABTI_IS_ERROR_CHECK_ENABLED
Definition: abti.h:20
static ABTU_ret_err int ABTU_calloc(size_t num, size_t size, void **p_ptr)
Definition: abtu.h:152
static void ABTU_free(void *ptr)
Definition: abtu.h:135
#define ABTU_ret_err
Definition: abtu.h:49