ARGOBOTS  140a356fc09a44696eb3487150e459266f9b5405
thread.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 inline int
9 ythread_create(ABTI_local *p_local, ABTI_pool *p_pool,
10  void (*thread_func)(void *), void *arg, ABTI_thread_attr *p_attr,
11  ABTI_thread_type thread_type, ABTI_sched *p_sched,
12  ABT_bool push_pool, ABTI_ythread **pp_newthread);
13 static inline void thread_join(ABTI_local **pp_local, ABTI_thread *p_thread);
14 static inline void thread_free(ABTI_local *p_local, ABTI_thread *p_thread,
15  ABT_bool free_unit);
16 static void thread_root_func(void *arg);
17 static void thread_main_sched_func(void *arg);
18 #ifndef ABT_CONFIG_DISABLE_MIGRATION
20  ABTI_thread *p_thread,
21  ABTI_pool *p_pool);
22 #endif
23 static inline ABT_unit_id thread_get_new_id(void);
24 
25 static void thread_key_destructor_stackable_sched(void *p_value);
29 static void thread_key_destructor_migration(void *p_value);
33 
85 int ABT_thread_create(ABT_pool pool, void (*thread_func)(void *), void *arg,
86  ABT_thread_attr attr, ABT_thread *newthread)
87 {
88 #ifndef ABT_CONFIG_ENABLE_VER_20_API
89  /* Argobots 1.x sets newthread to NULL on error. */
90  if (newthread)
91  *newthread = ABT_THREAD_NULL;
92 #endif
93  ABTI_local *p_local = ABTI_local_get_local();
94  ABTI_ythread *p_newthread;
95 
96  ABTI_pool *p_pool = ABTI_pool_get_ptr(pool);
98 
99  ABTI_thread_type unit_type =
100  (newthread != NULL)
103  int abt_errno = ythread_create(p_local, p_pool, thread_func, arg,
104  ABTI_thread_attr_get_ptr(attr), unit_type,
105  NULL, ABT_TRUE, &p_newthread);
106  ABTI_CHECK_ERROR(abt_errno);
107 
108  /* Return value */
109  if (newthread)
110  *newthread = ABTI_ythread_get_handle(p_newthread);
111  return ABT_SUCCESS;
112 }
113 
163  void (*thread_func)(void *), void *arg,
164  ABT_thread_attr attr, ABT_thread *newthread)
165 {
166 #ifndef ABT_CONFIG_ENABLE_VER_20_API
167  /* Argobots 1.x sets newthread to NULL on error. */
168  if (newthread)
169  *newthread = ABT_THREAD_NULL;
170 #endif
171  ABTI_local *p_local = ABTI_local_get_local();
172  ABTI_ythread *p_newthread;
173 
174  ABTI_xstream *p_xstream = ABTI_xstream_get_ptr(xstream);
175  ABTI_CHECK_NULL_XSTREAM_PTR(p_xstream);
176 
177  /* TODO: need to consider the access type of target pool */
178  ABTI_pool *p_pool = ABTI_xstream_get_main_pool(p_xstream);
179  ABTI_thread_type unit_type =
180  (newthread != NULL)
183  int abt_errno = ythread_create(p_local, p_pool, thread_func, arg,
184  ABTI_thread_attr_get_ptr(attr), unit_type,
185  NULL, ABT_TRUE, &p_newthread);
186  ABTI_CHECK_ERROR(abt_errno);
187 
188  /* Return value */
189  if (newthread)
190  *newthread = ABTI_ythread_get_handle(p_newthread);
191 
192  return ABT_SUCCESS;
193 }
194 
243 int ABT_thread_create_many(int num_threads, ABT_pool *pool_list,
244  void (**thread_func_list)(void *), void **arg_list,
245  ABT_thread_attr attr, ABT_thread *newthread_list)
246 {
247  ABTI_local *p_local = ABTI_local_get_local();
248  int i;
249 
250  if (attr != ABT_THREAD_ATTR_NULL) {
251  /* This implies that the stack is given by a user. Since threads
252  * cannot use the same stack region, this is illegal. */
253  ABTI_CHECK_TRUE(!(ABTI_thread_attr_get_ptr(attr)->thread_type &
257  }
258 
259  if (newthread_list == NULL) {
260  for (i = 0; i < num_threads; i++) {
261  ABTI_ythread *p_newthread;
262  ABT_pool pool = pool_list[i];
263  ABTI_pool *p_pool = ABTI_pool_get_ptr(pool);
264  ABTI_CHECK_NULL_POOL_PTR(p_pool);
265 
266  void (*thread_f)(void *) = thread_func_list[i];
267  void *arg = arg_list ? arg_list[i] : NULL;
268  int abt_errno = ythread_create(p_local, p_pool, thread_f, arg,
271  ABT_TRUE, &p_newthread);
272  ABTI_CHECK_ERROR(abt_errno);
273  }
274  } else {
275  for (i = 0; i < num_threads; i++) {
276  ABTI_ythread *p_newthread;
277  ABT_pool pool = pool_list[i];
278  ABTI_pool *p_pool = ABTI_pool_get_ptr(pool);
279  ABTI_CHECK_NULL_POOL_PTR(p_pool);
280 
281  void (*thread_f)(void *) = thread_func_list[i];
282  void *arg = arg_list ? arg_list[i] : NULL;
283  int abt_errno = ythread_create(p_local, p_pool, thread_f, arg,
287  NULL, ABT_TRUE, &p_newthread);
288  newthread_list[i] = ABTI_ythread_get_handle(p_newthread);
289  /* TODO: Release threads that have been already created. */
290  ABTI_CHECK_ERROR(abt_errno);
291  }
292  }
293 
294  return ABT_SUCCESS;
295 }
296 
343 int ABT_thread_revive(ABT_pool pool, void (*thread_func)(void *), void *arg,
344  ABT_thread *thread)
345 {
346  ABTI_local *p_local = ABTI_local_get_local();
347 
348  ABTI_thread *p_thread = ABTI_thread_get_ptr(*thread);
349  ABTI_CHECK_NULL_THREAD_PTR(p_thread);
350 
354 
355  ABTI_pool *p_pool = ABTI_pool_get_ptr(pool);
356  ABTI_CHECK_NULL_POOL_PTR(p_pool);
357 
358  ABTI_thread_revive(p_local, p_pool, thread_func, arg, p_thread);
359 
360  return ABT_SUCCESS;
361 }
362 
404 int ABT_thread_free(ABT_thread *thread)
405 {
407  ABT_thread h_thread = *thread;
408 
409  ABTI_thread *p_thread = ABTI_thread_get_ptr(h_thread);
410  ABTI_CHECK_NULL_THREAD_PTR(p_thread);
412  p_thread != ABTI_local_get_xstream(p_local)->p_thread,
414  ABTI_CHECK_TRUE(!(p_thread->type &
417 
418  /* Wait until the thread terminates */
419  thread_join(&p_local, p_thread);
420  /* Free the ABTI_thread structure */
421  ABTI_thread_free(p_local, p_thread);
422 
423  /* Return value */
424  *thread = ABT_THREAD_NULL;
425 
426  return ABT_SUCCESS;
427 }
428 
460 int ABT_thread_free_many(int num_threads, ABT_thread *thread_list)
461 {
463  int i;
464 
465  for (i = 0; i < num_threads; i++) {
466  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread_list[i]);
467  /* TODO: check input */
468  thread_join(&p_local, p_thread);
469  ABTI_thread_free(p_local, p_thread);
470  }
471  return ABT_SUCCESS;
472 }
473 
513 int ABT_thread_join(ABT_thread thread)
514 {
516  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
517  ABTI_CHECK_NULL_THREAD_PTR(p_thread);
519  p_thread != ABTI_local_get_xstream(p_local)->p_thread,
521  ABTI_CHECK_TRUE(!(p_thread->type &
524 
525  thread_join(&p_local, p_thread);
526  return ABT_SUCCESS;
527 }
528 
560 int ABT_thread_join_many(int num_threads, ABT_thread *thread_list)
561 {
563  int i;
564  for (i = 0; i < num_threads; i++) {
565  /* TODO: check input */
566  thread_join(&p_local, ABTI_thread_get_ptr(thread_list[i]));
567  }
568  return ABT_SUCCESS;
569 }
570 
596 int ABT_thread_exit(void)
597 {
598  ABTI_xstream *p_local_xstream;
599  ABTI_ythread *p_ythread;
600 #ifndef ABT_CONFIG_ENABLE_VER_20_API
601  ABTI_SETUP_LOCAL_YTHREAD_WITH_INIT_CHECK(&p_local_xstream, &p_ythread);
602 #else
603  ABTI_SETUP_LOCAL_YTHREAD(&p_local_xstream, &p_ythread);
604 #endif
607 
608  ABTI_ythread_exit(p_local_xstream, p_ythread);
609  return ABT_SUCCESS;
610 }
611 
644 int ABT_thread_cancel(ABT_thread thread)
645 {
646 #ifdef ABT_CONFIG_DISABLE_THREAD_CANCEL
648 #else
649  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
650  ABTI_CHECK_NULL_THREAD_PTR(p_thread);
653 
654  /* Set the cancel request */
656  return ABT_SUCCESS;
657 #endif
658 }
659 
692 int ABT_thread_self(ABT_thread *thread)
693 {
694 #ifndef ABT_CONFIG_ENABLE_VER_20_API
695  *thread = ABT_THREAD_NULL;
696  ABTI_ythread *p_self;
698  *thread = ABTI_thread_get_handle(&p_self->thread);
699 #else
700  ABTI_xstream *p_local_xstream;
701  ABTI_SETUP_LOCAL_XSTREAM(&p_local_xstream);
702  *thread = ABTI_thread_get_handle(p_local_xstream->p_thread);
703 #endif
704  return ABT_SUCCESS;
705 }
706 
738 {
739 #ifndef ABT_CONFIG_ENABLE_VER_20_API
740  ABTI_ythread *p_self;
742  *id = ABTI_thread_get_id(&p_self->thread);
743 #else
744  ABTI_xstream *p_local_xstream;
745  ABTI_SETUP_LOCAL_XSTREAM(&p_local_xstream);
746  *id = ABTI_thread_get_id(p_local_xstream->p_thread);
747 #endif
748  return ABT_SUCCESS;
749 }
750 
780 {
781  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
782  ABTI_CHECK_NULL_THREAD_PTR(p_thread);
783 
784  *xstream = ABTI_xstream_get_handle(p_thread->p_last_xstream);
785  return ABT_SUCCESS;
786 }
787 
821 {
822  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
823  ABTI_CHECK_NULL_THREAD_PTR(p_thread);
824 
826  return ABT_SUCCESS;
827 }
828 
861 {
862  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
863  ABTI_CHECK_NULL_THREAD_PTR(p_thread);
864 
865  *pool = ABTI_pool_get_handle(p_thread->p_pool);
866  return ABT_SUCCESS;
867 }
868 
900 int ABT_thread_get_last_pool_id(ABT_thread thread, int *id)
901 {
902  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
903  ABTI_CHECK_NULL_THREAD_PTR(p_thread);
904  *id = (int)p_thread->p_pool->id;
905  return ABT_SUCCESS;
906 }
907 
940 {
941  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
942  ABTI_CHECK_NULL_THREAD_PTR(p_thread);
943  ABTI_pool *p_pool = ABTI_pool_get_ptr(pool);
944  ABTI_CHECK_NULL_POOL_PTR(p_pool);
945 
946  p_thread->p_pool = p_pool;
947  return ABT_SUCCESS;
948 }
949 
996 {
997  ABTI_xstream *p_local_xstream;
998  ABTI_ythread *p_cur_ythread;
999 #ifndef ABT_CONFIG_ENABLE_VER_20_API
1002  p_local_xstream == NULL) {
1003  return ABT_SUCCESS;
1004  } else {
1005  p_cur_ythread =
1006  ABTI_thread_get_ythread_or_null(p_local_xstream->p_thread);
1007  if (ABTI_IS_ERROR_CHECK_ENABLED && !p_cur_ythread)
1008  return ABT_SUCCESS;
1009  }
1010 #else
1011  ABTI_SETUP_LOCAL_YTHREAD(&p_local_xstream, &p_cur_ythread);
1012 #endif
1013 
1014  ABTI_thread *p_tar_thread = ABTI_thread_get_ptr(thread);
1015  ABTI_CHECK_NULL_THREAD_PTR(p_tar_thread);
1016  ABTI_ythread *p_tar_ythread = ABTI_thread_get_ythread_or_null(p_tar_thread);
1017  ABTI_CHECK_NULL_YTHREAD_PTR(p_tar_ythread);
1018  ABTI_CHECK_TRUE(p_cur_ythread != p_tar_ythread, ABT_ERR_INV_THREAD);
1023 
1024  LOG_DEBUG("[U%" PRIu64 ":E%d] yield_to -> U%" PRIu64 "\n",
1025  ABTI_thread_get_id(&p_cur_ythread->thread),
1026  p_cur_ythread->thread.p_last_xstream->rank,
1027  ABTI_thread_get_id(&p_tar_ythread->thread));
1028 
1029  /* If the target thread is not in READY, we don't yield. Note that ULT can
1030  * be regarded as 'ready' only if its state is READY and it has been
1031  * pushed into a pool. Since we set ULT's state to READY and then push it
1032  * into a pool, we check them in the reverse order, i.e., check if the ULT
1033  * is inside a pool and the its state. */
1034  if (!(p_tar_ythread->thread.p_pool->u_is_in_pool(
1035  p_tar_ythread->thread.unit) == ABT_TRUE &&
1036  ABTD_atomic_acquire_load_int(&p_tar_ythread->thread.state) ==
1038  /* This is undefined behavior. */
1039  return ABT_SUCCESS;
1040  }
1041 
1042  /* Remove the target ULT from the pool */
1044  /* This is necessary to prevent the size of this pool from 0. */
1045  ABTI_pool_inc_num_blocked(p_tar_ythread->thread.p_pool);
1046  }
1047  int abt_errno = ABTI_pool_remove(p_tar_ythread->thread.p_pool,
1048  p_tar_ythread->thread.unit);
1050  ABTI_pool_dec_num_blocked(p_tar_ythread->thread.p_pool);
1051  ABTI_CHECK_ERROR(abt_errno);
1052  }
1053 
1054  ABTD_atomic_release_store_int(&p_cur_ythread->thread.state,
1056 
1057  /* This operation is corresponding to yield */
1058  ABTI_tool_event_ythread_yield(p_local_xstream, p_cur_ythread,
1059  p_cur_ythread->thread.p_parent,
1060  ABT_SYNC_EVENT_TYPE_USER, NULL);
1061 
1062  /* Add the current thread to the pool again. */
1063  ABTI_pool_push(p_cur_ythread->thread.p_pool, p_cur_ythread->thread.unit);
1064 
1065  /* We set the last ES */
1066  p_tar_ythread->thread.p_last_xstream = p_local_xstream;
1067 
1068  /* Switch the context */
1069  ABTD_atomic_release_store_int(&p_tar_ythread->thread.state,
1071  ABTI_ythread *p_prev =
1072  ABTI_ythread_context_switch_to_sibling(&p_local_xstream, p_cur_ythread,
1073  p_tar_ythread);
1074  ABTI_tool_event_thread_run(p_local_xstream, &p_cur_ythread->thread,
1075  &p_prev->thread, p_cur_ythread->thread.p_parent);
1076  return ABT_SUCCESS;
1077 }
1078 
1107 int ABT_thread_yield(void)
1108 {
1109  ABTI_xstream *p_local_xstream;
1110  ABTI_ythread *p_ythread;
1111 #ifndef ABT_CONFIG_ENABLE_VER_20_API
1114  ABTU_unlikely(p_local_xstream == NULL)) {
1115  return ABT_SUCCESS;
1116  } else {
1117  p_ythread = ABTI_thread_get_ythread_or_null(p_local_xstream->p_thread);
1118  if (ABTI_IS_ERROR_CHECK_ENABLED && ABTU_unlikely(!p_ythread)) {
1119  return ABT_SUCCESS;
1120  }
1121  }
1122 #else
1123  ABTI_SETUP_LOCAL_YTHREAD(&p_local_xstream, &p_ythread);
1124 #endif
1125 
1126  ABTI_ythread_yield(&p_local_xstream, p_ythread, ABT_SYNC_EVENT_TYPE_USER,
1127  NULL);
1128  return ABT_SUCCESS;
1129 }
1130 
1160 int ABT_thread_resume(ABT_thread thread)
1161 {
1163 
1164  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
1165  ABTI_CHECK_NULL_THREAD_PTR(p_thread);
1166  ABTI_ythread *p_ythread;
1167  ABTI_CHECK_YIELDABLE(p_thread, &p_ythread, ABT_ERR_INV_THREAD);
1168 
1169 #ifndef ABT_CONFIG_ENABLE_VER_20_API
1170  /* The ULT must be in BLOCKED state. */
1173  ABT_ERR_THREAD);
1174 #endif
1175 
1176  ABTI_ythread_set_ready(p_local, p_ythread);
1177  return ABT_SUCCESS;
1178 }
1179 
1232 {
1233 #ifndef ABT_CONFIG_DISABLE_MIGRATION
1234  ABTI_local *p_local = ABTI_local_get_local();
1235  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
1236  ABTI_CHECK_NULL_THREAD_PTR(p_thread);
1237  ABTI_xstream *p_xstream = ABTI_xstream_get_ptr(xstream);
1238  ABTI_CHECK_NULL_XSTREAM_PTR(p_xstream);
1243  /* Check if a thread is associated with a pool of the main scheduler. */
1244  ABTI_sched *p_sched = p_xstream->p_main_sched;
1246  size_t p;
1247  for (p = 0; p < p_sched->num_pools; p++)
1248  ABTI_CHECK_TRUE(ABTI_pool_get_ptr(p_sched->pools[p]) !=
1249  p_thread->p_pool,
1251  }
1252  /* Get the target pool. */
1253  ABTI_pool *p_pool = NULL;
1254  int abt_errno;
1255  abt_errno =
1256  ABTI_sched_get_migration_pool(p_sched, p_thread->p_pool, &p_pool);
1257  ABTI_CHECK_ERROR(abt_errno);
1258  /* Request a migration. */
1259  abt_errno = thread_migrate_to_pool(p_local, p_thread, p_pool);
1260  ABTI_CHECK_ERROR(abt_errno);
1261  return ABT_SUCCESS;
1262 #else
1264 #endif
1265 }
1266 
1315 {
1316 #ifndef ABT_CONFIG_DISABLE_MIGRATION
1317  ABTI_local *p_local = ABTI_local_get_local();
1318  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
1319  ABTI_CHECK_NULL_THREAD_PTR(p_thread);
1320  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
1321  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
1326  /* Check if a thread is associated with a pool of the main scheduler. */
1328  size_t p;
1329  for (p = 0; p < p_sched->num_pools; p++)
1330  ABTI_CHECK_TRUE(ABTI_pool_get_ptr(p_sched->pools[p]) !=
1331  p_thread->p_pool,
1333  }
1334  /* Get the target pool. */
1335  ABTI_pool *p_pool;
1336  int abt_errno;
1337  abt_errno =
1338  ABTI_sched_get_migration_pool(p_sched, p_thread->p_pool, &p_pool);
1339  ABTI_CHECK_ERROR(abt_errno);
1340  /* Request a migration. */
1341  abt_errno = thread_migrate_to_pool(p_local, p_thread, p_pool);
1342  ABTI_CHECK_ERROR(abt_errno);
1343  return ABT_SUCCESS;
1344 #else
1346 #endif
1347 }
1348 
1395 {
1396 #ifndef ABT_CONFIG_DISABLE_MIGRATION
1397  ABTI_local *p_local = ABTI_local_get_local();
1398  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
1399  ABTI_CHECK_NULL_THREAD_PTR(p_thread);
1400  ABTI_pool *p_pool = ABTI_pool_get_ptr(pool);
1401  ABTI_CHECK_NULL_POOL_PTR(p_pool);
1406  ABTI_CHECK_TRUE(p_thread->p_pool != p_pool, ABT_ERR_MIGRATION_TARGET);
1407  /* Request a migration. */
1408  int abt_errno = thread_migrate_to_pool(p_local, p_thread, p_pool);
1409  ABTI_CHECK_ERROR(abt_errno);
1410  return ABT_SUCCESS;
1411 #else
1413 #endif
1414 }
1415 
1469 int ABT_thread_migrate(ABT_thread thread)
1470 {
1471 #ifndef ABT_CONFIG_DISABLE_MIGRATION
1472  /* TODO: fix the bug(s) */
1473  ABTI_local *p_local = ABTI_local_get_local();
1474  ABTI_global *p_global = gp_ABTI_global;
1475  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
1476  ABTI_CHECK_NULL_THREAD_PTR(p_thread);
1481 
1482  /* Copy the target executions streams. */
1483  int i, num_xstreams, abt_errno;
1484  ABTI_xstream **xstreams;
1486  num_xstreams = p_global->num_xstreams;
1487  abt_errno =
1488  ABTU_malloc(sizeof(ABTI_xstream *) * num_xstreams, (void **)&xstreams);
1489  if (!(ABTI_IS_ERROR_CHECK_ENABLED && abt_errno != ABT_SUCCESS)) {
1490  ABTI_xstream *p_xstream = p_global->p_xstream_head;
1491  i = 0;
1492  while (p_xstream) {
1493  xstreams[i++] = p_xstream;
1494  p_xstream = p_xstream->p_next;
1495  }
1496  }
1498  ABTI_CHECK_ERROR(abt_errno);
1499 
1500  /* Choose the destination xstream. The user needs to maintain all the pools
1501  * and execution streams alive. */
1502  for (i = 0; i < num_xstreams; i++) {
1503  ABTI_xstream *p_xstream = xstreams[i];
1504  if (p_xstream == p_thread->p_last_xstream)
1505  continue;
1506  if (ABTD_atomic_acquire_load_int(&p_xstream->state) !=
1508  continue;
1509  /* Check if a thread is associated with a pool of the main scheduler. */
1510  ABTI_sched *p_sched = p_xstream->p_main_sched;
1511  ABT_bool is_valid = ABT_TRUE;
1512  size_t p;
1513  for (p = 0; p < p_sched->num_pools; p++) {
1514  if (ABTI_pool_get_ptr(p_sched->pools[p]) != p_thread->p_pool) {
1515  is_valid = ABT_FALSE;
1516  break;
1517  }
1518  }
1519  if (!is_valid)
1520  continue;
1521  /* Get the target pool. */
1522  ABTI_pool *p_pool = NULL;
1523  abt_errno =
1524  ABTI_sched_get_migration_pool(p_sched, p_thread->p_pool, &p_pool);
1525  if (abt_errno != ABT_SUCCESS)
1526  continue;
1527  /* Request a migration. */
1528  abt_errno = thread_migrate_to_pool(p_local, p_thread, p_pool);
1529  if (abt_errno != ABT_SUCCESS)
1530  continue;
1531  /* Succeeds. Return. */
1532  ABTU_free(xstreams);
1533  return ABT_SUCCESS;
1534  }
1535  /* All attempts failed. */
1536  ABTU_free(xstreams);
1537  return ABT_ERR_MIGRATION_NA;
1538 #else
1540 #endif
1541 }
1542 
1584  void (*cb_func)(ABT_thread thread, void *cb_arg),
1585  void *cb_arg)
1586 {
1587 #ifndef ABT_CONFIG_DISABLE_MIGRATION
1588  ABTI_local *p_local = ABTI_local_get_local();
1589  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
1590  ABTI_CHECK_NULL_THREAD_PTR(p_thread);
1591 
1592  ABTI_thread_mig_data *p_mig_data;
1593  int abt_errno = ABTI_thread_get_mig_data(p_local, p_thread, &p_mig_data);
1594  ABTI_CHECK_ERROR(abt_errno);
1595 
1596  p_mig_data->f_migration_cb = cb_func;
1597  p_mig_data->p_migration_cb_arg = cb_arg;
1598  return ABT_SUCCESS;
1599 #else
1601 #endif
1602 }
1603 
1641 int ABT_thread_set_migratable(ABT_thread thread, ABT_bool migratable)
1642 {
1643 #ifndef ABT_CONFIG_DISABLE_MIGRATION
1644  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
1645  ABTI_CHECK_NULL_THREAD_PTR(p_thread);
1646 
1647 #ifndef ABT_CONFIG_ENABLE_VER_20_API
1648  if (p_thread->type &
1650  return ABT_SUCCESS;
1651 #else
1652  ABTI_CHECK_TRUE(!(p_thread->type &
1655 #endif
1656 
1657  if (migratable) {
1658  p_thread->type |= ABTI_THREAD_TYPE_MIGRATABLE;
1659  } else {
1660  p_thread->type &= ~ABTI_THREAD_TYPE_MIGRATABLE;
1661  }
1662  return ABT_SUCCESS;
1663 #else
1665 #endif
1666 }
1667 
1698 int ABT_thread_is_migratable(ABT_thread thread, ABT_bool *is_migratable)
1699 {
1700 #ifndef ABT_CONFIG_DISABLE_MIGRATION
1701  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
1702  ABTI_CHECK_NULL_THREAD_PTR(p_thread);
1703 
1704  *is_migratable =
1706  return ABT_SUCCESS;
1707 #else
1709 #endif
1710 }
1711 
1740 int ABT_thread_is_primary(ABT_thread thread, ABT_bool *is_primary)
1741 {
1742  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
1743  ABTI_CHECK_NULL_THREAD_PTR(p_thread);
1744 
1745  *is_primary =
1746  (p_thread->type & ABTI_THREAD_TYPE_PRIMARY) ? ABT_TRUE : ABT_FALSE;
1747  return ABT_SUCCESS;
1748 }
1749 
1777 int ABT_thread_is_unnamed(ABT_thread thread, ABT_bool *is_unnamed)
1778 {
1779  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
1780  ABTI_CHECK_NULL_THREAD_PTR(p_thread);
1781 
1782  *is_unnamed =
1783  (p_thread->type & ABTI_THREAD_TYPE_NAMED) ? ABT_FALSE : ABT_TRUE;
1784  return ABT_SUCCESS;
1785 }
1786 
1824 int ABT_thread_equal(ABT_thread thread1, ABT_thread thread2, ABT_bool *result)
1825 {
1826  ABTI_thread *p_thread1 = ABTI_thread_get_ptr(thread1);
1827  ABTI_thread *p_thread2 = ABTI_thread_get_ptr(thread2);
1828  *result = (p_thread1 == p_thread2) ? ABT_TRUE : ABT_FALSE;
1829  return ABT_SUCCESS;
1830 }
1831 
1860 int ABT_thread_get_stacksize(ABT_thread thread, size_t *stacksize)
1861 {
1862  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
1863  ABTI_CHECK_NULL_THREAD_PTR(p_thread);
1864  ABTI_ythread *p_ythread = ABTI_thread_get_ythread_or_null(p_thread);
1865  if (p_ythread) {
1866  *stacksize = p_ythread->stacksize;
1867  } else {
1868  *stacksize = 0;
1869  }
1870  return ABT_SUCCESS;
1871 }
1872 
1899 int ABT_thread_get_id(ABT_thread thread, ABT_unit_id *thread_id)
1900 {
1901  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
1902  ABTI_CHECK_NULL_THREAD_PTR(p_thread);
1903 
1904  *thread_id = ABTI_thread_get_id(p_thread);
1905  return ABT_SUCCESS;
1906 }
1907 
1934 int ABT_thread_set_arg(ABT_thread thread, void *arg)
1935 {
1936  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
1937  ABTI_CHECK_NULL_THREAD_PTR(p_thread);
1938 
1939  p_thread->p_arg = arg;
1940  return ABT_SUCCESS;
1941 }
1942 
1969 int ABT_thread_get_arg(ABT_thread thread, void **arg)
1970 {
1971  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
1972  ABTI_CHECK_NULL_THREAD_PTR(p_thread);
1973 
1974  *arg = p_thread->p_arg;
1975  return ABT_SUCCESS;
1976 }
1977 
2004 int ABT_thread_set_specific(ABT_thread thread, ABT_key key, void *value)
2005 {
2007 
2008  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
2009  ABTI_CHECK_NULL_THREAD_PTR(p_thread);
2010 
2011  ABTI_key *p_key = ABTI_key_get_ptr(key);
2012  ABTI_CHECK_NULL_KEY_PTR(p_key);
2013 
2014  /* Set the value. */
2015  int abt_errno =
2016  ABTI_ktable_set(p_local, &p_thread->p_keytable, p_key, value);
2017  ABTI_CHECK_ERROR(abt_errno);
2018  return ABT_SUCCESS;
2019 }
2020 
2048 int ABT_thread_get_specific(ABT_thread thread, ABT_key key, void **value)
2049 {
2050  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
2051  ABTI_CHECK_NULL_THREAD_PTR(p_thread);
2052 
2053  ABTI_key *p_key = ABTI_key_get_ptr(key);
2054  ABTI_CHECK_NULL_KEY_PTR(p_key);
2055 
2056  /* Get the value. */
2057  *value = ABTI_ktable_get(&p_thread->p_keytable, p_key);
2058  return ABT_SUCCESS;
2059 }
2060 
2093 {
2094  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
2095  ABTI_CHECK_NULL_THREAD_PTR(p_thread);
2096 
2097  ABTI_thread_attr thread_attr, *p_attr;
2098  ABTI_ythread *p_ythread = ABTI_thread_get_ythread_or_null(p_thread);
2099 #ifndef ABT_CONFIG_ENABLE_VER_20_API
2100  ABTI_CHECK_TRUE(p_ythread, ABT_ERR_INV_THREAD);
2101 #endif
2102 
2103  if (p_ythread) {
2104  thread_attr.p_stack = p_ythread->p_stack;
2105  thread_attr.stacksize = p_ythread->stacksize;
2106  } else {
2107  thread_attr.p_stack = NULL;
2108  thread_attr.stacksize = 0;
2109  }
2110  thread_attr.thread_type = p_thread->type;
2111 #ifndef ABT_CONFIG_DISABLE_MIGRATION
2112  thread_attr.migratable =
2114  ABTI_thread_mig_data *p_mig_data =
2117  if (p_mig_data) {
2118  thread_attr.f_cb = p_mig_data->f_migration_cb;
2119  thread_attr.p_cb_arg = p_mig_data->p_migration_cb_arg;
2120  } else {
2121  thread_attr.f_cb = NULL;
2122  thread_attr.p_cb_arg = NULL;
2123  }
2124 #endif
2125  int abt_errno = ABTI_thread_attr_dup(&thread_attr, &p_attr);
2126  ABTI_CHECK_ERROR(abt_errno);
2127 
2128  *attr = ABTI_thread_attr_get_handle(p_attr);
2129  return ABT_SUCCESS;
2130 }
2131 
2132 /*****************************************************************************/
2133 /* Private APIs */
2134 /*****************************************************************************/
2135 
2136 void ABTI_thread_revive(ABTI_local *p_local, ABTI_pool *p_pool,
2137  void (*thread_func)(void *), void *arg,
2138  ABTI_thread *p_thread)
2139 {
2142  p_thread->f_thread = thread_func;
2143  p_thread->p_arg = arg;
2144 
2147  p_thread->p_last_xstream = NULL;
2148  p_thread->p_parent = NULL;
2149 
2150  ABTI_ythread *p_ythread = ABTI_thread_get_ythread_or_null(p_thread);
2151  if (p_thread->p_pool != p_pool) {
2152  /* Free the unit for the old pool */
2153  p_thread->p_pool->u_free(&p_thread->unit);
2154 
2155  /* Set the new pool */
2156  p_thread->p_pool = p_pool;
2157 
2158  /* Create a wrapper unit */
2159  ABT_thread h_thread = ABTI_thread_get_handle(p_thread);
2160  p_thread->unit = p_pool->u_create_from_thread(h_thread);
2161  }
2162 
2163  if (p_ythread) {
2164  /* Create a ULT context */
2165  size_t stacksize = p_ythread->stacksize;
2166  ABTD_ythread_context_create(NULL, stacksize, p_ythread->p_stack,
2167  &p_ythread->ctx);
2168  }
2169 
2170  /* Invoke a thread revive event. */
2171  ABTI_tool_event_thread_revive(p_local, p_thread,
2173  ? ABTI_local_get_xstream(p_local)
2174  ->p_thread
2175  : NULL,
2176  p_pool);
2177 
2178  LOG_DEBUG("[U%" PRIu64 "] revived\n", ABTI_thread_get_id(p_thread));
2179 
2180  /* Add this thread to the pool */
2181  ABTI_pool_push(p_pool, p_thread->unit);
2182 }
2183 
2185  ABTI_xstream *p_xstream,
2186  ABTI_ythread **p_ythread)
2187 {
2188  ABTI_thread_attr attr;
2189  ABTI_pool *p_pool;
2190 
2191  /* Get the first pool of ES */
2192  p_pool = ABTI_pool_get_ptr(p_xstream->p_main_sched->pools[0]);
2193 
2194  /* Allocate a ULT object */
2195 
2197  ABT_FALSE);
2198 
2199  /* Although this primary ULT is running now, we add this primary ULT to the
2200  * pool so that the scheduler can schedule the primary ULT when the primary
2201  * ULT is context switched to the scheduler for the first time. */
2202  ABT_bool push_pool = ABT_TRUE;
2203  int abt_errno =
2204  ythread_create(p_local, p_pool, NULL, NULL, &attr,
2206  NULL, push_pool, p_ythread);
2207  ABTI_CHECK_ERROR(abt_errno);
2208  return ABT_SUCCESS;
2209 }
2210 
2212  ABTI_xstream *p_xstream,
2213  ABTI_ythread **pp_root_ythread)
2214 {
2215  ABTI_thread_attr attr;
2216  /* Create a ULT context */
2217  if (p_xstream->type == ABTI_XSTREAM_TYPE_PRIMARY) {
2218  /* Create a thread with its stack */
2221  ABT_FALSE);
2222  } else {
2223  /* For secondary ESs, the stack of an OS thread is used. */
2225  ABT_FALSE);
2226  }
2227  ABTI_ythread *p_root_ythread;
2228  int abt_errno =
2229  ythread_create(p_local, NULL, thread_root_func, NULL, &attr,
2231  ABT_FALSE, &p_root_ythread);
2232  ABTI_CHECK_ERROR(abt_errno);
2233  *pp_root_ythread = p_root_ythread;
2234  return ABT_SUCCESS;
2235 }
2236 
2238  ABTI_xstream *p_xstream,
2239  ABTI_sched *p_sched)
2240 {
2241  ABTI_thread_attr attr;
2242 
2243  /* Allocate a ULT object and its stack */
2246  int abt_errno =
2247  ythread_create(p_local, p_xstream->p_root_pool, thread_main_sched_func,
2248  NULL, &attr,
2251  p_sched, ABT_TRUE, &p_sched->p_ythread);
2252  ABTI_CHECK_ERROR(abt_errno);
2253  return ABT_SUCCESS;
2254 }
2255 
2256 /* This routine is to create a ULT for the scheduler. */
2258  ABTI_pool *p_pool,
2259  ABTI_sched *p_sched)
2260 {
2261  ABTI_thread_attr attr;
2262 
2263  /* Allocate a ULT object and its stack */
2266  int abt_errno =
2267  ythread_create(p_local, p_pool, (void (*)(void *))p_sched->run,
2268  (void *)ABTI_sched_get_handle(p_sched), &attr,
2270  &p_sched->p_ythread);
2271  ABTI_CHECK_ERROR(abt_errno);
2272  return ABT_SUCCESS;
2273 }
2274 
2275 void ABTI_thread_join(ABTI_local **pp_local, ABTI_thread *p_thread)
2276 {
2277  thread_join(pp_local, p_thread);
2278 }
2279 
2280 void ABTI_thread_free(ABTI_local *p_local, ABTI_thread *p_thread)
2281 {
2282  LOG_DEBUG("[U%" PRIu64 ":E%d] freed\n", ABTI_thread_get_id(p_thread),
2284  ? ABTI_local_get_xstream(p_local)->rank
2285  : -1);
2286  thread_free(p_local, p_thread, ABT_TRUE);
2287 }
2288 
2289 void ABTI_ythread_free_primary(ABTI_local *p_local, ABTI_ythread *p_ythread)
2290 {
2291  ABTI_thread *p_thread = &p_ythread->thread;
2292  LOG_DEBUG("[U%" PRIu64 ":E%d] primary ULT freed\n",
2293  ABTI_thread_get_id(p_thread), p_thread->p_last_xstream->rank);
2294  thread_free(p_local, p_thread, ABT_FALSE);
2295 }
2296 
2297 void ABTI_ythread_free_root(ABTI_local *p_local, ABTI_ythread *p_ythread)
2298 {
2299  thread_free(p_local, &p_ythread->thread, ABT_FALSE);
2300 }
2301 
2302 ABTU_noreturn void ABTI_ythread_exit(ABTI_xstream *p_local_xstream,
2303  ABTI_ythread *p_ythread)
2305  /* Set the exit request */
2307 
2308  /* Terminate this ULT */
2309  ABTD_ythread_exit(p_local_xstream, p_ythread);
2310  ABTU_unreachable();
2311 }
2312 
2314  ABTI_thread *p_thread,
2315  ABTI_thread_mig_data **pp_mig_data)
2316 {
2317  ABTI_thread_mig_data *p_mig_data =
2320  if (!p_mig_data) {
2321  int abt_errno;
2322  abt_errno =
2323  ABTU_calloc(1, sizeof(ABTI_thread_mig_data), (void **)&p_mig_data);
2324  ABTI_CHECK_ERROR(abt_errno);
2325  abt_errno = ABTI_ktable_set(p_local, &p_thread->p_keytable,
2326  &g_thread_mig_data_key, (void *)p_mig_data);
2327  if (ABTI_IS_ERROR_CHECK_ENABLED && abt_errno != ABT_SUCCESS) {
2328  /* Failed to add p_mig_data to p_thread's keytable. */
2329  ABTU_free(p_mig_data);
2330  return abt_errno;
2331  }
2332  }
2333  *pp_mig_data = p_mig_data;
2334  return ABT_SUCCESS;
2335 }
2336 
2337 void ABTI_thread_print(ABTI_thread *p_thread, FILE *p_os, int indent)
2338 {
2339  if (p_thread == NULL) {
2340  fprintf(p_os, "%*s== NULL thread ==\n", indent, "");
2341  } else {
2342  ABTI_xstream *p_xstream = p_thread->p_last_xstream;
2343  int xstream_rank = p_xstream ? p_xstream->rank : 0;
2344  const char *type, *yieldable, *state, *named, *migratable;
2345 
2346  if (p_thread->type & ABTI_THREAD_TYPE_PRIMARY) {
2347  type = "PRIMARY";
2348  } else if (p_thread->type & ABTI_THREAD_TYPE_MAIN_SCHED) {
2349  type = "MAIN_SCHED";
2350  } else if (p_thread->type & ABTI_THREAD_TYPE_ROOT) {
2351  type = "ROOT";
2352  } else {
2353  type = "USER";
2354  }
2355  if (p_thread->type & ABTI_THREAD_TYPE_YIELDABLE) {
2356  yieldable = "yes";
2357  } else {
2358  yieldable = "no";
2359  }
2360  if (p_thread->type & ABTI_THREAD_TYPE_NAMED) {
2361  named = "yes";
2362  } else {
2363  named = "no";
2364  }
2365  if (p_thread->type & ABTI_THREAD_TYPE_MIGRATABLE) {
2366  migratable = "yes";
2367  } else {
2368  migratable = "no";
2369  }
2370  switch (ABTD_atomic_acquire_load_int(&p_thread->state)) {
2372  state = "READY";
2373  break;
2375  state = "RUNNING";
2376  break;
2378  state = "BLOCKED";
2379  break;
2381  state = "TERMINATED";
2382  break;
2383  default:
2384  state = "UNKNOWN";
2385  break;
2386  }
2387  ABTI_thread_mig_data *p_mig_data =
2390  void *p_migration_cb_arg =
2391  p_mig_data ? p_mig_data->p_migration_cb_arg : NULL;
2392 
2393  fprintf(p_os,
2394  "%*s== Thread (%p) ==\n"
2395  "%*sid : %" PRIu64 "\n"
2396  "%*stype : %s\n"
2397  "%*syieldable : %s\n"
2398  "%*sstate : %s\n"
2399  "%*slast_ES : %p (%d)\n"
2400  "%*sparent : %p\n"
2401  "%*sp_arg : %p\n"
2402  "%*spool : %p\n"
2403  "%*snamed : %s\n"
2404  "%*smigratable : %s\n"
2405  "%*srequest : 0x%x\n"
2406  "%*smig_cb_arg : %p\n"
2407  "%*skeytable : %p\n",
2408  indent, "", (void *)p_thread, indent, "",
2409  ABTI_thread_get_id(p_thread), indent, "", type, indent, "",
2410  yieldable, indent, "", state, indent, "", (void *)p_xstream,
2411  xstream_rank, indent, "", (void *)p_thread->p_parent, indent,
2412  "", p_thread->p_arg, indent, "", (void *)p_thread->p_pool,
2413  indent, "", named, indent, "", migratable, indent, "",
2414  ABTD_atomic_acquire_load_uint32(&p_thread->request), indent, "",
2415  p_migration_cb_arg, indent, "",
2416  ABTD_atomic_acquire_load_ptr(&p_thread->p_keytable));
2417 
2418  if (p_thread->type & ABTI_THREAD_TYPE_YIELDABLE) {
2419  ABTI_ythread *p_ythread = ABTI_thread_get_ythread(p_thread);
2420  fprintf(p_os,
2421  "%*sstack : %p\n"
2422  "%*sstacksize : %zu\n",
2423  indent, "", p_ythread->p_stack, indent, "",
2424  p_ythread->stacksize);
2425  }
2426  }
2427  fflush(p_os);
2428 }
2429 
2433 {
2435 }
2436 
2438 {
2439  if (p_thread == NULL)
2440  return ABTI_THREAD_INIT_ID;
2441 
2442  if (p_thread->id == ABTI_THREAD_INIT_ID) {
2443  p_thread->id = thread_get_new_id();
2444  }
2445  return p_thread->id;
2446 }
2447 
2448 /*****************************************************************************/
2449 /* Internal static functions */
2450 /*****************************************************************************/
2451 
2452 ABTU_ret_err static inline int
2453 ythread_create(ABTI_local *p_local, ABTI_pool *p_pool,
2454  void (*thread_func)(void *), void *arg, ABTI_thread_attr *p_attr,
2455  ABTI_thread_type thread_type, ABTI_sched *p_sched,
2456  ABT_bool push_pool, ABTI_ythread **pp_newthread)
2457 {
2458  int abt_errno;
2459  ABTI_ythread *p_newthread;
2460  ABT_thread h_newthread;
2461  ABTI_ktable *p_keytable = NULL;
2462 
2463  /* Allocate a ULT object and its stack, then create a thread context. */
2464  if (!p_attr) {
2465  abt_errno = ABTI_mem_alloc_ythread_default(p_local, &p_newthread);
2466  ABTI_CHECK_ERROR(abt_errno);
2467 #ifndef ABT_CONFIG_DISABLE_MIGRATION
2468  thread_type |= ABTI_THREAD_TYPE_MIGRATABLE;
2469 #endif
2470  } else {
2471  ABTI_thread_type attr_type = p_attr->thread_type;
2472  if (attr_type & ABTI_THREAD_TYPE_MEM_MEMPOOL_DESC_STACK) {
2473 #ifdef ABT_CONFIG_USE_MEM_POOL
2474  abt_errno =
2475  ABTI_mem_alloc_ythread_mempool_desc_stack(p_local, p_attr,
2476  &p_newthread);
2477  ABTI_CHECK_ERROR(abt_errno);
2478 #else
2479  abt_errno =
2480  ABTI_mem_alloc_ythread_malloc_desc_stack(p_attr, &p_newthread);
2481 #endif
2482  ABTI_CHECK_ERROR(abt_errno);
2483  } else if (attr_type & ABTI_THREAD_TYPE_MEM_MALLOC_DESC_STACK) {
2484  abt_errno =
2485  ABTI_mem_alloc_ythread_malloc_desc_stack(p_attr, &p_newthread);
2486  ABTI_CHECK_ERROR(abt_errno);
2487  } else {
2490  /* Let's try to use mempool first since it performs better. */
2491  abt_errno = ABTI_mem_alloc_ythread_mempool_desc(p_local, p_attr,
2492  &p_newthread);
2493  ABTI_CHECK_ERROR(abt_errno);
2494  }
2495 #ifndef ABT_CONFIG_DISABLE_MIGRATION
2496  thread_type |= p_attr->migratable ? ABTI_THREAD_TYPE_MIGRATABLE : 0;
2497  if (ABTU_unlikely(p_attr->f_cb)) {
2498  ABTI_thread_mig_data *p_mig_data;
2499  abt_errno = ABTU_calloc(1, sizeof(ABTI_thread_mig_data),
2500  (void **)&p_mig_data);
2502  ABTU_unlikely(abt_errno != ABT_SUCCESS)) {
2503  ABTI_mem_free_thread(p_local, &p_newthread->thread);
2504  return abt_errno;
2505  }
2506  p_mig_data->f_migration_cb = p_attr->f_cb;
2507  p_mig_data->p_migration_cb_arg = p_attr->p_cb_arg;
2508  abt_errno = ABTI_ktable_set_unsafe(p_local, &p_keytable,
2510  (void *)p_mig_data);
2512  ABTU_unlikely(abt_errno != ABT_SUCCESS)) {
2513  if (p_keytable)
2514  ABTI_ktable_free(p_local, p_keytable);
2515  ABTU_free(p_mig_data);
2516  ABTI_mem_free_thread(p_local, &p_newthread->thread);
2517  return abt_errno;
2518  }
2519  }
2520 #endif
2521  }
2522 
2523  if (thread_type & (ABTI_THREAD_TYPE_PRIMARY | ABTI_THREAD_TYPE_ROOT)) {
2524  if (p_newthread->p_stack == NULL) {
2525  /* We don't need to initialize the context if a thread will run on
2526  * OS-level threads. Invalidate the context here. */
2527  ABTD_ythread_context_invalidate(&p_newthread->ctx);
2528  } else {
2529  /* Create the context. This thread is special, so dynamic promotion
2530  * is not supported. */
2531  size_t stack_size = p_newthread->stacksize;
2532  void *p_stack = p_newthread->p_stack;
2533  ABTD_ythread_context_create(NULL, stack_size, p_stack,
2534  &p_newthread->ctx);
2535  }
2536  } else {
2537 #if ABT_CONFIG_THREAD_TYPE != ABT_THREAD_TYPE_DYNAMIC_PROMOTION
2538  size_t stack_size = p_newthread->stacksize;
2539  void *p_stack = p_newthread->p_stack;
2540  ABTD_ythread_context_create(NULL, stack_size, p_stack,
2541  &p_newthread->ctx);
2542 #else
2543  /* The context is not fully created now. */
2544  ABTD_ythread_context_init(NULL, &p_newthread->ctx);
2545 #endif
2546  }
2547  p_newthread->thread.f_thread = thread_func;
2548  p_newthread->thread.p_arg = arg;
2549 
2553  p_newthread->thread.p_last_xstream = NULL;
2554  p_newthread->thread.p_parent = NULL;
2555  p_newthread->thread.p_pool = p_pool;
2556  p_newthread->thread.type |= thread_type;
2557  p_newthread->thread.id = ABTI_THREAD_INIT_ID;
2558  if (p_sched && !(thread_type & (ABTI_THREAD_TYPE_PRIMARY |
2560  /* Set a destructor for p_sched. */
2561  abt_errno = ABTI_ktable_set_unsafe(p_local, &p_keytable,
2562  &g_thread_sched_key, p_sched);
2564  ABTU_unlikely(abt_errno != ABT_SUCCESS)) {
2565  if (p_keytable)
2566  ABTI_ktable_free(p_local, p_keytable);
2567  ABTI_mem_free_thread(p_local, &p_newthread->thread);
2568  return abt_errno;
2569  }
2570  }
2571  ABTD_atomic_relaxed_store_ptr(&p_newthread->thread.p_keytable, p_keytable);
2572 
2573 #ifdef ABT_CONFIG_USE_DEBUG_LOG
2574  ABT_unit_id thread_id = ABTI_thread_get_id(&p_newthread->thread);
2575  if (thread_type & ABTI_THREAD_TYPE_PRIMARY) {
2576  LOG_DEBUG("[U%" PRIu64 "] primary ULT created\n", thread_id);
2577  } else if (thread_type & ABTI_THREAD_TYPE_MAIN_SCHED) {
2578  LOG_DEBUG("[U%" PRIu64 "] main sched ULT created\n", thread_id);
2579  } else {
2580  LOG_DEBUG("[U%" PRIu64 "] created\n", thread_id);
2581  }
2582 #endif
2583 
2584  /* Invoke a thread creation event. */
2585  ABTI_tool_event_thread_create(p_local, &p_newthread->thread,
2587  ? ABTI_local_get_xstream(p_local)
2588  ->p_thread
2589  : NULL,
2590  push_pool ? p_pool : NULL);
2591 
2592  /* Create a wrapper unit */
2593  h_newthread = ABTI_ythread_get_handle(p_newthread);
2594  if (push_pool) {
2595  p_newthread->thread.unit = p_pool->u_create_from_thread(h_newthread);
2596  /* Add this thread to the pool */
2597  ABTI_pool_push(p_pool, p_newthread->thread.unit);
2598  } else {
2599  p_newthread->thread.unit = ABT_UNIT_NULL;
2600  }
2601 
2602  /* Return value */
2603  *pp_newthread = p_newthread;
2604  return ABT_SUCCESS;
2605 }
2606 
2607 #ifndef ABT_CONFIG_DISABLE_MIGRATION
2608 ABTU_ret_err static int thread_migrate_to_pool(ABTI_local *p_local,
2609  ABTI_thread *p_thread,
2610  ABTI_pool *p_pool)
2611 {
2612  /* Adding request to the thread. p_migration_pool must be updated before
2613  * setting the request since the target thread would read p_migration_pool
2614  * after ABTI_THREAD_REQ_MIGRATE. The update must be "atomic" (but does not
2615  * require acq-rel) since two threads can update the pointer value
2616  * simultaneously. */
2617 
2618  ABTI_thread_mig_data *p_mig_data;
2619  int abt_errno = ABTI_thread_get_mig_data(p_local, p_thread, &p_mig_data);
2620  ABTI_CHECK_ERROR(abt_errno);
2621 
2623  (void *)p_pool);
2625  return ABT_SUCCESS;
2626 }
2627 #endif
2628 
2629 static inline void thread_free(ABTI_local *p_local, ABTI_thread *p_thread,
2630  ABT_bool free_unit)
2632  /* Invoke a thread freeing event. */
2633  ABTI_tool_event_thread_free(p_local, p_thread,
2635  ? ABTI_local_get_xstream(p_local)->p_thread
2636  : NULL);
2637 
2638  /* Free the unit */
2639  if (free_unit) {
2640  p_thread->p_pool->u_free(&p_thread->unit);
2641  }
2642 
2643  /* Free the key-value table */
2644  ABTI_ktable *p_ktable = ABTD_atomic_acquire_load_ptr(&p_thread->p_keytable);
2645  /* No parallel access to TLS is allowed. */
2646  ABTI_ASSERT(p_ktable != ABTI_KTABLE_LOCKED);
2647  if (p_ktable) {
2648  ABTI_ktable_free(p_local, p_ktable);
2649  }
2650 
2651  /* Free ABTI_thread (stack will also be freed) */
2652  ABTI_mem_free_thread(p_local, p_thread);
2653 }
2654 
2655 static void thread_key_destructor_stackable_sched(void *p_value)
2656 {
2657  /* This destructor should be called in ABTI_ythread_free(), so it should not
2658  * free the thread again. */
2659  ABTI_sched *p_sched = (ABTI_sched *)p_value;
2660  p_sched->used = ABTI_SCHED_NOT_USED;
2661  if (p_sched->automatic == ABT_TRUE) {
2662  p_sched->p_ythread = NULL;
2664  }
2665 }
2666 
2667 static void thread_key_destructor_migration(void *p_value)
2668 {
2669  ABTI_thread_mig_data *p_mig_data = (ABTI_thread_mig_data *)p_value;
2670  ABTU_free(p_mig_data);
2671 }
2672 
2673 static void thread_join_busywait(ABTI_thread *p_thread)
2674 {
2675  while (ABTD_atomic_acquire_load_int(&p_thread->state) !=
2678  }
2679  ABTI_tool_event_thread_join(NULL, p_thread, NULL);
2680 }
2681 
2682 static void thread_join_yield_thread(ABTI_xstream **pp_local_xstream,
2683  ABTI_ythread *p_self,
2684  ABTI_thread *p_thread)
2685 {
2686  while (ABTD_atomic_acquire_load_int(&p_thread->state) !=
2688  ABTI_ythread_yield(pp_local_xstream, p_self,
2689  ABT_SYNC_EVENT_TYPE_THREAD_JOIN, (void *)p_thread);
2690  }
2692  p_thread, &p_self->thread);
2693 }
2694 
2695 static inline void thread_join(ABTI_local **pp_local, ABTI_thread *p_thread)
2696 {
2699  ABTI_tool_event_thread_join(*pp_local, p_thread,
2701  ? ABTI_local_get_xstream(*pp_local)
2702  ->p_thread
2703  : NULL);
2704  return;
2705  }
2706  /* The primary ULT cannot be joined. */
2707  ABTI_ASSERT(!(p_thread->type & ABTI_THREAD_TYPE_PRIMARY));
2708 
2709  ABTI_xstream *p_local_xstream = ABTI_local_get_xstream_or_null(*pp_local);
2710  if (ABTI_IS_EXT_THREAD_ENABLED && !p_local_xstream) {
2711  thread_join_busywait(p_thread);
2712  return;
2713  }
2714 
2715  ABTI_thread *p_self_thread = p_local_xstream->p_thread;
2716 
2717  ABTI_ythread *p_self = ABTI_thread_get_ythread_or_null(p_self_thread);
2718  if (!p_self) {
2719  thread_join_busywait(p_thread);
2720  return;
2721  }
2722 
2723  /* The target ULT should be different. */
2724  ABTI_ASSERT(p_thread != p_self_thread);
2725 
2726  ABTI_ythread *p_ythread = ABTI_thread_get_ythread_or_null(p_thread);
2727  if (!p_ythread) {
2728  thread_join_yield_thread(&p_local_xstream, p_self, p_thread);
2729  *pp_local = ABTI_xstream_get_local(p_local_xstream);
2730  return;
2731  }
2732 
2733  /* Tell p_ythread that there has been a join request. */
2734  /* If request already has ABTI_THREAD_REQ_JOIN, p_ythread is
2735  * terminating. We can't block p_self in this case. */
2736  uint32_t req = ABTD_atomic_fetch_or_uint32(&p_ythread->thread.request,
2738  if (req & ABTI_THREAD_REQ_JOIN) {
2739  thread_join_yield_thread(&p_local_xstream, p_self, &p_ythread->thread);
2740  *pp_local = ABTI_xstream_get_local(p_local_xstream);
2741  return;
2742  }
2743 
2744  ABTI_ythread_set_blocked(p_self);
2745  LOG_DEBUG("[U%" PRIu64 ":E%d] blocked to join U%" PRIu64 "\n",
2746  ABTI_thread_get_id(&p_self->thread),
2747  p_self->thread.p_last_xstream->rank,
2748  ABTI_thread_get_id(&p_ythread->thread));
2749 
2750  /* Set the link in the context of the target ULT. This p_link might be
2751  * read by p_ythread running on another ES in parallel, so release-store
2752  * is needed here. */
2754  &p_self->ctx);
2755 
2756  /* Suspend the current ULT */
2757  ABTI_ythread_suspend(&p_local_xstream, p_self,
2758  ABT_SYNC_EVENT_TYPE_THREAD_JOIN, (void *)p_ythread);
2759  *pp_local = ABTI_xstream_get_local(p_local_xstream);
2760 
2761  /* Resume */
2762  /* If p_self's state is BLOCKED, the target ULT has terminated on the same
2763  * ES as p_self's ES and the control has come from the target ULT.
2764  * Otherwise, the target ULT had been migrated to a different ES, p_self
2765  * has been resumed by p_self's scheduler. In the latter case, we don't
2766  * need to change p_self's state. */
2767  if (ABTD_atomic_relaxed_load_int(&p_self->thread.state) ==
2772  LOG_DEBUG("[U%" PRIu64 ":E%d] resume after join\n",
2773  ABTI_thread_get_id(&p_self->thread),
2774  p_self->thread.p_last_xstream->rank);
2775  ABTI_tool_event_thread_join(*pp_local, p_thread, &p_self->thread);
2776  } else {
2777  /* Use a yield-based method. */
2778  thread_join_yield_thread(&p_local_xstream, p_self, &p_ythread->thread);
2779  *pp_local = ABTI_xstream_get_local(p_local_xstream);
2780  return;
2781  }
2782 }
2783 
2784 static void thread_root_func(void *arg)
2785 {
2786  /* root thread is working on a special context, so it should not rely on
2787  * functionality that needs yield. */
2788  ABTI_local *p_local = ABTI_local_get_local();
2789  ABTI_xstream *p_local_xstream = ABTI_local_get_xstream(p_local);
2790  ABTI_ASSERT(ABTD_atomic_relaxed_load_int(&p_local_xstream->state) ==
2792 
2793  ABTI_ythread *p_root_ythread = p_local_xstream->p_root_ythread;
2794  p_local_xstream->p_thread = &p_root_ythread->thread;
2795  ABTI_pool *p_root_pool = p_local_xstream->p_root_pool;
2796 
2797  do {
2798  ABT_unit unit = ABTI_pool_pop(p_root_pool);
2799  if (unit != ABT_UNIT_NULL) {
2800  ABTI_xstream *p_xstream = p_local_xstream;
2801  ABTI_xstream_run_unit(&p_xstream, unit, p_root_pool);
2802  /* The root thread must be executed on the same execution stream. */
2803  ABTI_ASSERT(p_xstream == p_local_xstream);
2804  }
2806  &p_local_xstream->p_main_sched->p_ythread->thread.state) !=
2808  /* The main scheduler thread finishes. */
2809 
2810  /* Set the ES's state as TERMINATED */
2811  ABTD_atomic_release_store_int(&p_local_xstream->state,
2813 
2814  if (p_local_xstream->type == ABTI_XSTREAM_TYPE_PRIMARY) {
2815  /* Let us jump back to the primary thread (then finalize Argobots) */
2816  ABTD_ythread_finish_context(&p_root_ythread->ctx,
2818  }
2819 }
2820 
2821 static void thread_main_sched_func(void *arg)
2822 {
2824  ABTI_xstream *p_local_xstream = ABTI_local_get_xstream(p_local);
2825 
2826  while (1) {
2827  /* Execute the run function of scheduler */
2828  ABTI_sched *p_sched = p_local_xstream->p_main_sched;
2829  ABTI_ASSERT(p_local_xstream->p_thread == &p_sched->p_ythread->thread);
2830 
2831  LOG_DEBUG("[S%" PRIu64 "] start\n", p_sched->id);
2832  p_sched->run(ABTI_sched_get_handle(p_sched));
2833  /* From here the main scheduler can have been already replaced. */
2834  /* The main scheduler must be executed on the same execution stream. */
2836  LOG_DEBUG("[S%" PRIu64 "] end\n", p_sched->id);
2837 
2838  p_sched = p_local_xstream->p_main_sched;
2839  uint32_t request = ABTD_atomic_acquire_load_uint32(
2840  &p_sched->p_ythread->thread.request);
2841 
2842  /* If there is an exit or a cancel request, the ES terminates
2843  * regardless of remaining work units. */
2845  break;
2846 
2847  /* When join is requested, the ES terminates after finishing
2848  * execution of all work units. */
2849  if ((ABTD_atomic_relaxed_load_uint32(&p_sched->request) &
2851  ABTI_sched_get_effective_size(p_local, p_sched) == 0) {
2852  break;
2853  }
2854  }
2855  /* Finish this thread and goes back to the root thread. */
2856 }
2857 
2858 static inline ABT_unit_id thread_get_new_id(void)
2859 {
2861 }
ABTI_key
Definition: abti.h:386
ABT_THREAD_STATE_TERMINATED
@ ABT_THREAD_STATE_TERMINATED
Definition: abt.h:415
ABT_thread_migrate_to_xstream
int ABT_thread_migrate_to_xstream(ABT_thread thread, ABT_xstream xstream)
Request a migration of a work unit to a specific execution stream.
Definition: thread.c:1233
ABT_SYNC_EVENT_TYPE_USER
@ ABT_SYNC_EVENT_TYPE_USER
Definition: abt.h:651
ABTI_CHECK_NULL_SCHED_PTR
#define ABTI_CHECK_NULL_SCHED_PTR(p)
Definition: abti_error.h:184
ABT_key
struct ABT_key_opaque * ABT_key
Work-unit-specific data key handle type.
Definition: abt.h:925
ABT_ERR_INV_THREAD
#define ABT_ERR_INV_THREAD
Error code: invalid work unit.
Definition: abt.h:175
ABTI_sched_get_ptr
static ABTI_sched * ABTI_sched_get_ptr(ABT_sched sched)
Definition: abti_sched.h:11
ABT_thread_get_arg
int ABT_thread_get_arg(ABT_thread thread, void **arg)
Retrieve an argument for a work unit function of a work unit.
Definition: thread.c:1971
ABT_thread_resume
int ABT_thread_resume(ABT_thread thread)
Resume a ULT.
Definition: thread.c:1162
ABTI_thread_print
void ABTI_thread_print(ABTI_thread *p_thread, FILE *p_os, int indent)
Definition: thread.c:2339
ABTI_mem_free_thread
static void ABTI_mem_free_thread(ABTI_local *p_local, ABTI_thread *p_thread)
Definition: abti_mem.h:244
ABT_thread_is_primary
int ABT_thread_is_primary(ABT_thread thread, ABT_bool *is_primary)
Check if a work unit is the primary ULT.
Definition: thread.c:1742
ABTI_thread_mig_data::f_migration_cb
void(* f_migration_cb)(ABT_thread, void *)
Definition: abti.h:373
ABT_bool
int ABT_bool
Boolean type.
Definition: abt.h:988
ABTD_atomic_release_store_ythread_context_ptr
static void ABTD_atomic_release_store_ythread_context_ptr(ABTD_ythread_context_atomic_ptr *ptr, ABTD_ythread_context *p_ctx)
Definition: abtd_context.h:49
ABTI_global::sched_stacksize
size_t sched_stacksize
Definition: abti.h:191
ABTI_XSTREAM_TYPE_PRIMARY
@ ABTI_XSTREAM_TYPE_PRIMARY
Definition: abti.h:65
ABTI_THREAD_REQ_TERMINATE
#define ABTI_THREAD_REQ_TERMINATE
Definition: abti.h:42
ABTI_SCHED_NOT_USED
@ ABTI_SCHED_NOT_USED
Definition: abti.h:70
ABTI_THREAD_TYPE_ROOT
#define ABTI_THREAD_TYPE_ROOT
Definition: abti.h:77
ABTI_SETUP_LOCAL_XSTREAM
#define ABTI_SETUP_LOCAL_XSTREAM(pp_local_xstream)
Definition: abti_error.h:68
ABTI_ktable_get
static void * ABTI_ktable_get(ABTD_atomic_ptr *pp_ktable, ABTI_key *p_key)
Definition: abti_key.h:283
ABTI_mem_alloc_ythread_default
static ABTU_ret_err int ABTI_mem_alloc_ythread_default(ABTI_local *p_local, ABTI_ythread **pp_ythread)
Definition: abti_mem.h:133
ABT_THREAD_STATE_READY
@ ABT_THREAD_STATE_READY
Definition: abt.h:409
ABTI_ktable_free
void ABTI_ktable_free(ABTI_local *p_local, ABTI_ktable *p_ktable)
Definition: key.c:226
ABTD_ythread_context_init
static void ABTD_ythread_context_init(ABTD_ythread_context *p_link, ABTD_ythread_context *p_newctx)
Definition: abtd_ythread.h:47
ABTD_atomic_uint64
Definition: abtd_atomic.h:35
ABTD_atomic_acquire_load_uint32
static uint32_t ABTD_atomic_acquire_load_uint32(const ABTD_atomic_uint32 *ptr)
Definition: abtd_atomic.h:928
ABTD_ythread_exit
void ABTD_ythread_exit(ABTI_xstream *p_local_xstream, ABTI_ythread *p_ythread)
Definition: abtd_ythread.c:30
thread_main_sched_func
static void thread_main_sched_func(void *arg)
Definition: thread.c:2823
ABT_thread_attr
struct ABT_thread_attr_opaque * ABT_thread_attr
ULT attribute handle type.
Definition: abt.h:884
ABT_thread
struct ABT_thread_opaque * ABT_thread
Work unit handle type.
Definition: abt.h:877
ABTI_thread_mig_data::p_migration_pool
ABTD_atomic_ptr p_migration_pool
Definition: abti.h:376
g_thread_id
static ABTD_atomic_uint64 g_thread_id
Definition: thread.c:2432
ABT_thread_join_many
int ABT_thread_join_many(int num_threads, ABT_thread *thread_list)
Wait for a set of work units to terminate.
Definition: thread.c:562
ABTI_key_get_ptr
static ABTI_key * ABTI_key_get_ptr(ABT_key key)
Definition: abti_key.h:11
ABT_thread_create_many
int ABT_thread_create_many(int num_threads, ABT_pool *pool_list, void(**thread_func_list)(void *), void **arg_list, ABT_thread_attr attr, ABT_thread *newthread_list)
Create a set of new ULTs.
Definition: thread.c:245
ABTI_ythread_context_switch_to_sibling
static ABTI_ythread * ABTI_ythread_context_switch_to_sibling(ABTI_xstream **pp_local_xstream, ABTI_ythread *p_old, ABTI_ythread *p_new)
Definition: abti_ythread.h:319
ythread_create
static ABTU_ret_err int ythread_create(ABTI_local *p_local, ABTI_pool *p_pool, void(*thread_func)(void *), void *arg, ABTI_thread_attr *p_attr, ABTI_thread_type thread_type, ABTI_sched *p_sched, ABT_bool push_pool, ABTI_ythread **pp_newthread)
Definition: thread.c:2455
ABTI_ythread_free_primary
void ABTI_ythread_free_primary(ABTI_local *p_local, ABTI_ythread *p_ythread)
Definition: thread.c:2291
ABTI_ythread_create_root
ABTU_ret_err int ABTI_ythread_create_root(ABTI_local *p_local, ABTI_xstream *p_xstream, ABTI_ythread **pp_root_ythread)
Definition: thread.c:2213
ABTI_thread::type
ABTI_thread_type type
Definition: abti.h:348
ABT_thread_get_stacksize
int ABT_thread_get_stacksize(ABT_thread thread, size_t *stacksize)
Get a stack size of a work unit.
Definition: thread.c:1862
ABTI_THREAD_TYPE_MEM_MEMPOOL_DESC
#define ABTI_THREAD_TYPE_MEM_MEMPOOL_DESC
Definition: abti.h:84
ABTI_thread_attr::migratable
ABT_bool migratable
Definition: abti.h:366
ABTI_ythread_exit
ABTU_noreturn void ABTI_ythread_exit(ABTI_xstream *p_local_xstream, ABTI_ythread *p_ythread)
Definition: thread.c:2304
ABTI_tool_event_thread_create
#define ABTI_tool_event_thread_create(p_local, p_thread, p_caller, p_pool)
Definition: abti_tool.h:258
ABTI_ythread_create_main_sched
ABTU_ret_err int ABTI_ythread_create_main_sched(ABTI_local *p_local, ABTI_xstream *p_xstream, ABTI_sched *p_sched)
Definition: thread.c:2239
ABT_thread_set_migratable
int ABT_thread_set_migratable(ABT_thread thread, ABT_bool migratable)
Set the migratability in a work unit.
Definition: thread.c:1643
ABT_ERR_POOL
#define ABT_ERR_POOL
Error code: an error related to a pool.
Definition: abt.h:281
ABTI_THREAD_INIT_ID
#define ABTI_THREAD_INIT_ID
Definition: abti.h:53
ABTI_CHECK_ERROR
#define ABTI_CHECK_ERROR(abt_errno)
Definition: abti_error.h:127
ABTI_ythread::stacksize
size_t stacksize
Definition: abti.h:383
ABTI_thread_attr_get_handle
static ABT_thread_attr ABTI_thread_attr_get_handle(ABTI_thread_attr *p_attr)
Definition: abti_thread_attr.h:27
ABTI_sched::num_pools
size_t num_pools
Definition: abti.h:272
ABTI_sched::automatic
ABT_bool automatic
Definition: abti.h:267
ABTI_xstream::rank
int rank
Definition: abti.h:245
ABT_thread_get_id
int ABT_thread_get_id(ABT_thread thread, ABT_unit_id *thread_id)
Get ID of a work unit.
Definition: thread.c:1901
gp_ABTI_global
ABTI_global * gp_ABTI_global
Definition: global.c:18
ABTI_thread::p_arg
void * p_arg
Definition: abti.h:353
ABTI_sched_get_handle
static ABT_sched ABTI_sched_get_handle(ABTI_sched *p_sched)
Definition: abti_sched.h:26
ABTU_noreturn
#define ABTU_noreturn
Definition: abtu.h:122
ABTI_thread::unit
ABT_unit unit
Definition: abti.h:349
ABTI_xstream::type
ABTI_xstream_type type
Definition: abti.h:246
ABTI_THREAD_TYPE_YIELDABLE
#define ABTI_THREAD_TYPE_YIELDABLE
Definition: abti.h:80
ABTI_thread::request
ABTD_atomic_uint32 request
Definition: abti.h:355
ABTI_thread_get_ythread
static ABTI_ythread * ABTI_thread_get_ythread(ABTI_thread *p_thread)
Definition: abti_thread.h:52
ABTI_thread_mig_data
Definition: abti.h:372
ABTI_SETUP_LOCAL_YTHREAD_WITH_INIT_CHECK
#define ABTI_SETUP_LOCAL_YTHREAD_WITH_INIT_CHECK(pp_local_xstream, pp_ythread)
Definition: abti_error.h:115
ABTI_pool_push
static void ABTI_pool_push(ABTI_pool *p_pool, ABT_unit unit)
Definition: abti_pool.h:53
ABT_THREAD_NULL
#define ABT_THREAD_NULL
Definition: abt.h:1049
ABTI_thread_get_handle
static ABT_thread ABTI_thread_get_handle(ABTI_thread *p_thread)
Definition: abti_thread.h:24
ABTI_pool::u_create_from_thread
ABT_unit_create_from_thread_fn u_create_from_thread
Definition: abti.h:312
ABTI_THREAD_TYPE_MEM_MEMPOOL_DESC_STACK
#define ABTI_THREAD_TYPE_MEM_MEMPOOL_DESC_STACK
Definition: abti.h:86
ABTI_thread_reset_id
void ABTI_thread_reset_id(void)
Definition: thread.c:2434
ABTI_thread
Definition: abti.h:344
ABTI_IS_ERROR_CHECK_ENABLED
#define ABTI_IS_ERROR_CHECK_ENABLED
Definition: abti.h:20
ABTI_CHECK_YIELDABLE
#define ABTI_CHECK_YIELDABLE(p_thread, pp_ythread, abt_errno)
Definition: abti_error.h:146
ABTD_ythread_context::p_link
ABTD_ythread_context_atomic_ptr p_link
Definition: abtd_fcontext.h:36
ABTI_thread_attr_get_ptr
static ABTI_thread_attr * ABTI_thread_attr_get_ptr(ABT_thread_attr attr)
Definition: abti_thread_attr.h:11
ABTI_KEY_STATIC_INITIALIZER
#define ABTI_KEY_STATIC_INITIALIZER(f_destructor, id)
Definition: abti_key.h:42
ABT_thread_get_state
int ABT_thread_get_state(ABT_thread thread, ABT_thread_state *state)
Get a state of a work unit.
Definition: thread.c:822
ABTI_xstream
Definition: abti.h:240
ABTI_tool_event_thread_revive
#define ABTI_tool_event_thread_revive(p_local, p_thread, p_caller, p_pool)
Definition: abti_tool.h:280
ABT_pool
struct ABT_pool_opaque * ABT_pool
Pool handle type.
Definition: abt.h:828
ABT_ERR_THREAD
#define ABT_ERR_THREAD
Error code: an error related to a work unit.
Definition: abt.h:291
ABTI_sched::p_ythread
ABTI_ythread * p_ythread
Definition: abti.h:273
ABTI_xstream::p_next
ABTI_xstream * p_next
Definition: abti.h:243
ABT_thread_state
ABT_thread_state
State of a work unit.
Definition: abt.h:407
ABT_thread_free
int ABT_thread_free(ABT_thread *thread)
Free a work unit.
Definition: thread.c:406
ABTI_thread_attr
Definition: abti.h:361
g_thread_sched_key
static ABTI_key g_thread_sched_key
Definition: thread.c:26
ABTU_unreachable
#define ABTU_unreachable()
Definition: abtu.h:116
ABTI_sched::used
ABTI_sched_used used
Definition: abti.h:266
ABT_sched
struct ABT_sched_opaque * ABT_sched
Scheduler handle type.
Definition: abt.h:795
ABTI_pool
Definition: abti.h:300
ABTI_THREAD_TYPE_PRIMARY
#define ABTI_THREAD_TYPE_PRIMARY
Definition: abti.h:78
ABTI_ythread_free_root
void ABTI_ythread_free_root(ABTI_local *p_local, ABTI_ythread *p_ythread)
Definition: thread.c:2299
ABT_thread_migrate_to_sched
int ABT_thread_migrate_to_sched(ABT_thread thread, ABT_sched sched)
Request a migration of a work unit to a specific scheduler.
Definition: thread.c:1316
ABTI_ythread_create_sched
ABTU_ret_err int ABTI_ythread_create_sched(ABTI_local *p_local, ABTI_pool *p_pool, ABTI_sched *p_sched)
Definition: thread.c:2259
ABT_thread_exit
int ABT_thread_exit(void)
Terminate a calling ULT.
Definition: thread.c:598
ABTI_xstream_get_handle
static ABT_xstream ABTI_xstream_get_handle(ABTI_xstream *p_xstream)
Definition: abti_stream.h:26
ABTD_atomic_release_store_uint64
static void ABTD_atomic_release_store_uint64(ABTD_atomic_uint64 *ptr, uint64_t val)
Definition: abtd_atomic.h:1124
ABT_THREAD_STATE_BLOCKED
@ ABT_THREAD_STATE_BLOCKED
Definition: abt.h:413
abti.h
ABTI_CHECK_NULL_THREAD_PTR
#define ABTI_CHECK_NULL_THREAD_PTR(p)
Definition: abti_error.h:202
ABTI_THREAD_REQ_MIGRATE
#define ABTI_THREAD_REQ_MIGRATE
Definition: abti.h:44
ABT_thread_set_specific
int ABT_thread_set_specific(ABT_thread thread, ABT_key key, void *value)
Set a value with a work-unit-specific key in a work unit.
Definition: thread.c:2006
ABTD_atomic_relaxed_store_uint32
static void ABTD_atomic_relaxed_store_uint32(ABTD_atomic_uint32 *ptr, uint32_t val)
Definition: abtd_atomic.h:1025
ABTD_atomic_relaxed_load_int
static int ABTD_atomic_relaxed_load_int(const ABTD_atomic_int *ptr)
Definition: abtd_atomic.h:763
ABTI_KEY_ID_STACKABLE_SCHED
#define ABTI_KEY_ID_STACKABLE_SCHED
Definition: abti_key.h:47
ABTI_thread_get_mig_data
ABTU_ret_err int ABTI_thread_get_mig_data(ABTI_local *p_local, ABTI_thread *p_thread, ABTI_thread_mig_data **pp_mig_data)
Definition: thread.c:2315
thread_migrate_to_pool
static ABTU_ret_err int thread_migrate_to_pool(ABTI_local *p_local, ABTI_thread *p_thread, ABTI_pool *p_pool)
Definition: thread.c:2610
ABT_unit_id
uint64_t ABT_unit_id
Work unit ID type.
Definition: abt.h:866
ABT_xstream
struct ABT_xstream_opaque * ABT_xstream
Execution stream handle type.
Definition: abt.h:776
ABTI_thread_get_ythread_or_null
static ABTI_ythread * ABTI_thread_get_ythread_or_null(ABTI_thread *p_thread)
Definition: abti_thread.h:59
ABTI_thread::state
ABTD_atomic_int state
Definition: abti.h:354
ABTI_pool::u_is_in_pool
ABT_unit_is_in_pool_fn u_is_in_pool
Definition: abti.h:311
ABT_thread_yield
int ABT_thread_yield(void)
Yield the calling ULT to its parent ULT.
Definition: thread.c:1109
ABT_thread_get_last_pool
int ABT_thread_get_last_pool(ABT_thread thread, ABT_pool *pool)
Get the last pool of a work unit.
Definition: thread.c:862
ABTI_HANDLE_ERROR
#define ABTI_HANDLE_ERROR(n)
Definition: abti_error.h:121
thread_key_destructor_migration
static void thread_key_destructor_migration(void *p_value)
Definition: thread.c:2669
ABTD_atomic_pause
static void ABTD_atomic_pause(void)
Definition: abtd_atomic.h:1257
ABTU_malloc
static ABTU_ret_err int ABTU_malloc(size_t size, void **p_ptr)
Definition: abtu.h:218
LOG_DEBUG
#define LOG_DEBUG(fmt,...)
Definition: abti_log.h:26
ABTI_THREAD_TYPE_MIGRATABLE
#define ABTI_THREAD_TYPE_MIGRATABLE
Definition: abti.h:82
ABTI_pool_remove
static ABTU_ret_err int ABTI_pool_remove(ABTI_pool *p_pool, ABT_unit unit)
Definition: abti_pool.h:68
ABTI_thread_join
void ABTI_thread_join(ABTI_local **pp_local, ABTI_thread *p_thread)
Definition: thread.c:2277
ABTD_atomic_relaxed_store_int
static void ABTD_atomic_relaxed_store_int(ABTD_atomic_int *ptr, int val)
Definition: abtd_atomic.h:996
ABT_thread_set_associated_pool
int ABT_thread_set_associated_pool(ABT_thread thread, ABT_pool pool)
Set an associated pool for the target work unit.
Definition: thread.c:941
ABT_thread_join
int ABT_thread_join(ABT_thread thread)
Wait for a work unit to terminate.
Definition: thread.c:515
ABTD_ATOMIC_UINT64_STATIC_INITIALIZER
#define ABTD_ATOMIC_UINT64_STATIC_INITIALIZER(val)
Definition: abtd_atomic.h:67
ABTD_atomic_relaxed_load_uint32
static uint32_t ABTD_atomic_relaxed_load_uint32(const ABTD_atomic_uint32 *ptr)
Definition: abtd_atomic.h:804
ABTI_xstream::p_main_sched
ABTI_sched * p_main_sched
Definition: abti.h:248
ABTI_pool::p_remove
ABT_pool_remove_fn p_remove
Definition: abti.h:322
ABTI_thread_mig_data::p_migration_cb_arg
void * p_migration_cb_arg
Definition: abti.h:374
ABT_ERR_INV_THREAD_ATTR
#define ABT_ERR_INV_THREAD_ATTR
Error code: invalid ULT attribute.
Definition: abt.h:180
ABTI_thread_attr_init
static void ABTI_thread_attr_init(ABTI_thread_attr *p_attr, void *p_stack, size_t stacksize, ABTI_thread_type thread_type, ABT_bool migratable)
Definition: abti_thread_attr.h:42
ABTI_sched_get_migration_pool
ABTU_ret_err int ABTI_sched_get_migration_pool(ABTI_sched *, ABTI_pool *, ABTI_pool **)
Definition: sched.c:892
ABTI_thread_attr::p_cb_arg
void * p_cb_arg
Definition: abti.h:368
thread_root_func
static void thread_root_func(void *arg)
Definition: thread.c:2786
ABTI_xstream_run_unit
void ABTI_xstream_run_unit(ABTI_xstream **pp_local_xstream, ABT_unit unit, ABTI_pool *p_pool)
Definition: stream.c:1491
ABTI_spinlock_release
static void ABTI_spinlock_release(ABTI_spinlock *p_lock)
Definition: abti_spinlock.h:42
ABTI_spinlock_acquire
static void ABTI_spinlock_acquire(ABTI_spinlock *p_lock)
Definition: abti_spinlock.h:28
ABT_unit
struct ABT_unit_opaque * ABT_unit
Work unit handle type for scheduling.
Definition: abt.h:856
thread_join
static void thread_join(ABTI_local **pp_local, ABTI_thread *p_thread)
Definition: thread.c:2697
ABTI_ythread::ctx
ABTD_ythread_context ctx
Definition: abti.h:381
ABTD_ythread_context_invalidate
static void ABTD_ythread_context_invalidate(ABTD_ythread_context *p_newctx)
Definition: abtd_ythread.h:34
ABT_thread_is_unnamed
int ABT_thread_is_unnamed(ABT_thread thread, ABT_bool *is_unnamed)
Check if a work unit is unnamed.
Definition: thread.c:1779
ABTI_ASSERT
#define ABTI_ASSERT(cond)
Definition: abti_error.h:12
thread_free
static void thread_free(ABTI_local *p_local, ABTI_thread *p_thread, ABT_bool free_unit)
Definition: thread.c:2631
ABTI_tool_event_ythread_yield
#define ABTI_tool_event_ythread_yield(p_local_xstream, p_ythread, p_parent, sync_event_type, p_sync)
Definition: abti_tool.h:312
ABTU_calloc
static ABTU_ret_err int ABTU_calloc(size_t num, size_t size, void **p_ptr)
Definition: abtu.h:227
ABT_ERR_MIGRATION_TARGET
#define ABT_ERR_MIGRATION_TARGET
Error code: an error related to a migration target.
Definition: abt.h:359
ABTI_sched::pools
ABT_pool * pools
Definition: abti.h:271
ABTI_mem_alloc_ythread_mempool_desc
static ABTU_ret_err int ABTI_mem_alloc_ythread_mempool_desc(ABTI_local *p_local, ABTI_thread_attr *p_attr, ABTI_ythread **pp_ythread)
Definition: abti_mem.h:219
ABT_THREAD_ATTR_NULL
#define ABT_THREAD_ATTR_NULL
Definition: abt.h:1050
ABTI_tool_event_thread_run
#define ABTI_tool_event_thread_run(p_local_xstream, p_thread, p_prev, p_parent)
Definition: abti_tool.h:288
ABTI_local_get_local
static ABTI_local * ABTI_local_get_local(void)
Definition: abti_local.h:41
ABTI_xstream_get_main_pool
static ABTI_pool * ABTI_xstream_get_main_pool(ABTI_xstream *p_xstream)
Definition: abti_stream.h:42
ABTI_ktable_set
static ABTU_ret_err int ABTI_ktable_set(ABTI_local *p_local, ABTD_atomic_ptr *pp_ktable, ABTI_key *p_key, void *value)
Definition: abti_key.h:224
ABTI_xstream::state
ABTD_atomic_int state
Definition: abti.h:247
ABTI_CHECK_NULL_YTHREAD_PTR
#define ABTI_CHECK_NULL_YTHREAD_PTR(p)
Definition: abti_error.h:211
ABTI_global::num_xstreams
int num_xstreams
Definition: abti.h:179
ABTI_pool::u_free
ABT_unit_free_fn u_free
Definition: abti.h:313
ABT_thread_create_on_xstream
int ABT_thread_create_on_xstream(ABT_xstream xstream, void(*thread_func)(void *), void *arg, ABT_thread_attr attr, ABT_thread *newthread)
Create a new ULT associated with an execution stream.
Definition: thread.c:164
thread_key_destructor_stackable_sched
static void thread_key_destructor_stackable_sched(void *p_value)
Definition: thread.c:2657
ABTI_global::p_primary_ythread
ABTI_ythread * p_primary_ythread
Definition: abti.h:194
ABT_thread_set_arg
int ABT_thread_set_arg(ABT_thread thread, void *arg)
Set an argument for a work unit function of a work unit.
Definition: thread.c:1936
ABT_SUCCESS
#define ABT_SUCCESS
Error code: the routine returns successfully.
Definition: abt.h:90
ABTI_tool_event_thread_join
#define ABTI_tool_event_thread_join(p_local, p_thread, p_caller)
Definition: abti_tool.h:266
ABTI_xstream::p_root_pool
ABTI_pool * p_root_pool
Definition: abti.h:254
ABTI_local_get_local_uninlined
static ABTI_local * ABTI_local_get_local_uninlined(void)
Definition: abti_local.h:51
thread_get_new_id
static ABT_unit_id thread_get_new_id(void)
Definition: thread.c:2860
ABTU_ret_err
#define ABTU_ret_err
Definition: abtu.h:138
ABTI_thread_attr::stacksize
size_t stacksize
Definition: abti.h:363
ABT_thread_get_last_xstream
int ABT_thread_get_last_xstream(ABT_thread thread, ABT_xstream *xstream)
Get an execution stream associated with a work unit.
Definition: thread.c:781
ABTI_ythread_get_handle
static ABT_thread ABTI_ythread_get_handle(ABTI_ythread *p_thread)
ABTI_SETUP_LOCAL_YTHREAD
#define ABTI_SETUP_LOCAL_YTHREAD(pp_local_xstream, pp_ythread)
Definition: abti_error.h:83
ABTI_global::p_xstream_head
ABTI_xstream * p_xstream_head
Definition: abti.h:180
ABTD_atomic_acquire_load_int
static int ABTD_atomic_acquire_load_int(const ABTD_atomic_int *ptr)
Definition: abtd_atomic.h:878
ABTI_ythread_set_blocked
void ABTI_ythread_set_blocked(ABTI_ythread *p_ythread)
Definition: ythread.c:23
ABTI_THREAD_REQ_CANCEL
#define ABTI_THREAD_REQ_CANCEL
Definition: abti.h:43
ABT_thread_migrate
int ABT_thread_migrate(ABT_thread thread)
Request a migration of a work unit to any available execution streams.
Definition: thread.c:1471
ABTI_local_get_xstream_or_null
static ABTI_xstream * ABTI_local_get_xstream_or_null(ABTI_local *p_local)
Definition: abti_local.h:77
ABT_thread_self_id
int ABT_thread_self_id(ABT_unit_id *id)
Get ID of the calling work unit.
Definition: thread.c:739
ABTI_global::xstream_list_lock
ABTI_spinlock xstream_list_lock
Definition: abti.h:182
ABTI_IS_EXT_THREAD_ENABLED
#define ABTI_IS_EXT_THREAD_ENABLED
Definition: abti.h:28
ABTI_thread_attr_dup
ABTU_ret_err int ABTI_thread_attr_dup(const ABTI_thread_attr *p_attr, ABTI_thread_attr **pp_dup_attr) ABTU_ret_err
Definition: thread_attr.c:403
ABT_thread_self
int ABT_thread_self(ABT_thread *thread)
Get the calling work unit.
Definition: thread.c:694
ABTI_sched::run
ABT_sched_run_fn run
Definition: abti.h:278
ABTI_xstream_get_local
static ABTI_local * ABTI_xstream_get_local(ABTI_xstream *p_xstream)
Definition: abti_stream.h:67
ABTI_thread_type
uint32_t ABTI_thread_type
Definition: abti.h:120
ABT_thread_free_many
int ABT_thread_free_many(int num_threads, ABT_thread *thread_list)
Free a set of work units.
Definition: thread.c:462
ABTU_unlikely
#define ABTU_unlikely(cond)
Definition: abtu.h:109
ABT_TRUE
#define ABT_TRUE
True constant for ABT_bool.
Definition: abt.h:735
ABTI_pool_get_ptr
static ABTI_pool * ABTI_pool_get_ptr(ABT_pool pool)
Definition: abti_pool.h:11
ABTI_sched::request
ABTD_atomic_uint32 request
Definition: abti.h:270
ABTI_pool_pop
static ABT_unit ABTI_pool_pop(ABTI_pool *p_pool)
Definition: abti_pool.h:96
ABT_XSTREAM_STATE_RUNNING
@ ABT_XSTREAM_STATE_RUNNING
Definition: abt.h:398
ABTI_ktable
Definition: abti.h:399
ABTI_sched_free
void ABTI_sched_free(ABTI_local *p_local, ABTI_sched *p_sched, ABT_bool force_free)
Definition: sched.c:837
ABT_thread_set_callback
int ABT_thread_set_callback(ABT_thread thread, void(*cb_func)(ABT_thread thread, void *cb_arg), void *cb_arg)
Set a callback function in a work unit.
Definition: thread.c:1585
ABTI_sched
Definition: abti.h:265
ABT_ERR_MIGRATION_NA
#define ABT_ERR_MIGRATION_NA
Error code: migration is not supported.
Definition: abt.h:368
ABTI_KTABLE_LOCKED
#define ABTI_KTABLE_LOCKED
Definition: abti_key.h:59
ABTI_tool_event_thread_free
#define ABTI_tool_event_thread_free(p_local, p_thread, p_caller)
Definition: abti_tool.h:273
ABT_SYNC_EVENT_TYPE_THREAD_JOIN
@ ABT_SYNC_EVENT_TYPE_THREAD_JOIN
Definition: abt.h:657
ABTI_xstream::p_root_ythread
ABTI_ythread * p_root_ythread
Definition: abti.h:253
ABT_FALSE
#define ABT_FALSE
False constant for ABT_bool.
Definition: abt.h:737
ABTI_ythread
Definition: abti.h:379
ABTI_thread_free
void ABTI_thread_free(ABTI_local *p_local, ABTI_thread *p_thread)
Definition: thread.c:2282
ABTI_ythread_set_ready
void ABTI_ythread_set_ready(ABTI_local *p_local, ABTI_ythread *p_ythread)
Definition: ythread.c:65
ABT_thread_is_migratable
int ABT_thread_is_migratable(ABT_thread thread, ABT_bool *is_migratable)
Get the migratability of a work unit.
Definition: thread.c:1700
ABTI_THREAD_TYPE_MAIN_SCHED
#define ABTI_THREAD_TYPE_MAIN_SCHED
Definition: abti.h:79
ABTI_ythread_suspend
void ABTI_ythread_suspend(ABTI_xstream **pp_local_xstream, ABTI_ythread *p_ythread, ABT_sync_event_type sync_event_type, void *p_sync)
Definition: ythread.c:45
ABTD_ythread_context_create
static void ABTD_ythread_context_create(ABTD_ythread_context *p_link, size_t stacksize, void *p_stack, ABTD_ythread_context *p_newctx)
Definition: abtd_ythread.h:20
ABTI_CHECK_NULL_POOL_PTR
#define ABTI_CHECK_NULL_POOL_PTR(p)
Definition: abti_error.h:175
ABTD_atomic_fetch_add_uint64
static uint64_t ABTD_atomic_fetch_add_uint64(ABTD_atomic_uint64 *ptr, uint64_t v)
Definition: abtd_atomic.h:477
ABTI_CHECK_NULL_XSTREAM_PTR
#define ABTI_CHECK_NULL_XSTREAM_PTR(p)
Definition: abti_error.h:166
ABT_thread_create
int ABT_thread_create(ABT_pool pool, void(*thread_func)(void *), void *arg, ABT_thread_attr attr, ABT_thread *newthread)
Create a new ULT.
Definition: thread.c:86
ABTU_free
static void ABTU_free(void *ptr)
Definition: abtu.h:211
ABTI_thread::p_parent
ABTI_thread * p_parent
Definition: abti.h:351
ABTD_atomic_fetch_or_uint32
static uint32_t ABTD_atomic_fetch_or_uint32(ABTD_atomic_uint32 *ptr, uint32_t v)
Definition: abtd_atomic.h:631
ABTI_THREAD_TYPE_NAMED
#define ABTI_THREAD_TYPE_NAMED
Definition: abti.h:81
ABTI_xstream_get_ptr
static ABTI_xstream * ABTI_xstream_get_ptr(ABT_xstream xstream)
Definition: abti_stream.h:11
ABTI_thread::p_last_xstream
ABTI_xstream * p_last_xstream
Definition: abti.h:350
ABTI_thread_attr::p_stack
void * p_stack
Definition: abti.h:362
ABTI_ythread::p_stack
void * p_stack
Definition: abti.h:382
ABTI_thread::p_keytable
ABTD_atomic_ptr p_keytable
Definition: abti.h:357
ABTI_ythread_create_primary
ABTU_ret_err int ABTI_ythread_create_primary(ABTI_local *p_local, ABTI_xstream *p_xstream, ABTI_ythread **p_ythread)
Definition: thread.c:2186
ABTI_ythread::thread
ABTI_thread thread
Definition: abti.h:380
ABTI_pool_inc_num_blocked
static void ABTI_pool_inc_num_blocked(ABTI_pool *p_pool)
Definition: abti_pool.h:42
ABTI_thread_attr::thread_type
ABTI_thread_type thread_type
Definition: abti.h:364
ABTI_local
struct ABTI_local ABTI_local
Definition: abti.h:104
thread_join_busywait
static void thread_join_busywait(ABTI_thread *p_thread)
Definition: thread.c:2675
ABTI_thread_attr::f_cb
void(* f_cb)(ABT_thread, void *)
Definition: abti.h:367
ABTI_ythread_yield
static void ABTI_ythread_yield(ABTI_xstream **pp_local_xstream, ABTI_ythread *p_ythread, ABT_sync_event_type sync_event_type, void *p_sync)
Definition: abti_ythread.h:365
ABTD_ythread_finish_context
static ABTU_noreturn void ABTD_ythread_finish_context(ABTD_ythread_context *p_old, ABTD_ythread_context *p_new)
Definition: abtd_ythread.h:80
ABTD_atomic_acquire_load_ptr
static void * ABTD_atomic_acquire_load_ptr(const ABTD_atomic_ptr *ptr)
Definition: abtd_atomic.h:979
ABTI_KEY_ID_MIGRATION
#define ABTI_KEY_ID_MIGRATION
Definition: abti_key.h:48
ABT_thread_yield_to
int ABT_thread_yield_to(ABT_thread thread)
Yield the calling ULT to the specific ULT.
Definition: thread.c:997
g_thread_mig_data_key
static ABTI_key g_thread_mig_data_key
Definition: thread.c:30
ABT_thread_get_last_pool_id
int ABT_thread_get_last_pool_id(ABT_thread thread, int *id)
Get the last pool's ID of a work unit.
Definition: thread.c:902
ABTI_pool::id
uint64_t id
Definition: abti.h:307
ABTI_CHECK_TRUE
#define ABTI_CHECK_TRUE(cond, abt_errno)
Definition: abti_error.h:137
ABT_thread_revive
int ABT_thread_revive(ABT_pool pool, void(*thread_func)(void *), void *arg, ABT_thread *thread)
Revive a terminated work unit.
Definition: thread.c:345
ABTI_CHECK_NULL_KEY_PTR
#define ABTI_CHECK_NULL_KEY_PTR(p)
Definition: abti_error.h:238
ABTI_mem_alloc_ythread_malloc_desc_stack
static ABTU_ret_err int ABTI_mem_alloc_ythread_malloc_desc_stack(ABTI_thread_attr *p_attr, ABTI_ythread **pp_ythread)
Definition: abti_mem.h:199
ABTI_global
Definition: abti.h:177
ABT_thread_equal
int ABT_thread_equal(ABT_thread thread1, ABT_thread thread2, ABT_bool *result)
Compare two work unit handles for equality.
Definition: thread.c:1826
ABT_ERR_FEATURE_NA
#define ABT_ERR_FEATURE_NA
Error code: unsupported feature.
Definition: abt.h:380
ABTI_thread::f_thread
void(* f_thread)(void *)
Definition: abti.h:352
ABT_THREAD_STATE_RUNNING
@ ABT_THREAD_STATE_RUNNING
Definition: abt.h:411
thread_join_yield_thread
static void thread_join_yield_thread(ABTI_xstream **pp_local_xstream, ABTI_ythread *p_self, ABTI_thread *p_thread)
Definition: thread.c:2684
ABTD_atomic_relaxed_store_ptr
static void ABTD_atomic_relaxed_store_ptr(ABTD_atomic_ptr *ptr, void *val)
Definition: abtd_atomic.h:1055
ABT_thread_get_specific
int ABT_thread_get_specific(ABT_thread thread, ABT_key key, void **value)
Get a value associated with a work-unit-specific key in a work unit.
Definition: thread.c:2050
ABTI_thread::p_pool
ABTI_pool * p_pool
Definition: abti.h:356
ABT_UNIT_NULL
#define ABT_UNIT_NULL
Definition: abt.h:1048
ABT_thread_migrate_to_pool
int ABT_thread_migrate_to_pool(ABT_thread thread, ABT_pool pool)
Request a migration of a work unit to a specific pool.
Definition: thread.c:1396
ABTD_atomic_release_store_uint32
static void ABTD_atomic_release_store_uint32(ABTD_atomic_uint32 *ptr, uint32_t val)
Definition: abtd_atomic.h:1100
ABTI_local_get_xstream
static ABTI_xstream * ABTI_local_get_xstream(ABTI_local *p_local)
Definition: abti_local.h:86
ABTI_thread_revive
void ABTI_thread_revive(ABTI_local *p_local, ABTI_pool *p_pool, void(*thread_func)(void *), void *arg, ABTI_thread *p_thread)
Definition: thread.c:2138
ABTD_atomic_release_store_int
static void ABTD_atomic_release_store_int(ABTD_atomic_int *ptr, int val)
Definition: abtd_atomic.h:1065
ABTI_thread_get_id
ABT_unit_id ABTI_thread_get_id(ABTI_thread *p_thread)
Definition: thread.c:2439
ABT_thread_cancel
int ABT_thread_cancel(ABT_thread thread)
Send a termination request to a work unit.
Definition: thread.c:646
ABTI_thread::id
ABT_unit_id id
Definition: abti.h:358
ABTI_SCHED_REQ_FINISH
#define ABTI_SCHED_REQ_FINISH
Definition: abti.h:38
ABTI_thread_get_ptr
static ABTI_thread * ABTI_thread_get_ptr(ABT_thread thread)
Definition: abti_thread.h:9
ABTI_pool_get_handle
static ABT_pool ABTI_pool_get_handle(ABTI_pool *p_pool)
Definition: abti_pool.h:26
ABT_XSTREAM_STATE_TERMINATED
@ ABT_XSTREAM_STATE_TERMINATED
Definition: abt.h:400
ABTI_ktable_set_unsafe
static ABTU_ret_err int ABTI_ktable_set_unsafe(ABTI_local *p_local, ABTI_ktable **pp_ktable, ABTI_key *p_key, void *value)
Definition: abti_key.h:265
ABTI_THREAD_TYPE_MEM_MALLOC_DESC_STACK
#define ABTI_THREAD_TYPE_MEM_MALLOC_DESC_STACK
Definition: abti.h:87
ABTI_sched_get_effective_size
size_t ABTI_sched_get_effective_size(ABTI_local *p_local, ABTI_sched *p_sched)
Definition: sched.c:926
ABTI_pool_dec_num_blocked
static void ABTI_pool_dec_num_blocked(ABTI_pool *p_pool)
Definition: abti_pool.h:48
ABTI_THREAD_TYPE_MEM_MALLOC_DESC
#define ABTI_THREAD_TYPE_MEM_MALLOC_DESC
Definition: abti.h:85
ABTI_thread_set_request
static void ABTI_thread_set_request(ABTI_thread *p_thread, uint32_t req)
Definition: abti_thread.h:68
ABT_thread_get_attr
int ABT_thread_get_attr(ABT_thread thread, ABT_thread_attr *attr)
Get attributes of a work unit.
Definition: thread.c:2094
ABTI_THREAD_REQ_JOIN
#define ABTI_THREAD_REQ_JOIN
Definition: abti.h:41