8 #ifdef ABT_CONFIG_ENABLE_STACK_UNWIND
10 #include <libunwind.h>
11 struct unwind_stack_t {
14 static void ythread_unwind_stack(
void *arg);
24 ABTI_ythread *p_prev = (ABTI_ythread *)arg;
25 if (ABTI_thread_handle_request(&p_prev->thread,
ABT_TRUE) &
26 ABTI_THREAD_HANDLE_REQUEST_CANCELLED) {
30 ABTI_pool_add_thread(&p_prev->thread, context);
34 void ABTI_ythread_callback_yield_user_yield(
void *arg)
39 void ABTI_ythread_callback_yield_loop(
void *arg)
44 void ABTI_ythread_callback_yield_user_yield_to(
void *arg)
49 void ABTI_ythread_callback_yield_create_to(
void *arg)
54 void ABTI_ythread_callback_yield_revive_to(
void *arg)
61 void ABTI_ythread_callback_thread_yield_to(
void *arg)
63 ABTI_ythread *p_prev = (ABTI_ythread *)arg;
68 ABTI_pool *p_pool = p_prev->thread.p_pool;
69 if (ABTI_thread_handle_request(&p_prev->thread,
ABT_TRUE) &
70 ABTI_THREAD_HANDLE_REQUEST_CANCELLED) {
74 ABTI_pool_add_thread(&p_prev->thread,
80 ABTI_pool_dec_num_blocked(p_pool);
83 void ABTI_ythread_callback_resume_yield_to(
void *arg)
85 ABTI_ythread_callback_resume_yield_to_arg *p_arg =
86 (ABTI_ythread_callback_resume_yield_to_arg *)arg;
89 ABTI_ythread *p_prev = p_arg->p_prev;
90 ABTI_ythread *p_next = p_arg->p_next;
91 if (ABTI_thread_handle_request(&p_prev->thread,
ABT_TRUE) &
92 ABTI_THREAD_HANDLE_REQUEST_CANCELLED) {
96 ABTI_pool_add_thread(&p_prev->thread,
100 ABTI_pool_dec_num_blocked(p_next->thread.p_pool);
103 void ABTI_ythread_callback_suspend(
void *arg)
105 ABTI_ythread *p_prev = (ABTI_ythread *)arg;
108 ABTI_pool_inc_num_blocked(p_prev->thread.p_pool);
110 ABTI_thread_handle_request(&p_prev->thread,
ABT_FALSE);
112 ABTD_atomic_release_store_int(&p_prev->thread.state,
116 void ABTI_ythread_callback_resume_suspend_to(
void *arg)
118 ABTI_ythread_callback_resume_suspend_to_arg *p_arg =
119 (ABTI_ythread_callback_resume_suspend_to_arg *)arg;
122 ABTI_ythread *p_prev = p_arg->p_prev;
123 ABTI_ythread *p_next = p_arg->p_next;
124 ABTI_pool *p_prev_pool = p_prev->thread.p_pool;
125 ABTI_pool *p_next_pool = p_next->thread.p_pool;
126 if (p_prev_pool != p_next_pool) {
128 ABTI_pool_inc_num_blocked(p_prev_pool);
130 ABTI_pool_dec_num_blocked(p_next_pool);
133 ABTI_thread_handle_request(&p_prev->thread,
ABT_FALSE);
135 ABTD_atomic_release_store_int(&p_prev->thread.state,
139 void ABTI_ythread_callback_exit(
void *arg)
142 ABTI_ythread *p_prev = (ABTI_ythread *)arg;
143 ABTI_thread_terminate(ABTI_global_get_global(),
144 p_prev->thread.p_last_xstream, &p_prev->thread);
147 void ABTI_ythread_callback_resume_exit_to(
void *arg)
149 ABTI_ythread_callback_resume_exit_to_arg *p_arg =
150 (ABTI_ythread_callback_resume_exit_to_arg *)arg;
153 ABTI_ythread *p_prev = p_arg->p_prev;
154 ABTI_ythread *p_next = p_arg->p_next;
156 ABTI_thread_terminate(ABTI_global_get_global(),
157 p_prev->thread.p_last_xstream, &p_prev->thread);
159 ABTI_pool_dec_num_blocked(p_next->thread.p_pool);
162 void ABTI_ythread_callback_suspend_unlock(
void *arg)
164 ABTI_ythread_callback_suspend_unlock_arg *p_arg =
165 (ABTI_ythread_callback_suspend_unlock_arg *)arg;
168 ABTI_ythread *p_prev = p_arg->p_prev;
169 ABTD_spinlock *p_lock = p_arg->p_lock;
171 ABTI_pool_inc_num_blocked(p_prev->thread.p_pool);
173 ABTI_thread_handle_request(&p_prev->thread,
ABT_FALSE);
175 ABTD_atomic_release_store_int(&p_prev->thread.state,
178 ABTD_spinlock_release(p_lock);
181 void ABTI_ythread_callback_suspend_join(
void *arg)
183 ABTI_ythread_callback_suspend_join_arg *p_arg =
184 (ABTI_ythread_callback_suspend_join_arg *)arg;
187 ABTI_ythread *p_prev = p_arg->p_prev;
188 ABTI_ythread *p_target = p_arg->p_target;
190 ABTI_pool_inc_num_blocked(p_prev->thread.p_pool);
192 ABTI_thread_handle_request(&p_prev->thread,
ABT_FALSE);
194 ABTD_atomic_release_store_int(&p_prev->thread.state,
199 ABTD_atomic_release_store_ythread_context_ptr(&p_target->ctx.p_link,
203 void ABTI_ythread_callback_suspend_replace_sched(
void *arg)
205 ABTI_ythread_callback_suspend_replace_sched_arg *p_arg =
206 (ABTI_ythread_callback_suspend_replace_sched_arg *)arg;
209 ABTI_ythread *p_prev = p_arg->p_prev;
210 ABTI_sched *p_main_sched = p_arg->p_main_sched;
212 ABTI_pool_inc_num_blocked(p_prev->thread.p_pool);
214 ABTI_thread_handle_request(&p_prev->thread,
ABT_FALSE);
216 ABTD_atomic_release_store_int(&p_prev->thread.state,
219 ABTI_sched_set_request(p_main_sched, ABTI_SCHED_REQ_REPLACE);
222 void ABTI_ythread_callback_orphan(
void *arg)
225 ABTI_ythread *p_prev = (ABTI_ythread *)arg;
226 ABTI_thread_unset_associated_pool(ABTI_global_get_global(),
231 ABTI_ythread *p_ythread,
234 ABTD_ythread_print_context(p_ythread, p_os, 0);
237 "stacksize : %" PRIu64
"\n",
238 ABTD_ythread_context_get_stacktop(&p_ythread->ctx),
239 (uint64_t)ABTD_ythread_context_get_stacksize(&p_ythread->ctx));
241 #ifdef ABT_CONFIG_ENABLE_STACK_UNWIND
246 &p_ythread->thread.state);
249 struct unwind_stack_t arg;
252 ABTI_ythread_context_peek(p_ythread, ythread_unwind_stack,
255 fprintf(p_os,
"not executed yet.\n");
258 fprintf(p_os,
"failed to unwind a stack.\n");
263 void *p_stacktop = ABTD_ythread_context_get_stacktop(&p_ythread->ctx);
265 stacksize = ABTD_ythread_context_get_stacksize(&p_ythread->ctx);
266 if (stacksize == 0 || p_stacktop == NULL) {
268 fprintf(p_os,
"no stack\n");
272 if (p_global->print_raw_stack) {
273 void *p_stack = (
void *)(((
char *)p_stacktop) - stacksize);
275 const size_t value_width = 8;
276 const int num_bytes =
sizeof(buffer);
277 static const char zero[
sizeof(buffer)];
280 for (i = 0; i < stacksize; i += num_bytes) {
281 if (stacksize >= i + num_bytes) {
282 memcpy(buffer, &((uint8_t *)p_stack)[i], num_bytes);
284 memset(buffer, 0, num_bytes);
285 memcpy(buffer, &((uint8_t *)p_stack)[i], stacksize - i);
289 if (!memcmp(zero, buffer,
sizeof(buffer))) {
299 fprintf(p_os,
"*\n");
305 #if SIZEOF_VOID_P == 8
306 fprintf(p_os,
"%016" PRIxPTR
":",
307 (uintptr_t)(&((uint8_t *)p_stack)[i]));
308 #elif SIZEOF_VOID_P == 4
309 fprintf(p_os,
"%08" PRIxPTR
":",
310 (uintptr_t)(&((uint8_t *)p_stack)[i]));
312 #error "unknown pointer size"
315 for (j = 0; j < num_bytes / value_width; j++) {
316 if (value_width == 8) {
317 uint64_t val = ((uint64_t *)buffer)[j];
318 fprintf(p_os,
" %016" PRIx64, val);
319 }
else if (value_width == 4) {
320 uint32_t val = ((uint32_t *)buffer)[j];
321 fprintf(p_os,
" %08" PRIx32, val);
322 }
else if (value_width == 2) {
323 uint16_t val = ((uint16_t *)buffer)[j];
324 fprintf(p_os,
" %04" PRIx16, val);
326 uint8_t val = ((uint8_t *)buffer)[j];
327 fprintf(p_os,
" %02" PRIx8, val);
329 if (j == (num_bytes / value_width) - 1)
341 #ifdef ABT_CONFIG_ENABLE_STACK_UNWIND
349 ret = unw_getcontext(&uc);
353 ret = unw_init_local(&cursor, &uc);
357 while (unw_step(&cursor) > 0 && level < 50) {
360 ret = unw_get_reg(&cursor, UNW_REG_IP, &ip);
364 ret = unw_get_reg(&cursor, UNW_REG_SP, &sp);
370 ret = unw_get_proc_name(&cursor, proc_name, 256, &offset);
375 fprintf(fp,
"#%d %p in %s () <+%d> (%s = %p)\n", level,
376 (
void *)((uintptr_t)ip), proc_name, (
int)offset,
377 unw_regname(UNW_REG_SP), (
void *)((uintptr_t)sp));
382 static void ythread_unwind_stack(
void *arg)
384 struct unwind_stack_t *p_arg = (
struct unwind_stack_t *)arg;
385 if (ythread_unwind_stack_impl(p_arg->fp) !=
ABT_SUCCESS) {
386 fprintf(p_arg->fp,
"libunwind error\n");