ARGOBOTS  dce6e727ffc4ca5b3ffc04cb9517c6689be51ec5
info.c
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 #include "abti.h"
7 
8 ABTU_ret_err static int info_print_thread_stacks_in_pool(ABTI_global *p_global,
9  FILE *fp,
10  ABTI_pool *p_pool);
12  FILE *fp, double timeout, void (*cb_func)(ABT_bool, void *), void *arg);
13 
216 int ABT_info_query_config(ABT_info_query_kind query_kind, void *val)
217 {
218  ABTI_UB_ASSERT(val);
219 
220 #ifndef ABT_CONFIG_ENABLE_VER_20_API
221  /* Argobots 1.x always requires an init check. */
222  ABTI_SETUP_GLOBAL(NULL);
223 #endif
224  switch (query_kind) {
226  ABTI_global *p_global = ABTI_global_get_global_or_null();
227  if (p_global) {
228  *((ABT_bool *)val) = p_global->use_debug;
229  } else {
230  *((ABT_bool *)val) = ABTD_env_get_use_debug();
231  }
232  } break;
234 #ifdef ABT_CONFIG_PRINT_ABT_ERRNO
235  *((ABT_bool *)val) = ABT_TRUE;
236 #else
237  *((ABT_bool *)val) = ABT_FALSE;
238 #endif
239  break;
241  ABTI_global *p_global = ABTI_global_get_global_or_null();
242  if (p_global) {
243  *((ABT_bool *)val) = p_global->use_logging;
244  } else {
245  *((ABT_bool *)val) = ABTD_env_get_use_logging();
246  }
247  } break;
249 #ifdef HAVE_VALGRIND_SUPPORT
250  *((ABT_bool *)val) = ABT_TRUE;
251 #else
252  *((ABT_bool *)val) = ABT_FALSE;
253 #endif
254  break;
256 #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK
257  *((ABT_bool *)val) = ABT_TRUE;
258 #else
259  *((ABT_bool *)val) = ABT_FALSE;
260 #endif
261  break;
263  *((ABT_bool *)val) = ABT_FALSE;
264  break;
266  *((ABT_bool *)val) = ABT_FALSE;
267  break;
269 #if !defined(ABTD_FCONTEXT_PRESERVE_FPU) && defined(ABT_CONFIG_USE_FCONTEXT)
270  *((ABT_bool *)val) = ABT_FALSE;
271 #else
272  /* If ucontext is used, FPU is preserved. */
273  *((ABT_bool *)val) = ABT_TRUE;
274 #endif
275  break;
277 #ifndef ABT_CONFIG_DISABLE_CANCELLATION
278  *((ABT_bool *)val) = ABT_TRUE;
279 #else
280  *((ABT_bool *)val) = ABT_FALSE;
281 #endif
282  break;
284 #ifndef ABT_CONFIG_DISABLE_CANCELLATION
285  *((ABT_bool *)val) = ABT_TRUE;
286 #else
287  *((ABT_bool *)val) = ABT_FALSE;
288 #endif
289  break;
291 #ifndef ABT_CONFIG_DISABLE_MIGRATION
292  *((ABT_bool *)val) = ABT_TRUE;
293 #else
294  *((ABT_bool *)val) = ABT_FALSE;
295 #endif
296  break;
298  *((ABT_bool *)val) = ABT_TRUE;
299  break;
301 #ifndef ABT_CONFIG_DISABLE_EXT_THREAD
302  *((ABT_bool *)val) = ABT_TRUE;
303 #else
304  *((ABT_bool *)val) = ABT_FALSE;
305 #endif
306  break;
308 #ifdef ABT_CONFIG_USE_SCHED_SLEEP
309  *((ABT_bool *)val) = ABT_TRUE;
310 #else
311  *((ABT_bool *)val) = ABT_FALSE;
312 #endif
313  break;
315  ABTI_global *p_global = ABTI_global_get_global_or_null();
316  if (p_global) {
317  *((ABT_bool *)val) = p_global->print_config;
318  } else {
319  *((ABT_bool *)val) = ABTD_env_get_print_config();
320  }
321  } break;
323  ABTI_global *p_global;
324  /* This check needs runtime check in ABT_init(). */
325  ABTI_SETUP_GLOBAL(&p_global);
326  *((ABT_bool *)val) = p_global->set_affinity;
327  } break;
329  ABTI_global *p_global = ABTI_global_get_global_or_null();
330  if (p_global) {
331  *((unsigned int *)val) = p_global->max_xstreams;
332  } else {
333  *((unsigned int *)val) = ABTD_env_get_max_xstreams();
334  }
335  } break;
337  ABTI_global *p_global = ABTI_global_get_global_or_null();
338  if (p_global) {
339  *((size_t *)val) = p_global->thread_stacksize;
340  } else {
341  *((size_t *)val) = ABTD_env_get_thread_stacksize();
342  }
343  } break;
345  ABTI_global *p_global = ABTI_global_get_global_or_null();
346  if (p_global) {
347  *((size_t *)val) = p_global->sched_stacksize;
348  } else {
349  *((size_t *)val) = ABTD_env_get_sched_stacksize();
350  }
351  } break;
353  ABTI_global *p_global = ABTI_global_get_global_or_null();
354  if (p_global) {
355  *((uint64_t *)val) = p_global->sched_event_freq;
356  } else {
357  *((uint64_t *)val) = ABTD_env_get_sched_event_freq();
358  }
359  } break;
361  ABTI_global *p_global = ABTI_global_get_global_or_null();
362  if (p_global) {
363  *((uint64_t *)val) = p_global->sched_sleep_nsec;
364  } else {
365  *((uint64_t *)val) = ABTD_env_get_sched_sleep_nsec();
366  }
367  } break;
369 #ifndef ABT_CONFIG_DISABLE_TOOL_INTERFACE
370  *((ABT_bool *)val) = ABT_TRUE;
371 #else
372  *((ABT_bool *)val) = ABT_FALSE;
373 #endif
374  break;
376 #ifdef ABT_CONFIG_USE_FCONTEXT
377  *((ABT_bool *)val) = ABT_TRUE;
378 #else
379  *((ABT_bool *)val) = ABT_FALSE;
380 #endif
381  break;
383  *((ABT_bool *)val) = ABT_FALSE;
384  break;
386 #ifdef ABT_CONFIG_ENABLE_STACK_UNWIND
387  *((ABT_bool *)val) = ABT_TRUE;
388 #else
389  *((ABT_bool *)val) = ABT_FALSE;
390 #endif
391  break;
393  ABTI_global *p_global = ABTI_global_get_global_or_null();
394  if (p_global) {
395  if (p_global->stack_guard_kind == ABTI_STACK_GUARD_MPROTECT) {
396  *((int *)val) = 2;
397  } else if (p_global->stack_guard_kind ==
398  ABTI_STACK_GUARD_MPROTECT_STRICT) {
399  *((int *)val) = 3;
400  } else {
401 #if ABT_CONFIG_STACK_CHECK_TYPE == ABTI_STACK_CHECK_TYPE_CANARY
402  *((int *)val) = 1;
403 #else
404  *((int *)val) = 0;
405 #endif
406  }
407  } else {
408  ABT_bool is_strict;
409  if (ABTD_env_get_stack_guard_mprotect(&is_strict)) {
410  if (is_strict) {
411  *((int *)val) = 3;
412  } else {
413  *((int *)val) = 2;
414  }
415  } else {
416 #if ABT_CONFIG_STACK_CHECK_TYPE == ABTI_STACK_CHECK_TYPE_CANARY
417  *((int *)val) = 1;
418 #else
419  *((int *)val) = 0;
420 #endif
421  }
422  }
423  } break;
425 #if ABT_CONFIG_ACTIVE_WAIT_POLICY
426  *((int *)val) = 1;
427 #else
428  *((int *)val) = 0;
429 #endif
430  break;
432 #ifdef ABT_CONFIG_DISABLE_LAZY_STACK_ALLOC
433  *((ABT_bool *)val) = ABT_FALSE;
434 #else
435  *((ABT_bool *)val) = ABT_TRUE;
436 #endif
437  break;
438  default:
439  ABTI_HANDLE_ERROR(ABT_ERR_INV_QUERY_KIND);
440  }
441  return ABT_SUCCESS;
442 }
443 
474 {
475  ABTI_UB_ASSERT(fp);
476 
477  ABTI_global *p_global;
478 #ifndef ABT_CONFIG_ENABLE_VER_20_API
479  /* Argobots 1.x always requires an init check. */
480  ABTI_SETUP_GLOBAL(&p_global);
481 #else
482  p_global = ABTI_global_get_global_or_null();
483  if (!p_global) {
484  fprintf(fp, "Argobots is not initialized.\n");
485  fflush(fp);
486  return ABT_SUCCESS;
487  }
488 #endif
489  ABTI_info_print_config(p_global, fp);
490  return ABT_SUCCESS;
491 }
492 
523 {
524  ABTI_UB_ASSERT(fp);
525 
526  ABTI_global *p_global;
527 #ifndef ABT_CONFIG_ENABLE_VER_20_API
528  /* Argobots 1.x always requires an init check. */
529  ABTI_SETUP_GLOBAL(&p_global);
530 #else
531  p_global = ABTI_global_get_global_or_null();
532  if (!p_global) {
533  fprintf(fp, "Argobots is not initialized.\n");
534  fflush(fp);
535  return ABT_SUCCESS;
536  }
537 #endif
538 
539  ABTD_spinlock_acquire(&p_global->xstream_list_lock);
540 
541  fprintf(fp, "# of created ESs: %d\n", p_global->num_xstreams);
542 
543  ABTI_xstream *p_xstream = p_global->p_xstream_head;
544  while (p_xstream) {
545  ABTI_xstream_print(p_xstream, fp, 0, ABT_FALSE);
546  p_xstream = p_xstream->p_next;
547  }
548 
549  ABTD_spinlock_release(&p_global->xstream_list_lock);
550 
551  fflush(fp);
552  return ABT_SUCCESS;
553 }
554 
585 int ABT_info_print_xstream(FILE *fp, ABT_xstream xstream)
586 {
587  ABTI_UB_ASSERT(fp);
588 
589  ABTI_xstream *p_xstream = ABTI_xstream_get_ptr(xstream);
590 #ifndef ABT_CONFIG_ENABLE_VER_20_API
591  /* Argobots 1.x requires a NULL-handle check. */
592  ABTI_CHECK_NULL_XSTREAM_PTR(p_xstream);
593 #endif
594  ABTI_xstream_print(p_xstream, fp, 0, ABT_FALSE);
595  return ABT_SUCCESS;
596 }
597 
628 int ABT_info_print_sched(FILE *fp, ABT_sched sched)
629 {
630  ABTI_UB_ASSERT(fp);
631 
632  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
633 #ifndef ABT_CONFIG_ENABLE_VER_20_API
634  /* Argobots 1.x requires a NULL-handle check. */
635  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
636 #endif
637  ABTI_sched_print(p_sched, fp, 0, ABT_TRUE);
638  return ABT_SUCCESS;
639 }
640 
671 int ABT_info_print_pool(FILE *fp, ABT_pool pool)
672 {
673  ABTI_UB_ASSERT(fp);
674 
675  ABTI_pool *p_pool = ABTI_pool_get_ptr(pool);
676 #ifndef ABT_CONFIG_ENABLE_VER_20_API
677  /* Argobots 1.x requires a NULL-handle check. */
678  ABTI_CHECK_NULL_POOL_PTR(p_pool);
679 #endif
680  ABTI_pool_print(p_pool, fp, 0);
681  return ABT_SUCCESS;
682 }
683 
718 int ABT_info_print_thread(FILE *fp, ABT_thread thread)
719 {
720  ABTI_UB_ASSERT(fp);
721 
722  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
723 #ifndef ABT_CONFIG_ENABLE_VER_20_API
724  /* Argobots 1.x requires a NULL-handle check. */
725  ABTI_CHECK_NULL_THREAD_PTR(p_thread);
726 #endif
727  ABTI_thread_print(p_thread, fp, 0);
728  return ABT_SUCCESS;
729 }
730 
762 {
763  ABTI_UB_ASSERT(fp);
764 
765  ABTI_thread_attr *p_attr = ABTI_thread_attr_get_ptr(attr);
766 #ifndef ABT_CONFIG_ENABLE_VER_20_API
767  /* Argobots 1.x requires a NULL-handle check. */
768  ABTI_CHECK_NULL_THREAD_ATTR_PTR(p_attr);
769 #endif
770  ABTI_thread_attr_print(p_attr, fp, 0);
771  return ABT_SUCCESS;
772 }
773 
809 int ABT_info_print_task(FILE *fp, ABT_task task)
810 {
811  ABTI_UB_ASSERT(fp);
812 
813  ABTI_thread *p_thread = ABTI_thread_get_ptr(task);
814 #ifndef ABT_CONFIG_ENABLE_VER_20_API
815  /* Argobots 1.x requires a NULL-handle check. */
816  ABTI_CHECK_NULL_TASK_PTR(p_thread);
817 #endif
818  ABTI_thread_print(p_thread, fp, 0);
819  return ABT_SUCCESS;
820 }
821 
857 int ABT_info_print_thread_stack(FILE *fp, ABT_thread thread)
858 {
859  ABTI_UB_ASSERT(fp);
860  /* We can check if thread is running or not in ABTI_UB_ASSERT(), but as this
861  * info function is basically used for debugging, printing a corrupted stack
862  * or even crashing a program would be fine. */
863 
864  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
865 #ifndef ABT_CONFIG_ENABLE_VER_20_API
866  /* Argobots 1.x requires a NULL-handle check. */
867  ABTI_CHECK_NULL_THREAD_PTR(p_thread);
868 #endif
869  if (!p_thread) {
870  fprintf(fp, "no stack\n");
871  fflush(0);
872  } else {
873  if (p_thread->type & ABTI_THREAD_TYPE_YIELDABLE) {
874  ABTI_global *p_global = ABTI_global_get_global_or_null();
875  if (!p_global) {
876  fprintf(fp, "Argobots is not initialized.\n");
877  fflush(0);
878  } else {
879  ABTI_ythread *p_ythread = ABTI_thread_get_ythread(p_thread);
880  ABTI_ythread_print_stack(p_global, p_ythread, fp);
881  }
882  } else {
883  fprintf(fp, "no stack\n");
884  fflush(0);
885  }
886  }
887  return ABT_SUCCESS;
888 }
889 
923 {
924  ABTI_UB_ASSERT(fp);
925 
926  ABTI_pool *p_pool = ABTI_pool_get_ptr(pool);
927 #ifndef ABT_CONFIG_ENABLE_VER_20_API
928  /* Argobots 1.x requires a NULL-handle check. */
929  ABTI_CHECK_NULL_POOL_PTR(p_pool);
930 #endif
931  ABTI_global *p_global = ABTI_global_get_global_or_null();
932  if (!p_global) {
933  fprintf(fp, "Argobots is not initialized.\n");
934  fflush(0);
935  } else {
936  int abt_errno = info_print_thread_stacks_in_pool(p_global, fp, p_pool);
937  ABTI_CHECK_ERROR(abt_errno);
938  }
939  return ABT_SUCCESS;
940 }
941 
1006 int ABT_info_trigger_print_all_thread_stacks(FILE *fp, double timeout,
1007  void (*cb_func)(ABT_bool, void *),
1008  void *arg)
1010  /* assert() is not signal safe, so we cannot validate variables. */
1011  info_trigger_print_all_thread_stacks(fp, timeout, cb_func, arg);
1012  return ABT_SUCCESS;
1013 }
1014 
1015 /*****************************************************************************/
1016 /* Private APIs */
1017 /*****************************************************************************/
1018 
1019 ABTU_ret_err static int print_all_thread_stacks(ABTI_global *p_global,
1020  FILE *fp);
1021 
1022 #define PRINT_STACK_FLAG_UNSET 0
1023 #define PRINT_STACK_FLAG_INITIALIZE 1
1024 #define PRINT_STACK_FLAG_WAIT 2
1025 #define PRINT_STACK_FLAG_FINALIZE 3
1027 static ABTD_atomic_int print_stack_flag =
1028  ABTD_ATOMIC_INT_STATIC_INITIALIZER(PRINT_STACK_FLAG_UNSET);
1029 static FILE *print_stack_fp = NULL;
1030 static double print_stack_timeout = 0.0;
1031 static void (*print_cb_func)(ABT_bool, void *) = NULL;
1032 static void *print_arg = NULL;
1033 static ABTD_atomic_int print_stack_barrier =
1034  ABTD_ATOMIC_INT_STATIC_INITIALIZER(0);
1036 void ABTI_info_check_print_all_thread_stacks(void)
1037 {
1038  if (ABTD_atomic_acquire_load_int(&print_stack_flag) !=
1040  return;
1041 
1042  /* Wait for the other execution streams using a barrier mechanism. */
1043  int self_value = ABTD_atomic_fetch_add_int(&print_stack_barrier, 1);
1044  if (self_value == 0) {
1045  ABTI_global *p_global = ABTI_global_get_global();
1046  /* This ES becomes the main ES. */
1047  double start_time = ABTI_get_wtime();
1048  ABT_bool force_print = ABT_FALSE;
1049 
1050  /* xstreams_lock is acquired to avoid dynamic ES creation while
1051  * printing data. */
1052  ABTD_spinlock_acquire(&p_global->xstream_list_lock);
1053  while (1) {
1054  if (ABTD_atomic_acquire_load_int(&print_stack_barrier) >=
1055  p_global->num_xstreams) {
1056  break;
1057  }
1058  if (print_stack_timeout >= 0.0 &&
1059  (ABTI_get_wtime() - start_time) >= print_stack_timeout) {
1060  force_print = ABT_TRUE;
1061  break;
1062  }
1063  ABTD_spinlock_release(&p_global->xstream_list_lock);
1064  ABTD_atomic_pause();
1065  ABTD_spinlock_acquire(&p_global->xstream_list_lock);
1066  }
1067  /* All the available ESs are (supposed to be) stopped. We *assume* that
1068  * no ES is calling and will call Argobots functions except this
1069  * function while printing stack information. */
1070  if (force_print) {
1071  fprintf(print_stack_fp,
1072  "ABT_info_trigger_print_all_thread_stacks: "
1073  "timeout (only %d ESs stop)\n",
1074  ABTD_atomic_acquire_load_int(&print_stack_barrier));
1075  }
1076  int abt_errno = print_all_thread_stacks(p_global, print_stack_fp);
1077  if (ABTI_IS_ERROR_CHECK_ENABLED && abt_errno != ABT_SUCCESS) {
1078  fprintf(print_stack_fp, "ABT_info_trigger_print_all_thread_stacks: "
1079  "failed because of an internal error.\n");
1080  }
1081  fflush(print_stack_fp);
1082  /* Release the lock that protects ES data. */
1083  ABTD_spinlock_release(&p_global->xstream_list_lock);
1084  if (print_cb_func)
1085  print_cb_func(force_print, print_arg);
1086  /* Update print_stack_flag to 3. */
1087  ABTD_atomic_release_store_int(&print_stack_flag,
1089  } else {
1090  /* Wait for the main ES's work. */
1091  while (ABTD_atomic_acquire_load_int(&print_stack_flag) !=
1093  ABTD_atomic_pause();
1094  }
1095  ABTI_ASSERT(ABTD_atomic_acquire_load_int(&print_stack_flag) ==
1097 
1098  /* Decrement the barrier value. */
1099  int dec_value = ABTD_atomic_fetch_sub_int(&print_stack_barrier, 1);
1100  if (dec_value == 0) {
1101  /* The last execution stream resets the flag. */
1102  ABTD_atomic_release_store_int(&print_stack_flag,
1104  }
1105 }
1106 
1107 void ABTI_info_print_config(ABTI_global *p_global, FILE *fp)
1108 {
1109  fprintf(fp, "Argobots Configuration:\n");
1110  fprintf(fp, " - version: " ABT_VERSION "\n");
1111  fprintf(fp, " - # of cores: %d\n", p_global->num_cores);
1112  fprintf(fp, " - cache line size: %u B\n", ABT_CONFIG_STATIC_CACHELINE_SIZE);
1113  fprintf(fp, " - huge page size: %zu B\n", p_global->huge_page_size);
1114  fprintf(fp, " - max. # of ESs: %d\n", p_global->max_xstreams);
1115  fprintf(fp, " - cur. # of ESs: %d\n", p_global->num_xstreams);
1116  fprintf(fp, " - ES affinity: %s\n",
1117  (p_global->set_affinity == ABT_TRUE) ? "on" : "off");
1118  fprintf(fp, " - logging: %s\n",
1119  (p_global->use_logging == ABT_TRUE) ? "on" : "off");
1120  fprintf(fp, " - debug output: %s\n",
1121  (p_global->use_debug == ABT_TRUE) ? "on" : "off");
1122  fprintf(fp, " - print errno: "
1123 #ifdef ABT_CONFIG_PRINT_ABT_ERRNO
1124  "on"
1125 #else
1126  "off"
1127 #endif
1128  "\n");
1129  fprintf(fp, " - valgrind support: "
1130 #ifdef HAVE_VALGRIND_SUPPORT
1131  "yes"
1132 #else
1133  "no"
1134 #endif
1135  "\n");
1136  fprintf(fp, " - thread cancellation: "
1137 #ifndef ABT_CONFIG_DISABLE_CANCELLATION
1138  "enabled"
1139 #else
1140  "disabled"
1141 #endif
1142  "\n");
1143  fprintf(fp, " - thread migration: "
1144 #ifndef ABT_CONFIG_DISABLE_MIGRATION
1145  "enabled"
1146 #else
1147  "disabled"
1148 #endif
1149  "\n");
1150  fprintf(fp, " - external thread: "
1151 #ifndef ABT_CONFIG_DISABLE_EXT_THREAD
1152  "enabled"
1153 #else
1154  "disabled"
1155 #endif
1156  "\n");
1157  fprintf(fp, " - error check: "
1158 #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK
1159  "enabled"
1160 #else
1161  "disable"
1162 #endif
1163  "\n");
1164  fprintf(fp, " - tool interface: "
1166  "yes"
1167 #else
1168  "no"
1169 #endif
1170  "\n");
1171  fprintf(fp, " - wait policy: "
1172 #ifdef ABT_CONFIG_ACTIVE_WAIT_POLICY
1173  "active"
1174 #else
1175  "passive"
1176 #endif
1177  "\n");
1178  fprintf(fp, " - context-switch: "
1180  "fcontext"
1181 #ifndef ABTD_FCONTEXT_PRESERVE_FPU
1182  " (no FPU save)"
1183 #endif
1184 #else /* ABT_CONFIG_USE_FCONTEXT */
1185  "ucontext"
1186 #endif /* !ABT_CONFIG_USE_FCONTEXT */
1187  "\n");
1188 
1189  fprintf(fp, " - key table entries: %" PRIu32 "\n",
1190  p_global->key_table_size);
1191  fprintf(fp, " - default ULT stack size: %zu KB\n",
1192  p_global->thread_stacksize / 1024);
1193  fprintf(fp, " - default scheduler stack size: %zu KB\n",
1194  p_global->sched_stacksize / 1024);
1195  fprintf(fp, " - default scheduler event check frequency: %u\n",
1196  p_global->sched_event_freq);
1197  fprintf(fp, " - default scheduler sleep: "
1198 #ifdef ABT_CONFIG_USE_SCHED_SLEEP
1199  "on"
1200 #else
1201  "off"
1202 #endif
1203  "\n");
1204  fprintf(fp, " - default scheduler sleep duration : %" PRIu64 " [ns]\n",
1205  p_global->sched_sleep_nsec);
1206 
1207  fprintf(fp, " - timer function: "
1208 #if defined(ABT_CONFIG_USE_CLOCK_GETTIME)
1209  "clock_gettime"
1210 #elif defined(ABT_CONFIG_USE_MACH_ABSOLUTE_TIME)
1211  "mach_absolute_time"
1212 #elif defined(ABT_CONFIG_USE_GETTIMEOFDAY)
1213  "gettimeofday"
1214 #endif
1215  "\n");
1216 
1217 #ifdef ABT_CONFIG_USE_MEM_POOL
1218  fprintf(fp, "Memory Pool:\n");
1219  fprintf(fp, " - page size for allocation: %zu KB\n",
1220  p_global->mem_page_size / 1024);
1221  fprintf(fp, " - stack page size: %zu KB\n", p_global->mem_sp_size / 1024);
1222  fprintf(fp, " - max. # of stacks per ES: %u\n", p_global->mem_max_stacks);
1223  fprintf(fp, " - max. # of descs per ES: %u\n", p_global->mem_max_descs);
1224  switch (p_global->mem_lp_alloc) {
1225  case ABTI_MEM_LP_MALLOC:
1226  fprintf(fp, " - large page allocation: malloc\n");
1227  break;
1228  case ABTI_MEM_LP_MMAP_RP:
1229  fprintf(fp, " - large page allocation: mmap regular pages\n");
1230  break;
1231  case ABTI_MEM_LP_MMAP_HP_RP:
1232  fprintf(fp, " - large page allocation: mmap huge pages + "
1233  "regular pages\n");
1234  break;
1235  case ABTI_MEM_LP_MMAP_HP_THP:
1236  fprintf(fp, " - large page allocation: mmap huge pages + THPs\n");
1237  break;
1238  case ABTI_MEM_LP_THP:
1239  fprintf(fp, " - large page allocation: THPs\n");
1240  break;
1241  }
1242 #endif /* ABT_CONFIG_USE_MEM_POOL */
1243 
1244  fflush(fp);
1245 }
1246 
1247 /*****************************************************************************/
1248 /* Internal static functions */
1249 /*****************************************************************************/
1250 
1251 struct info_print_unit_arg_t {
1252  ABTI_global *p_global;
1253  FILE *fp;
1254 };
1257  ABT_pool *pools;
1258  size_t num;
1259  size_t len;
1260 };
1262 static void info_print_unit(void *arg, ABT_thread thread)
1263 {
1264  /* This function may not have any side effect on unit because it is passed
1265  * to p_print_all. */
1266  struct info_print_unit_arg_t *p_arg;
1267  p_arg = (struct info_print_unit_arg_t *)arg;
1268  FILE *fp = p_arg->fp;
1269  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
1270 
1271  if (!p_thread) {
1272  fprintf(fp, "=== unknown (%p) ===\n", (void *)thread);
1273  } else if (p_thread->type & ABTI_THREAD_TYPE_YIELDABLE) {
1274  fprintf(fp, "=== ULT (%p) ===\n", (void *)thread);
1275  ABTI_ythread *p_ythread = ABTI_thread_get_ythread(p_thread);
1276  ABT_unit_id thread_id = ABTI_thread_get_id(&p_ythread->thread);
1277  fprintf(fp,
1278  "id : %" PRIu64 "\n"
1279  "ctx : %p\n",
1280  (uint64_t)thread_id, (void *)&p_ythread->ctx);
1281  ABTI_ythread_print_stack(p_arg->p_global, p_ythread, fp);
1282  } else {
1283  fprintf(fp, "=== tasklet (%p) ===\n", (void *)thread);
1284  }
1285 }
1286 
1288  FILE *fp,
1289  ABTI_pool *p_pool)
1291  if (p_pool == NULL) {
1292  fprintf(fp, "== NULL pool ==\n");
1293  fflush(fp);
1294  return ABT_SUCCESS;
1295  }
1296  ABTI_CHECK_TRUE(p_pool->optional_def.p_print_all, ABT_ERR_POOL);
1297 
1298  ABT_pool pool = ABTI_pool_get_handle(p_pool);
1299 
1300  fprintf(fp, "== pool (%p) ==\n", (void *)p_pool);
1301  struct info_print_unit_arg_t arg;
1302  arg.p_global = p_global;
1303  arg.fp = fp;
1304  p_pool->optional_def.p_print_all(pool, &arg, info_print_unit);
1305  fflush(fp);
1306  return ABT_SUCCESS;
1307 }
1308 
1309 ABTU_ret_err static inline int
1311 {
1312  size_t default_len = 16;
1313  int abt_errno =
1314  ABTU_malloc(sizeof(ABT_pool) * default_len, (void **)&p_set->pools);
1315  ABTI_CHECK_ERROR(abt_errno);
1316  p_set->num = 0;
1317  p_set->len = default_len;
1318  return ABT_SUCCESS;
1319 }
1320 
1321 static inline void info_finalize_pool_set(struct info_pool_set_t *p_set)
1322 {
1323  ABTU_free(p_set->pools);
1325 
1326 ABTU_ret_err static inline int info_add_pool_set(ABT_pool pool,
1327  struct info_pool_set_t *p_set)
1328 {
1329  size_t i;
1330  for (i = 0; i < p_set->num; i++) {
1331  if (p_set->pools[i] == pool)
1332  return ABT_SUCCESS;
1333  }
1334  /* Add pool to p_set. */
1335  if (p_set->num == p_set->len) {
1336  size_t new_len = p_set->len * 2;
1337  int abt_errno =
1338  ABTU_realloc(sizeof(ABT_pool) * p_set->len,
1339  sizeof(ABT_pool) * new_len, (void **)&p_set->pools);
1340  ABTI_CHECK_ERROR(abt_errno);
1341  p_set->len = new_len;
1342  }
1343  p_set->pools[p_set->num++] = pool;
1344  return ABT_SUCCESS;
1345 }
1346 
1348  FILE *fp, double timeout, void (*cb_func)(ABT_bool, void *), void *arg)
1349 {
1350  /* This function is signal-safe, so it may not call other functions unless
1351  * you really know what the called functions do. */
1352  if (ABTD_atomic_acquire_load_int(&print_stack_flag) ==
1354  if (ABTD_atomic_bool_cas_strong_int(&print_stack_flag,
1357  /* Save fp and timeout. */
1358  print_stack_fp = fp;
1359  print_stack_timeout = timeout;
1360  print_cb_func = cb_func;
1361  print_arg = arg;
1362  /* Here print_stack_barrier must be 0. */
1363  ABTI_ASSERT(ABTD_atomic_acquire_load_int(&print_stack_barrier) ==
1364  0);
1365  ABTD_atomic_release_store_int(&print_stack_flag,
1367  }
1368  }
1369 }
1370 
1371 ABTU_ret_err static int print_all_thread_stacks(ABTI_global *p_global, FILE *fp)
1372 {
1373  size_t i;
1374  int abt_errno;
1375  struct info_pool_set_t pool_set;
1376  struct tm *tm = NULL;
1377  time_t seconds;
1378 
1379  abt_errno = info_initialize_pool_set(&pool_set);
1380  ABTI_CHECK_ERROR(abt_errno);
1381  ABTI_xstream *p_xstream = p_global->p_xstream_head;
1382 
1383  seconds = (time_t)ABT_get_wtime();
1384  tm = localtime(&seconds);
1385  ABTI_ASSERT(tm != NULL);
1386  fprintf(fp, "Start of ULT stacks dump %04d/%02d/%02d-%02d:%02d:%02d\n",
1387  tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour,
1388  tm->tm_min, tm->tm_sec);
1389 
1390  while (p_xstream) {
1391  ABTI_sched *p_main_sched = p_xstream->p_main_sched;
1392  fprintf(fp, "= xstream[%d] (%p) =\n", p_xstream->rank,
1393  (void *)p_xstream);
1394  fprintf(fp, "main_sched : %p\n", (void *)p_main_sched);
1395  if (!p_main_sched)
1396  continue;
1397  for (i = 0; i < p_main_sched->num_pools; i++) {
1398  ABT_pool pool = p_main_sched->pools[i];
1399  ABTI_ASSERT(pool != ABT_POOL_NULL);
1400  fprintf(fp, " pools[%zu] : %p\n", i,
1401  (void *)ABTI_pool_get_ptr(pool));
1402  abt_errno = info_add_pool_set(pool, &pool_set);
1403  if (ABTI_IS_ERROR_CHECK_ENABLED && abt_errno != ABT_SUCCESS) {
1404  info_finalize_pool_set(&pool_set);
1405  ABTI_HANDLE_ERROR(abt_errno);
1406  }
1407  }
1408  p_xstream = p_xstream->p_next;
1409  }
1410  for (i = 0; i < pool_set.num; i++) {
1411  ABT_pool pool = pool_set.pools[i];
1412  ABTI_pool *p_pool = ABTI_pool_get_ptr(pool);
1413  abt_errno = info_print_thread_stacks_in_pool(p_global, fp, p_pool);
1414  if (abt_errno != ABT_SUCCESS)
1415  fprintf(fp, " Failed to print (errno = %d).\n", abt_errno);
1416  }
1417 
1418  seconds = (time_t)ABT_get_wtime();
1419  tm = localtime(&seconds);
1420  ABTI_ASSERT(tm != NULL);
1421  fprintf(fp, "End of ULT stacks dump %04d/%02d/%02d-%02d:%02d:%02d\n",
1422  tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour,
1423  tm->tm_min, tm->tm_sec);
1424 
1425  info_finalize_pool_set(&pool_set);
1426  return ABT_SUCCESS;
1427 }
ABT_INFO_QUERY_KIND_ENABLED_STACK_OVERFLOW_CHECK
@ ABT_INFO_QUERY_KIND_ENABLED_STACK_OVERFLOW_CHECK
Definition: abt.h:655
ABT_info_print_xstream
int ABT_info_print_xstream(FILE *fp, ABT_xstream xstream)
Print the information of an execution stream.
Definition: info.c:585
ABT_get_wtime
double ABT_get_wtime(void) ABT_API_PUBLIC
Get elapsed wall clock time.
Definition: timer.c:28
info_print_unit_arg_t::fp
FILE * fp
Definition: info.c:1256
ABT_bool
int ABT_bool
Boolean type.
Definition: abt.h:1043
info_trigger_print_all_thread_stacks
static void info_trigger_print_all_thread_stacks(FILE *fp, double timeout, void(*cb_func)(ABT_bool, void *), void *arg)
Definition: info.c:1350
ABTU_realloc
static ABTU_ret_err int ABTU_realloc(size_t old_size, size_t new_size, void **p_ptr)
Definition: abtu.h:257
ABT_info_print_thread_attr
int ABT_info_print_thread_attr(FILE *fp, ABT_thread_attr attr)
Print the information of a ULT attribute.
Definition: info.c:762
ABT_thread_attr
struct ABT_thread_attr_opaque * ABT_thread_attr
ULT attribute handle type.
Definition: abt.h:939
ABT_task
struct ABT_thread_opaque * ABT_task
Work unit handle type.
Definition: abt.h:973
ABT_thread
struct ABT_thread_opaque * ABT_thread
Work unit handle type.
Definition: abt.h:932
ABT_INFO_QUERY_KIND_ENABLED_LAZY_STACK_ALLOC
@ ABT_INFO_QUERY_KIND_ENABLED_LAZY_STACK_ALLOC
Definition: abt.h:659
ABT_info_print_all_xstreams
int ABT_info_print_all_xstreams(FILE *fp)
Print the information of all execution streams.
Definition: info.c:522
ABT_INFO_QUERY_KIND_DEFAULT_SCHED_STACKSIZE
@ ABT_INFO_QUERY_KIND_DEFAULT_SCHED_STACKSIZE
Definition: abt.h:641
ABT_INFO_QUERY_KIND_ENABLED_STACK_UNWIND
@ ABT_INFO_QUERY_KIND_ENABLED_STACK_UNWIND
Definition: abt.h:653
info_print_unit_arg_t
Definition: info.c:1254
ABT_ERR_POOL
#define ABT_ERR_POOL
Error code: error related to a pool.
Definition: abt.h:292
info_finalize_pool_set
static void info_finalize_pool_set(struct info_pool_set_t *p_set)
Definition: info.c:1324
print_stack_flag
static ABTD_atomic_int print_stack_flag
Definition: info.c:1030
ABT_CONFIG_USE_FCONTEXT
#define ABT_CONFIG_USE_FCONTEXT
Definition: abt_config.h:102
print_stack_fp
static FILE * print_stack_fp
Definition: info.c:1032
ABT_info_trigger_print_all_thread_stacks
int ABT_info_trigger_print_all_thread_stacks(FILE *fp, double timeout, void(*cb_func)(ABT_bool, void *), void *arg)
Print stacks of work units in pools associated with all the main schedulers.
Definition: info.c:1009
ABT_INFO_QUERY_KIND_ENABLED_MIGRATION
@ ABT_INFO_QUERY_KIND_ENABLED_MIGRATION
Definition: abt.h:624
info_print_unit
static void info_print_unit(void *arg, ABT_thread thread)
Definition: info.c:1265
ABT_info_print_thread_stacks_in_pool
int ABT_info_print_thread_stacks_in_pool(FILE *fp, ABT_pool pool)
Print stacks of all work units in a pool.
Definition: info.c:925
print_cb_func
static void(* print_cb_func)(ABT_bool, void *)
Definition: info.c:1034
ABT_CONFIG_DISABLE_TOOL_INTERFACE
#define ABT_CONFIG_DISABLE_TOOL_INTERFACE
Definition: abt_config.h:48
info_pool_set_t
Definition: info.c:1259
ABT_pool
struct ABT_pool_opaque * ABT_pool
Pool handle type.
Definition: abt.h:878
ABT_sched
struct ABT_sched_opaque * ABT_sched
Scheduler handle type.
Definition: abt.h:845
ABT_INFO_QUERY_KIND_FCONTEXT
@ ABT_INFO_QUERY_KIND_FCONTEXT
Definition: abt.h:649
ABT_ERR_INV_QUERY_KIND
#define ABT_ERR_INV_QUERY_KIND
Error code: invalid query kind.
Definition: abt.h:250
print_stack_timeout
static double print_stack_timeout
Definition: info.c:1033
ABT_POOL_NULL
#define ABT_POOL_NULL
Definition: abt.h:1102
ABT_INFO_QUERY_KIND_ENABLED_EXTERNAL_THREAD
@ ABT_INFO_QUERY_KIND_ENABLED_EXTERNAL_THREAD
Definition: abt.h:628
abti.h
ABT_INFO_QUERY_KIND_ENABLED_AFFINITY
@ ABT_INFO_QUERY_KIND_ENABLED_AFFINITY
Definition: abt.h:635
ABT_info_query_config
int ABT_info_query_config(ABT_info_query_kind query_kind, void *val)
Retrieve the configuration information.
Definition: info.c:216
info_pool_set_t::num
size_t num
Definition: info.c:1261
ABT_INFO_QUERY_KIND_ENABLED_CHECK_POOL_PRODUCER
@ ABT_INFO_QUERY_KIND_ENABLED_CHECK_POOL_PRODUCER
Definition: abt.h:613
ABT_unit_id
uint64_t ABT_unit_id
Work unit ID type.
Definition: abt.h:921
ABT_xstream
struct ABT_xstream_opaque * ABT_xstream
Execution stream handle type.
Definition: abt.h:826
ABT_info_print_thread_stack
int ABT_info_print_thread_stack(FILE *fp, ABT_thread thread)
Print stack of a work unit.
Definition: info.c:860
ABT_INFO_QUERY_KIND_ENABLED_VALGRIND
@ ABT_INFO_QUERY_KIND_ENABLED_VALGRIND
Definition: abt.h:609
ABT_CONFIG_USE_CLOCK_GETTIME
#define ABT_CONFIG_USE_CLOCK_GETTIME
Definition: abt_config.h:90
ABTU_malloc
static ABTU_ret_err int ABTU_malloc(size_t size, void **p_ptr)
Definition: abtu.h:235
info_print_unit_arg_t::p_global
ABTI_global * p_global
Definition: info.c:1255
ABT_info_query_kind
ABT_info_query_kind
Query kind for ABT_info_query_config().
Definition: abt.h:601
ABT_INFO_QUERY_KIND_ENABLED_STACKABLE_SCHED
@ ABT_INFO_QUERY_KIND_ENABLED_STACKABLE_SCHED
Definition: abt.h:626
PRINT_STACK_FLAG_INITIALIZE
#define PRINT_STACK_FLAG_INITIALIZE
Definition: info.c:1026
ABT_INFO_QUERY_KIND_ENABLED_PRINT_CONFIG
@ ABT_INFO_QUERY_KIND_ENABLED_PRINT_CONFIG
Definition: abt.h:633
info_add_pool_set
static ABTU_ret_err int info_add_pool_set(ABT_pool pool, struct info_pool_set_t *p_set)
Definition: info.c:1329
info_pool_set_t::pools
ABT_pool * pools
Definition: info.c:1260
ABT_INFO_QUERY_KIND_ENABLED_DEBUG
@ ABT_INFO_QUERY_KIND_ENABLED_DEBUG
Definition: abt.h:603
ABT_CONFIG_STATIC_CACHELINE_SIZE
#define ABT_CONFIG_STATIC_CACHELINE_SIZE
Definition: abt_config.h:81
ABT_INFO_QUERY_KIND_ENABLED_TOOL
@ ABT_INFO_QUERY_KIND_ENABLED_TOOL
Definition: abt.h:647
ABT_SUCCESS
#define ABT_SUCCESS
Error code: the routine returns successfully.
Definition: abt.h:92
PRINT_STACK_FLAG_UNSET
#define PRINT_STACK_FLAG_UNSET
Definition: info.c:1025
ABTU_ret_err
#define ABTU_ret_err
Definition: abtu.h:155
ABT_INFO_QUERY_KIND_DYNAMIC_PROMOTION
@ ABT_INFO_QUERY_KIND_DYNAMIC_PROMOTION
Definition: abt.h:651
print_stack_barrier
static ABTD_atomic_int print_stack_barrier
Definition: info.c:1036
ABT_info_print_pool
int ABT_info_print_pool(FILE *fp, ABT_pool pool)
Print the information of a pool.
Definition: info.c:671
ABT_INFO_QUERY_KIND_DEFAULT_THREAD_STACKSIZE
@ ABT_INFO_QUERY_KIND_DEFAULT_THREAD_STACKSIZE
Definition: abt.h:639
ABT_TRUE
#define ABT_TRUE
True constant for ABT_bool.
Definition: abt.h:784
ABT_INFO_QUERY_KIND_ENABLED_CHECK_POOL_CONSUMER
@ ABT_INFO_QUERY_KIND_ENABLED_CHECK_POOL_CONSUMER
Definition: abt.h:615
PRINT_STACK_FLAG_WAIT
#define PRINT_STACK_FLAG_WAIT
Definition: info.c:1027
ABT_INFO_QUERY_KIND_ENABLED_CHECK_ERROR
@ ABT_INFO_QUERY_KIND_ENABLED_CHECK_ERROR
Definition: abt.h:611
ABT_FALSE
#define ABT_FALSE
False constant for ABT_bool.
Definition: abt.h:786
ABT_info_print_thread
int ABT_info_print_thread(FILE *fp, ABT_thread thread)
Print the information of a work unit.
Definition: info.c:719
print_arg
static void * print_arg
Definition: info.c:1035
ABTU_free
static void ABTU_free(void *ptr)
Definition: abtu.h:228
print_all_thread_stacks
static ABTU_ret_err int print_all_thread_stacks(ABTI_global *p_global, FILE *fp)
Definition: info.c:1374
ABT_INFO_QUERY_KIND_ENABLED_PRESERVE_FPU
@ ABT_INFO_QUERY_KIND_ENABLED_PRESERVE_FPU
Definition: abt.h:618
ABT_INFO_QUERY_KIND_ENABLED_PRINT_ERRNO
@ ABT_INFO_QUERY_KIND_ENABLED_PRINT_ERRNO
Definition: abt.h:605
info_print_thread_stacks_in_pool
static ABTU_ret_err int info_print_thread_stacks_in_pool(ABTI_global *p_global, FILE *fp, ABTI_pool *p_pool)
Definition: info.c:1290
ABT_info_print_task
int ABT_info_print_task(FILE *fp, ABT_task task)
Print the information of a work unit.
Definition: info.c:811
ABT_info_print_config
int ABT_info_print_config(FILE *fp)
Print the runtime information of Argobots.
Definition: info.c:473
ABT_INFO_QUERY_KIND_ENABLED_TASK_CANCEL
@ ABT_INFO_QUERY_KIND_ENABLED_TASK_CANCEL
Definition: abt.h:622
ABT_INFO_QUERY_KIND_DEFAULT_SCHED_EVENT_FREQ
@ ABT_INFO_QUERY_KIND_DEFAULT_SCHED_EVENT_FREQ
Definition: abt.h:643
ABT_INFO_QUERY_KIND_WAIT_POLICY
@ ABT_INFO_QUERY_KIND_WAIT_POLICY
Definition: abt.h:657
info_pool_set_t::len
size_t len
Definition: info.c:1262
ABT_info_print_sched
int ABT_info_print_sched(FILE *fp, ABT_sched sched)
Print the information of a scheduler.
Definition: info.c:628
info_initialize_pool_set
static ABTU_ret_err int info_initialize_pool_set(struct info_pool_set_t *p_set)
Definition: info.c:1313
ABT_INFO_QUERY_KIND_MAX_NUM_XSTREAMS
@ ABT_INFO_QUERY_KIND_MAX_NUM_XSTREAMS
Definition: abt.h:637
ABT_INFO_QUERY_KIND_DEFAULT_SCHED_SLEEP_NSEC
@ ABT_INFO_QUERY_KIND_DEFAULT_SCHED_SLEEP_NSEC
Definition: abt.h:645
ABT_INFO_QUERY_KIND_ENABLED_LOG
@ ABT_INFO_QUERY_KIND_ENABLED_LOG
Definition: abt.h:607
PRINT_STACK_FLAG_FINALIZE
#define PRINT_STACK_FLAG_FINALIZE
Definition: info.c:1028
ABT_VERSION
#define ABT_VERSION
Version string of Argobots.
Definition: abt.h:46
ABT_INFO_QUERY_KIND_ENABLED_THREAD_CANCEL
@ ABT_INFO_QUERY_KIND_ENABLED_THREAD_CANCEL
Definition: abt.h:620
ABT_INFO_QUERY_KIND_ENABLED_SCHED_SLEEP
@ ABT_INFO_QUERY_KIND_ENABLED_SCHED_SLEEP
Definition: abt.h:630