6 #ifndef ABTI_MEM_H_INCLUDED 7 #define ABTI_MEM_H_INCLUDED 12 #define ABTI_MEM_SH_SIZE \ 13 (((sizeof(ABTI_thread) + sizeof(ABTI_stack_header) + \ 14 ABT_CONFIG_STATIC_CACHELINE_SIZE - 1) / \ 15 ABT_CONFIG_STATIC_CACHELINE_SIZE) * \ 16 ABT_CONFIG_STATIC_CACHELINE_SIZE) 18 #ifdef ABT_CONFIG_USE_MEM_POOL 19 typedef struct ABTI_blk_header ABTI_blk_header;
22 ABTI_MEM_LP_MALLOC = 0,
24 ABTI_MEM_LP_MMAP_HP_RP,
25 ABTI_MEM_LP_MMAP_HP_THP,
29 struct ABTI_sp_header {
30 uint32_t num_total_stacks;
31 ABTD_atomic_uint32 num_empty_stacks;
36 ABTI_sp_header *p_next;
39 struct ABTI_stack_header {
40 ABTI_stack_header *p_next;
41 ABTI_sp_header *p_sph;
45 struct ABTI_page_header {
47 uint32_t num_total_blks;
48 uint32_t num_empty_blks;
49 ABTD_atomic_uint32 num_remote_free;
50 ABTI_blk_header *p_head;
51 ABTI_blk_header *p_free;
52 ABTI_native_thread_id owner_id;
53 ABTI_page_header *p_prev;
54 ABTI_page_header *p_next;
58 struct ABTI_blk_header {
59 ABTI_page_header *p_ph;
60 ABTI_blk_header *p_next;
63 void ABTI_mem_init(ABTI_global *p_global);
64 void ABTI_mem_init_local(ABTI_local *p_local);
65 void ABTI_mem_finalize(ABTI_global *p_global);
66 void ABTI_mem_finalize_local(ABTI_local *p_local);
67 int ABTI_mem_check_lp_alloc(
int lp_alloc);
69 char *ABTI_mem_take_global_stack(ABTI_local *p_local);
70 void ABTI_mem_add_stack_to_global(ABTI_stack_header *p_sh);
71 ABTI_page_header *ABTI_mem_alloc_page(ABTI_local *p_local,
size_t blk_size);
72 void ABTI_mem_free_page(ABTI_local *p_local, ABTI_page_header *p_ph);
73 void ABTI_mem_take_free(ABTI_page_header *p_ph);
74 void ABTI_mem_free_remote(ABTI_page_header *p_ph, ABTI_blk_header *p_bh);
75 ABTI_page_header *ABTI_mem_take_global_page(ABTI_local *p_local);
77 char *ABTI_mem_alloc_sp(ABTI_local *p_local,
size_t stacksize);
97 static inline ABTI_thread *
98 ABTI_mem_alloc_thread_with_stacksize(
size_t stacksize, ABTI_thread_attr *p_attr)
100 size_t actual_stacksize;
102 ABTI_thread *p_thread;
106 actual_stacksize = stacksize -
sizeof(ABTI_thread);
113 p_thread = (ABTI_thread *)p_blk;
114 p_stack = (
void *)(p_blk +
sizeof(ABTI_thread));
119 ABTI_thread_attr_copy(&p_thread->attr, p_attr);
120 p_thread->attr.stacksize = actual_stacksize;
121 p_thread->attr.p_stack = p_stack;
122 p_thread->attr.stacktype = ABTI_STACK_TYPE_MALLOC;
125 ABTI_thread_attr_init(&p_thread->attr, p_stack, actual_stacksize,
129 ABTI_VALGRIND_REGISTER_STACK(p_thread->attr.p_stack, actual_stacksize);
133 static inline ABTI_thread *ABTI_mem_alloc_thread(ABTI_local *p_local,
134 ABTI_thread_attr *p_attr)
140 size_t stacksize, def_stacksize, actual_stacksize;
142 ABTI_thread *p_thread;
143 ABTI_stack_header *p_sh;
147 def_stacksize = ABTI_global_get_thread_stacksize();
148 if (p_attr == NULL) {
149 stacksize = def_stacksize;
151 #ifndef ABT_CONFIG_DISABLE_EXT_THREAD 153 if (p_local == NULL) {
154 return ABTI_mem_alloc_thread_with_stacksize(stacksize, NULL);
159 ABTI_stack_type stacktype = p_attr->stacktype;
160 if (stacktype == ABTI_STACK_TYPE_USER ||
161 stacktype == ABTI_STACK_TYPE_MAIN) {
164 p_thread = (ABTI_thread *)
ABTU_malloc(
sizeof(ABTI_thread));
165 ABTI_thread_attr_copy(&p_thread->attr, p_attr);
167 if (p_attr->stacktype != ABTI_STACK_TYPE_MAIN) {
168 ABTI_VALGRIND_REGISTER_STACK(p_thread->attr.p_stack,
174 stacksize = p_attr->stacksize;
175 if (stacksize != def_stacksize || stacktype == ABTI_STACK_TYPE_MALLOC) {
178 return ABTI_mem_alloc_thread_with_stacksize(stacksize, p_attr);
183 if (p_local->p_mem_stack) {
185 p_sh = p_local->p_mem_stack;
186 p_local->p_mem_stack = p_sh->p_next;
187 p_local->num_stacks--;
190 p_blk = (
char *)p_sh -
sizeof(ABTI_thread);
195 p_blk = ABTI_mem_take_global_stack(p_local);
197 p_blk = ABTI_mem_alloc_sp(p_local, stacksize);
201 p_blk = ABTI_mem_alloc_sp(p_local, stacksize);
204 p_sh = (ABTI_stack_header *)(p_blk +
sizeof(ABTI_thread));
209 actual_stacksize = stacksize - ABTI_MEM_SH_SIZE;
212 p_thread = (ABTI_thread *)p_blk;
213 p_stack = p_sh->p_stack;
216 if (p_attr == NULL) {
217 ABTI_thread_attr *p_myattr = &p_thread->attr;
218 ABTI_thread_attr_init(p_myattr, p_stack, actual_stacksize,
221 ABTI_thread_attr_copy(&p_thread->attr, p_attr);
222 p_thread->attr.stacksize = actual_stacksize;
223 p_thread->attr.p_stack = p_stack;
226 ABTI_VALGRIND_REGISTER_STACK(p_thread->attr.p_stack, actual_stacksize);
230 static inline void ABTI_mem_free_thread(ABTI_local *p_local,
231 ABTI_thread *p_thread)
233 ABTI_stack_header *p_sh;
234 ABTI_VALGRIND_UNREGISTER_STACK(p_thread->attr.p_stack);
236 if (p_thread->attr.stacktype != ABTI_STACK_TYPE_MEMPOOL) {
240 p_sh = (ABTI_stack_header *)((
char *)p_thread +
sizeof(ABTI_thread));
242 #ifndef ABT_CONFIG_DISABLE_EXT_THREAD 246 ABTI_mem_add_stack_to_global(p_sh);
252 p_sh->p_next = p_local->p_mem_stack;
253 p_local->p_mem_stack = p_sh;
254 p_local->num_stacks++;
256 ABTI_mem_add_stack_to_global(p_sh);
260 static inline ABTI_task *ABTI_mem_alloc_task(ABTI_local *p_local)
262 ABTI_task *p_task = NULL;
263 const size_t blk_size =
sizeof(ABTI_blk_header) +
sizeof(ABTI_task);
265 #ifndef ABT_CONFIG_DISABLE_EXT_THREAD 266 if (p_local == NULL) {
269 ABTI_blk_header *p_blk_header = (ABTI_blk_header *)p_blk;
270 p_blk_header->p_ph = NULL;
271 p_task = (ABTI_task *)(p_blk +
sizeof(ABTI_blk_header));
277 ABTI_page_header *p_ph = p_local->p_mem_task_head;
282 ABTI_mem_take_free(p_ph);
287 if (p_ph == p_local->p_mem_task_head) {
297 p_ph = ABTI_mem_take_global_page(p_local);
299 p_ph = ABTI_mem_alloc_page(p_local, blk_size);
303 p_ph = ABTI_mem_alloc_page(p_local, blk_size);
307 ABTI_blk_header *p_head = p_ph->p_head;
308 p_ph->p_head = p_head->p_next;
309 p_ph->num_empty_blks--;
311 p_task = (ABTI_task *)((
char *)p_head +
sizeof(ABTI_blk_header));
316 static inline void ABTI_mem_free_task(ABTI_local *p_local, ABTI_task *p_task)
318 ABTI_blk_header *p_head;
319 ABTI_page_header *p_ph;
321 p_head = (ABTI_blk_header *)((
char *)p_task -
sizeof(ABTI_blk_header));
324 #ifndef ABT_CONFIG_DISABLE_EXT_THREAD 329 }
else if (!p_local) {
332 ABTI_mem_free_remote(p_ph, p_head);
337 if (p_ph->owner_id == ABTI_self_get_native_thread_id(p_local)) {
338 p_head->p_next = p_ph->p_head;
339 p_ph->p_head = p_head;
340 p_ph->num_empty_blks++;
346 ABTI_mem_free_remote(p_ph, p_head);
352 #define ABTI_mem_init(p) 353 #define ABTI_mem_init_local(p) 354 #define ABTI_mem_finalize(p) 355 #define ABTI_mem_finalize_local(p) 357 static inline ABTI_thread *
358 ABTI_mem_alloc_thread_with_stacksize(
size_t *p_stacksize)
360 size_t stacksize, actual_stacksize;
363 ABTI_thread *p_thread;
366 stacksize = *p_stacksize;
367 actual_stacksize = stacksize -
sizeof(ABTI_thread);
371 p_thread = (ABTI_thread *)p_blk;
372 p_stack = (
void *)(p_blk +
sizeof(ABTI_thread));
375 ABTI_thread_attr *p_myattr = &p_thread->attr;
376 ABTI_thread_attr_init(p_myattr, p_stack, actual_stacksize,
379 *p_stacksize = actual_stacksize;
380 ABTI_VALGRIND_REGISTER_STACK(p_thread->attr.p_stack, *p_stacksize);
387 ABTI_thread *p_thread;
390 *p_stacksize = ABTI_global_get_thread_stacksize();
391 return ABTI_mem_alloc_thread_with_stacksize(p_stacksize);
395 ABTI_thread_attr *p_attr = ABTI_thread_attr_get_ptr(attr);
396 if (p_attr->p_stack == NULL) {
397 ABTI_ASSERT(p_attr->userstack ==
ABT_FALSE);
399 char *p_blk = (
char *)
ABTU_malloc(p_attr->stacksize);
400 p_thread = (ABTI_thread *)p_blk;
402 ABTI_thread_attr_copy(&p_thread->attr, p_attr);
403 p_thread->attr.stacksize -=
sizeof(ABTI_thread);
404 p_thread->attr.p_stack = (
void *)(p_blk +
sizeof(ABTI_thread));
410 p_thread = (ABTI_thread *)
ABTU_malloc(
sizeof(ABTI_thread));
411 ABTI_thread_attr_copy(&p_thread->attr, p_attr);
414 *p_stacksize = p_thread->attr.stacksize;
418 static inline ABTI_thread *ABTI_mem_alloc_main_thread(
ABT_thread_attr attr)
420 ABTI_thread *p_thread;
422 p_thread = (ABTI_thread *)
ABTU_malloc(
sizeof(ABTI_thread));
426 ABTI_thread_attr *p_attr = &p_thread->attr;
427 ABTI_thread_attr_init(p_attr, NULL, 0, ABTI_STACK_TYPE_MAIN,
ABT_FALSE);
432 static inline void ABTI_mem_free_thread(ABTI_thread *p_thread)
434 ABTI_VALGRIND_UNREGISTER_STACK(p_thread->attr.p_stack);
438 static inline ABTI_task *ABTI_mem_alloc_task(
void)
440 return (ABTI_task *)
ABTU_malloc(
sizeof(ABTI_task));
443 static inline void ABTI_mem_free_task(ABTI_task *p_task)
struct ABT_thread_attr_opaque * ABT_thread_attr
static void * ABTU_malloc(size_t size)
ABTI_global * gp_ABTI_global
#define ABT_THREAD_ATTR_NULL
static void ABTU_free(void *ptr)