ARGOBOTS  1.1
sched.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 sched_create(ABT_sched_def *def, int num_pools,
9  ABT_pool *pools,
10  ABTI_sched_config *p_config,
11  ABT_bool def_automatic,
12  ABTI_sched **pp_newsched);
13 static inline ABTI_sched_kind sched_get_kind(ABT_sched_def *def);
14 #ifdef ABT_CONFIG_USE_DEBUG_LOG
15 static inline uint64_t sched_get_new_id(void);
16 #endif
17 
91 int ABT_sched_create(ABT_sched_def *def, int num_pools, ABT_pool *pools,
92  ABT_sched_config config, ABT_sched *newsched)
93 {
94  ABTI_sched *p_sched;
95 #ifndef ABT_CONFIG_ENABLE_VER_20_API
96  *newsched = ABT_SCHED_NULL;
97  ABTI_CHECK_TRUE(newsched != NULL, ABT_ERR_SCHED);
98 #endif
99  ABTI_CHECK_TRUE(num_pools >= 0, ABT_ERR_INV_ARG);
100 
101  /* The default automatic is different from ABT_sched_create_basic(). */
102  const ABT_bool def_automatic = ABT_FALSE;
103  ABTI_sched_config *p_config = ABTI_sched_config_get_ptr(config);
104  int abt_errno =
105  sched_create(def, num_pools, pools, p_config, def_automatic, &p_sched);
106  ABTI_CHECK_ERROR(abt_errno);
107 
108  /* Return value */
109  *newsched = ABTI_sched_get_handle(p_sched);
110  return ABT_SUCCESS;
111 }
112 
174 int ABT_sched_create_basic(ABT_sched_predef predef, int num_pools,
175  ABT_pool *pools, ABT_sched_config config,
176  ABT_sched *newsched)
177 {
178 #ifndef ABT_CONFIG_ENABLE_VER_20_API
179  *newsched = ABT_SCHED_NULL;
180  ABTI_CHECK_TRUE(newsched != NULL, ABT_ERR_SCHED);
181 #endif
182  ABTI_CHECK_TRUE(num_pools >= 0, ABT_ERR_INV_ARG);
183 
184  ABTI_sched *p_newsched;
185  ABTI_sched_config *p_config = ABTI_sched_config_get_ptr(config);
186  int abt_errno = ABTI_sched_create_basic(predef, num_pools, pools, p_config,
187  &p_newsched);
188  ABTI_CHECK_ERROR(abt_errno);
189  *newsched = ABTI_sched_get_handle(p_newsched);
190  return ABT_SUCCESS;
191 }
192 
235 {
236  ABTI_global *p_global;
237  ABTI_SETUP_GLOBAL(&p_global);
238  ABTI_local *p_local = ABTI_local_get_local();
239  ABTI_sched *p_sched = ABTI_sched_get_ptr(*sched);
240  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
241 #ifndef ABT_CONFIG_ENABLE_VER_20_API
243 #endif
244 
245  /* Free the scheduler */
246  ABTI_sched_free(p_global, p_local, p_sched, ABT_FALSE);
247 
248  /* Return value */
249  *sched = ABT_SCHED_NULL;
250  return ABT_SUCCESS;
251 }
252 
275 int ABT_sched_get_num_pools(ABT_sched sched, int *num_pools)
276 {
277  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
278  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
279 
280  *num_pools = p_sched->num_pools;
281  return ABT_SUCCESS;
282 }
283 
320 int ABT_sched_get_pools(ABT_sched sched, int max_pools, int idx,
321  ABT_pool *pools)
322 {
323  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
324  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
325  ABTI_CHECK_TRUE(max_pools >= 0, ABT_ERR_INV_ARG);
326  ABTI_CHECK_TRUE(idx >= 0, ABT_ERR_INV_ARG);
327 #ifndef ABT_CONFIG_ENABLE_VER_20_API
328  ABTI_CHECK_TRUE((size_t)(idx + max_pools) <= p_sched->num_pools,
329  ABT_ERR_SCHED);
330 #endif
331 
332  size_t p;
333  for (p = idx; p < (size_t)idx + max_pools; p++) {
334  if (p >= p_sched->num_pools) {
335  /* Out of range. */
336  break;
337  }
338  pools[p - idx] = p_sched->pools[p];
339  }
340  return ABT_SUCCESS;
341 }
342 
374 {
375  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
376  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
377 
378  ABTI_sched_finish(p_sched);
379  return ABT_SUCCESS;
380 }
381 
411 {
412  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
413  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
414 
415  ABTI_sched_exit(p_sched);
416  return ABT_SUCCESS;
417 }
418 
457 {
458 #ifndef ABT_CONFIG_ENABLE_VER_20_API
459  *stop = ABT_FALSE;
460 #endif
461  ABTI_local *p_local = ABTI_local_get_local();
462  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
463  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
464 #ifndef ABT_CONFIG_ENABLE_VER_20_API
466 #endif
467 
468  *stop = ABTI_sched_has_to_stop(&p_local, p_sched);
469  return ABT_SUCCESS;
470 }
471 
495 {
496  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
497  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
498 
499  p_sched->data = data;
500  return ABT_SUCCESS;
501 }
502 
527 {
528  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
529  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
530 
531  *data = p_sched->data;
532  return ABT_SUCCESS;
533 }
568 int ABT_sched_get_size(ABT_sched sched, size_t *size)
569 {
570 #ifndef ABT_CONFIG_ENABLE_VER_20_API
571  *size = 0;
572 #endif
573 
574  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
575  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
576 
577  *size = ABTI_sched_get_size(p_sched);
578  return ABT_SUCCESS;
579 }
580 
616 int ABT_sched_get_total_size(ABT_sched sched, size_t *size)
617 {
618 #ifndef ABT_CONFIG_ENABLE_VER_20_API
619  *size = 0;
620 #endif
621 
622  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
623  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
624 
625  *size = ABTI_sched_get_total_size(p_sched);
626  return ABT_SUCCESS;
627 }
628 
629 /*****************************************************************************/
630 /* Private APIs */
631 /*****************************************************************************/
632 
634 {
635  size_t pool_size = 0, p;
636 
637  for (p = 0; p < p_sched->num_pools; p++) {
638  ABTI_pool *p_pool = ABTI_pool_get_ptr(p_sched->pools[p]);
639  pool_size += ABTI_pool_get_size(p_pool);
640  }
641 
642  return pool_size;
643 }
644 
646 {
648 }
649 
651 {
653 }
654 
656  ABT_pool *pools,
657  ABTI_sched_config *p_config,
658  ABTI_sched **pp_newsched)
659 {
660  int abt_errno;
662  /* The default value is different from ABT_sched_create. */
663  const ABT_bool def_automatic = ABT_TRUE;
664  /* Always use MPMC pools */
665  const ABT_pool_access def_access = ABT_POOL_ACCESS_MPMC;
666 
667  /* A pool array is provided, predef has to be compatible */
668  if (pools != NULL) {
669  /* Copy of the contents of pools */
670  ABT_pool *pool_list;
671  if (num_pools > 0) {
672  abt_errno =
673  ABTU_malloc(num_pools * sizeof(ABT_pool), (void **)&pool_list);
674  ABTI_CHECK_ERROR(abt_errno);
675 
676  int p;
677  for (p = 0; p < num_pools; p++) {
678  if (pools[p] == ABT_POOL_NULL) {
679  ABTI_pool *p_newpool;
680  abt_errno =
682  ABT_TRUE, &p_newpool);
684  abt_errno != ABT_SUCCESS) {
685  /* Remove pools that are already created. */
686  int i;
687  for (i = 0; i < p; i++) {
688  if (pools[i] != ABT_POOL_NULL)
689  continue; /* User given pool. */
690  /* Free a pool created in this function. */
691  ABTI_pool_free(ABTI_pool_get_ptr(pool_list[i]));
692  }
693  ABTU_free(pool_list);
694  ABTI_HANDLE_ERROR(abt_errno);
695  }
696  pool_list[p] = ABTI_pool_get_handle(p_newpool);
697  } else {
698  pool_list[p] = pools[p];
699  }
700  }
701  } else {
702  /* TODO: Check if it works. */
703  pool_list = NULL;
704  }
705 
706  /* Creation of the scheduler */
707  switch (predef) {
708  case ABT_SCHED_DEFAULT:
709  case ABT_SCHED_BASIC:
710  abt_errno = sched_create(ABTI_sched_get_basic_def(), num_pools,
711  pool_list, p_config, def_automatic,
712  pp_newsched);
713  break;
716  num_pools, pool_list, p_config,
717  def_automatic, pp_newsched);
718  break;
719  case ABT_SCHED_PRIO:
720  abt_errno = sched_create(ABTI_sched_get_prio_def(), num_pools,
721  pool_list, p_config, def_automatic,
722  pp_newsched);
723  break;
724  case ABT_SCHED_RANDWS:
725  abt_errno = sched_create(ABTI_sched_get_randws_def(), num_pools,
726  pool_list, p_config, def_automatic,
727  pp_newsched);
728  break;
729  default:
730  abt_errno = ABT_ERR_INV_SCHED_PREDEF;
731  break;
732  }
733  if (ABTI_IS_ERROR_CHECK_ENABLED && abt_errno != ABT_SUCCESS) {
734  /* Remove pools that are already created. */
735  int i;
736  for (i = 0; i < num_pools; i++) {
737  if (pools[i] != ABT_POOL_NULL)
738  continue; /* User given pool. */
739  /* Free a pool created in this function. */
740  ABTI_pool_free(ABTI_pool_get_ptr(pool_list[i]));
741  }
742  ABTU_free(pool_list);
743  ABTI_HANDLE_ERROR(abt_errno);
744  }
745  ABTU_free(pool_list);
746  } else { /* No pool array is provided, predef has to be compatible */
747  /* Set the number of pools */
748  switch (predef) {
749  case ABT_SCHED_DEFAULT:
750  case ABT_SCHED_BASIC:
751  num_pools = 1;
752  break;
754  /* FIFO_WAIT is default pool for use with BASIC_WAIT sched */
755  kind = ABT_POOL_FIFO_WAIT;
756  num_pools = 1;
757  break;
758  case ABT_SCHED_PRIO:
759  num_pools = ABTI_SCHED_NUM_PRIO;
760  break;
761  case ABT_SCHED_RANDWS:
762  num_pools = 1;
763  break;
764  default:
765  abt_errno = ABT_ERR_INV_SCHED_PREDEF;
766  ABTI_CHECK_ERROR(abt_errno);
767  break;
768  }
769 
770  /* Creation of the pools */
771  /* To avoid the malloc overhead, we use a stack array. */
772  ABT_pool pool_list[ABTI_SCHED_NUM_PRIO];
773  int p;
774  /* ICC 19 warns an unused variable in the following error path. To
775  * suppress the warning, let's initialize the array member here. */
776  for (p = 0; p < num_pools; p++)
777  pool_list[p] = ABT_POOL_NULL;
778  for (p = 0; p < num_pools; p++) {
779  ABTI_pool *p_newpool;
780  abt_errno =
781  ABTI_pool_create_basic(kind, def_access, ABT_TRUE, &p_newpool);
782  if (ABTI_IS_ERROR_CHECK_ENABLED && abt_errno != ABT_SUCCESS) {
783  /* Remove pools that are already created. */
784  int i;
785  for (i = 0; i < p; i++) {
786  /* Free a pool created in this function. */
787  ABTI_pool_free(ABTI_pool_get_ptr(pool_list[i]));
788  }
789  ABTI_HANDLE_ERROR(abt_errno);
790  }
791  pool_list[p] = ABTI_pool_get_handle(p_newpool);
792  }
793 
794  /* Creation of the scheduler */
795  switch (predef) {
796  case ABT_SCHED_DEFAULT:
797  case ABT_SCHED_BASIC:
798  abt_errno = sched_create(ABTI_sched_get_basic_def(), num_pools,
799  pool_list, p_config, def_automatic,
800  pp_newsched);
801  break;
804  num_pools, pool_list, p_config,
805  def_automatic, pp_newsched);
806  break;
807  case ABT_SCHED_PRIO:
808  abt_errno = sched_create(ABTI_sched_get_prio_def(), num_pools,
809  pool_list, p_config, def_automatic,
810  pp_newsched);
811  break;
812  case ABT_SCHED_RANDWS:
813  abt_errno = sched_create(ABTI_sched_get_randws_def(), num_pools,
814  pool_list, p_config, def_automatic,
815  pp_newsched);
816  break;
817  default:
818  abt_errno = ABT_ERR_INV_SCHED_PREDEF;
819  break;
820  }
821  if (ABTI_IS_ERROR_CHECK_ENABLED && abt_errno != ABT_SUCCESS) {
822  /* Remove pools that are already created. */
823  int i;
824  for (i = 0; i < num_pools; i++) {
825  /* Free a pool created in this function. */
826  ABTI_pool_free(ABTI_pool_get_ptr(pool_list[i]));
827  }
828  ABTI_HANDLE_ERROR(abt_errno);
829  }
830  }
831  return ABT_SUCCESS;
832 }
833 
834 void ABTI_sched_free(ABTI_global *p_global, ABTI_local *p_local,
835  ABTI_sched *p_sched, ABT_bool force_free)
836 {
837  ABTI_ASSERT(p_sched->used == ABTI_SCHED_NOT_USED);
838  /* Free the scheduler first. */
839  if (p_sched->free) {
840  p_sched->free(ABTI_sched_get_handle(p_sched));
841  }
842  /* If sched is a default provided one, it should free its pool here.
843  * Otherwise, freeing the pool is the user's responsibility. */
844  size_t p;
845  for (p = 0; p < p_sched->num_pools; p++) {
846  ABTI_pool *p_pool = ABTI_pool_get_ptr(p_sched->pools[p]);
847  if (!p_pool) {
848  /* p_pool can be set to NULL when that p_pool must be preserved,
849  * for example, when this function is called because
850  * ABT_xstream_create_basic() fails. */
851  continue;
852  }
853  int32_t num_scheds = ABTI_pool_release(p_pool);
854  if ((p_pool->automatic == ABT_TRUE && num_scheds == 0) || force_free) {
855  ABTI_pool_free(p_pool);
856  }
857  }
858  ABTU_free(p_sched->pools);
859 
860  /* Free the associated work unit */
861  if (p_sched->p_ythread) {
862  ABTI_thread_free(p_global, p_local, &p_sched->p_ythread->thread);
863  }
864 
865  LOG_DEBUG("[S%" PRIu64 "] freed\n", p_sched->id);
866  p_sched->data = NULL;
867 
868  ABTU_free(p_sched);
869 }
870 
872 {
873  /* Check exit request */
876  return ABT_TRUE;
877  }
878 
879  if (ABTI_sched_get_effective_size(*pp_local, p_sched) == 0) {
882  /* Check join request */
883  if (ABTI_sched_get_effective_size(*pp_local, p_sched) == 0)
884  return ABT_TRUE;
885  } else if (p_sched->used == ABTI_SCHED_IN_POOL) {
886  /* Let's finish it anyway.
887  * TODO: think about the condition. */
888  return ABT_TRUE;
889  }
890  }
891  return ABT_FALSE;
892 }
893 
894 /* Get the pool suitable for receiving a migrating thread */
896  ABTI_pool *source_pool,
897  ABTI_pool **pp_pool)
898 {
899  /* Find a pool. If get_migr_pool is not defined, we pick the first pool */
900  if (p_sched->get_migr_pool == NULL) {
902  *pp_pool = ABTI_pool_get_ptr(p_sched->pools[0]);
903  } else {
904  ABT_sched sched = ABTI_sched_get_handle(p_sched);
905  ABTI_pool *p_pool = ABTI_pool_get_ptr(p_sched->get_migr_pool(sched));
907  *pp_pool = p_pool;
908  }
909  return ABT_SUCCESS;
910 }
911 
913 {
914  size_t pool_size = 0, p;
915 
916  for (p = 0; p < p_sched->num_pools; p++) {
917  ABTI_pool *p_pool = ABTI_pool_get_ptr(p_sched->pools[p]);
918  pool_size += ABTI_pool_get_total_size(p_pool);
919  }
920 
921  return pool_size;
922 }
923 
924 /* Compared to \c ABTI_sched_get_total_size, ABTI_sched_get_effective_size does
925  * not count the number of blocked ULTs if a pool has more than one consumer or
926  * the caller ES is not the latest consumer. This is necessary when the ES
927  * associated with the target scheduler has to be joined and the pool is shared
928  * between different schedulers associated with different ESs. */
930 {
931  size_t pool_size = 0, p;
932 
933  for (p = 0; p < p_sched->num_pools; p++) {
934  ABT_pool pool = p_sched->pools[p];
935  ABTI_pool *p_pool = ABTI_pool_get_ptr(pool);
936  pool_size += ABTI_pool_get_size(p_pool);
937  switch (p_pool->access) {
939  pool_size +=
941  break;
946  if (ABTD_atomic_acquire_load_int32(&p_pool->num_scheds) == 1) {
947  pool_size +=
949  }
950  break;
951  default:
952  break;
953  }
954  }
955 
956  return pool_size;
957 }
958 
959 void ABTI_sched_print(ABTI_sched *p_sched, FILE *p_os, int indent,
960  ABT_bool print_sub)
961 {
962  if (p_sched == NULL) {
963  fprintf(p_os, "%*s== NULL SCHED ==\n", indent, "");
964  } else {
965  ABTI_sched_kind kind;
966  const char *kind_str, *used;
967 
968  kind = p_sched->kind;
969  if (kind == sched_get_kind(ABTI_sched_get_basic_def())) {
970  kind_str = "BASIC";
971  } else if (kind == sched_get_kind(ABTI_sched_get_basic_wait_def())) {
972  kind_str = "BASIC_WAIT";
973  } else if (kind == sched_get_kind(ABTI_sched_get_prio_def())) {
974  kind_str = "PRIO";
975  } else if (kind == sched_get_kind(ABTI_sched_get_randws_def())) {
976  kind_str = "RANDWS";
977  } else {
978  kind_str = "USER";
979  }
980 
981  switch (p_sched->used) {
982  case ABTI_SCHED_NOT_USED:
983  used = "NOT_USED";
984  break;
985  case ABTI_SCHED_MAIN:
986  used = "MAIN";
987  break;
988  case ABTI_SCHED_IN_POOL:
989  used = "IN_POOL";
990  break;
991  default:
992  used = "UNKNOWN";
993  break;
994  }
995 
996  fprintf(p_os,
997  "%*s== SCHED (%p) ==\n"
998 #ifdef ABT_CONFIG_USE_DEBUG_LOG
999  "%*sid : %" PRIu64 "\n"
1000 #endif
1001  "%*skind : %" PRIxPTR " (%s)\n"
1002  "%*sused : %s\n"
1003  "%*sautomatic: %s\n"
1004  "%*srequest : 0x%x\n"
1005  "%*snum_pools: %zu\n"
1006  "%*ssize : %zu\n"
1007  "%*stot_size : %zu\n"
1008  "%*sthread : %p\n"
1009  "%*sdata : %p\n",
1010  indent, "", (void *)p_sched,
1011 #ifdef ABT_CONFIG_USE_DEBUG_LOG
1012  indent, "", p_sched->id,
1013 #endif
1014  indent, "", p_sched->kind, kind_str, indent, "", used, indent,
1015  "", (p_sched->automatic == ABT_TRUE) ? "TRUE" : "FALSE", indent,
1016  "", ABTD_atomic_acquire_load_uint32(&p_sched->request), indent,
1017  "", p_sched->num_pools, indent, "",
1018  ABTI_sched_get_size(p_sched), indent, "",
1019  ABTI_sched_get_total_size(p_sched), indent, "",
1020  (void *)p_sched->p_ythread, indent, "", p_sched->data);
1021  if (print_sub == ABT_TRUE) {
1022  size_t i;
1023  for (i = 0; i < p_sched->num_pools; i++) {
1024  ABTI_pool *p_pool = ABTI_pool_get_ptr(p_sched->pools[i]);
1025  ABTI_pool_print(p_pool, p_os, indent + 2);
1026  }
1027  }
1028  }
1029  fflush(p_os);
1030 }
1031 
1034 {
1036 }
1037 
1038 /*****************************************************************************/
1039 /* Internal static functions */
1040 /*****************************************************************************/
1041 
1043 {
1044  return (ABTI_sched_kind)def;
1045 }
1046 
1047 ABTU_ret_err static int sched_create(ABT_sched_def *def, int num_pools,
1048  ABT_pool *pools,
1049  ABTI_sched_config *p_config,
1050  ABT_bool def_automatic,
1051  ABTI_sched **pp_newsched)
1052 {
1053  ABTI_sched *p_sched;
1054  int p, abt_errno;
1055 
1056  abt_errno = ABTU_malloc(sizeof(ABTI_sched), (void **)&p_sched);
1057  ABTI_CHECK_ERROR(abt_errno);
1058 
1059  /* We read the config and set the configured parameters */
1060  ABT_bool automatic = def_automatic;
1061  if (p_config) {
1062  int automatic_val = 0;
1063  abt_errno =
1065  &automatic_val);
1066  if (abt_errno == ABT_SUCCESS) {
1067  automatic = (automatic_val == 0) ? ABT_FALSE : ABT_TRUE;
1068  }
1069  }
1070 
1071  /* Copy of the contents of pools */
1072  ABT_pool *pool_list;
1073  abt_errno = ABTU_malloc(num_pools * sizeof(ABT_pool), (void **)&pool_list);
1074  if (ABTI_IS_ERROR_CHECK_ENABLED && abt_errno != ABT_SUCCESS) {
1075  ABTU_free(p_sched);
1076  return abt_errno;
1077  }
1078  for (p = 0; p < num_pools; p++) {
1079  if (pools[p] == ABT_POOL_NULL) {
1080  ABTI_pool *p_newpool;
1081  abt_errno =
1083  ABT_TRUE, &p_newpool);
1084  if (ABTI_IS_ERROR_CHECK_ENABLED && abt_errno != ABT_SUCCESS) {
1085  int i;
1086  for (i = 0; i < p; i++) {
1087  if (pools[i] == ABT_POOL_NULL)
1088  ABTI_pool_free(ABTI_pool_get_ptr(pool_list[i]));
1089  }
1090  ABTU_free(pool_list);
1091  ABTU_free(p_sched);
1092  return abt_errno;
1093  }
1094  pool_list[p] = ABTI_pool_get_handle(p_newpool);
1095  } else {
1096  pool_list[p] = pools[p];
1097  }
1098  }
1099  /* Check if the pools are available */
1100  for (p = 0; p < num_pools; p++) {
1101  ABTI_pool_retain(ABTI_pool_get_ptr(pool_list[p]));
1102  }
1103 
1104  p_sched->used = ABTI_SCHED_NOT_USED;
1105  p_sched->automatic = automatic;
1106  p_sched->kind = sched_get_kind(def);
1107  p_sched->p_replace_sched = NULL;
1108  p_sched->p_replace_waiter = NULL;
1109  ABTD_atomic_relaxed_store_uint32(&p_sched->request, 0);
1110  p_sched->pools = pool_list;
1111  p_sched->num_pools = num_pools;
1112  p_sched->type = def->type;
1113  p_sched->p_ythread = NULL;
1114  p_sched->data = NULL;
1115 
1116  p_sched->init = def->init;
1117  p_sched->run = def->run;
1118  p_sched->free = def->free;
1119  p_sched->get_migr_pool = def->get_migr_pool;
1120 
1121 #ifdef ABT_CONFIG_USE_DEBUG_LOG
1122  p_sched->id = sched_get_new_id();
1123 #endif
1124  LOG_DEBUG("[S%" PRIu64 "] created\n", p_sched->id);
1125 
1126  /* Return value */
1127  ABT_sched newsched = ABTI_sched_get_handle(p_sched);
1128 
1129  /* Specific initialization */
1130  if (p_sched->init) {
1132  abt_errno = p_sched->init(newsched, config);
1133  if (ABTI_IS_ERROR_CHECK_ENABLED && abt_errno != ABT_SUCCESS) {
1134  for (p = 0; p < num_pools; p++) {
1135  if (pools[p] == ABT_POOL_NULL) {
1136  ABTI_pool_free(ABTI_pool_get_ptr(pool_list[p]));
1137  } else {
1138  ABTI_pool_release(ABTI_pool_get_ptr(pool_list[p]));
1139  }
1140  }
1141  ABTU_free(pool_list);
1142  ABTU_free(p_sched);
1143  return abt_errno;
1144  }
1145  }
1146 
1147  *pp_newsched = p_sched;
1148 
1149  return ABT_SUCCESS;
1150 }
1151 
1152 #ifdef ABT_CONFIG_USE_DEBUG_LOG
1153 static inline uint64_t sched_get_new_id(void)
1154 {
1156 }
1157 #endif
ABTI_CHECK_NULL_SCHED_PTR
#define ABTI_CHECK_NULL_SCHED_PTR(p)
Definition: abti_error.h:177
ABTI_sched::data
void * data
Definition: abti.h:301
ABT_sched_predef
ABT_sched_predef
Predefined scheduler type.
Definition: abt.h:465
ABTI_sched_get_ptr
static ABTI_sched * ABTI_sched_get_ptr(ABT_sched sched)
Definition: abti_sched.h:11
ABTI_sched_reset_id
void ABTI_sched_reset_id(void)
Definition: sched.c:1033
ABTI_pool::num_blocked
ABTD_atomic_int32 num_blocked
Definition: abti.h:333
ABTD_atomic_relaxed_store_uint64
static void ABTD_atomic_relaxed_store_uint64(ABTD_atomic_uint64 *ptr, uint64_t val)
Definition: abtd_atomic.h:1045
ABT_sched_create_basic
int ABT_sched_create_basic(ABT_sched_predef predef, int num_pools, ABT_pool *pools, ABT_sched_config config, ABT_sched *newsched)
Create a new scheduler with a predefined scheduler type.
Definition: sched.c:174
ABT_bool
int ABT_bool
Boolean type.
Definition: abt.h:1001
ABTI_SCHED_NOT_USED
@ ABTI_SCHED_NOT_USED
Definition: abti.h:76
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
ABT_sched_def::type
ABT_sched_type type
Unused value.
Definition: abt.h:1309
ABTI_SETUP_GLOBAL
#define ABTI_SETUP_GLOBAL(pp_global)
Definition: abti_error.h:59
ABTI_sched_print
void ABTI_sched_print(ABTI_sched *p_sched, FILE *p_os, int indent, ABT_bool print_sub)
Definition: sched.c:959
ABTI_sched_create_basic
ABTU_ret_err int ABTI_sched_create_basic(ABT_sched_predef predef, int num_pools, ABT_pool *pools, ABTI_sched_config *p_config, ABTI_sched **pp_newsched)
Definition: sched.c:655
ABT_ERR_INV_XSTREAM
#define ABT_ERR_INV_XSTREAM
Error code: invalid execution stream.
Definition: abt.h:114
ABT_ERR_INV_SCHED_PREDEF
#define ABT_ERR_INV_SCHED_PREDEF
Error code: invalid predefined scheduler type.
Definition: abt.h:139
ABTI_SCHED_NUM_PRIO
#define ABTI_SCHED_NUM_PRIO
Definition: abti.h:36
ABTI_sched_free
void ABTI_sched_free(ABTI_global *p_global, ABTI_local *p_local, ABTI_sched *p_sched, ABT_bool force_free)
Definition: sched.c:834
ABTI_CHECK_ERROR
#define ABTI_CHECK_ERROR(abt_errno)
Definition: abti_error.h:120
data
Definition: fifo.c:29
ABT_sched_exit
int ABT_sched_exit(ABT_sched sched)
Request a scheduler to finish.
Definition: sched.c:410
ABTI_sched::num_pools
size_t num_pools
Definition: abti.h:299
ABTI_sched_get_handle
static ABT_sched ABTI_sched_get_handle(ABTI_sched *p_sched)
Definition: abti_sched.h:26
ABT_POOL_ACCESS_MPMC
@ ABT_POOL_ACCESS_MPMC
Definition: abt.h:541
ABT_sched_def::run
ABT_sched_run_fn run
Function that defines a kernel of a scheduler.
Definition: abt.h:1367
ABT_sched_config
struct ABT_sched_config_opaque * ABT_sched_config
Scheduler configuration handle type.
Definition: abt.h:815
ABT_SCHED_DEFAULT
@ ABT_SCHED_DEFAULT
Definition: abt.h:467
ABTI_pool::automatic
ABT_bool automatic
Definition: abti.h:329
ABTI_thread_free
void ABTI_thread_free(ABTI_global *p_global, ABTI_local *p_local, ABTI_thread *p_thread)
Definition: thread.c:2400
ABTI_pool_get_size
static size_t ABTI_pool_get_size(ABTI_pool *p_pool)
Definition: abti_pool.h:121
ABTI_IS_ERROR_CHECK_ENABLED
#define ABTI_IS_ERROR_CHECK_ENABLED
Definition: abti.h:20
g_sched_id
static ABTD_atomic_uint64 g_sched_id
Definition: sched.c:1032
ABTI_sched_config
Definition: abti.h:323
ABT_pool
struct ABT_pool_opaque * ABT_pool
Pool handle type.
Definition: abt.h:841
ABTI_sched::p_ythread
ABTI_ythread * p_ythread
Definition: abti.h:300
ABT_sched_config_automatic
ABT_sched_config_var ABT_sched_config_automatic
Predefined ABT_sched_config_var to configure whether the scheduler is freed automatically or not.
Definition: config.c:30
ABT_POOL_ACCESS_MPSC
@ ABT_POOL_ACCESS_MPSC
Definition: abt.h:535
ABTI_SCHED_IN_POOL
@ ABTI_SCHED_IN_POOL
Definition: abti.h:78
ABTI_sched_get_effective_size
size_t ABTI_sched_get_effective_size(ABTI_local *p_local, ABTI_sched *p_sched)
Definition: sched.c:929
ABT_sched_finish
int ABT_sched_finish(ABT_sched sched)
Request a scheduler to finish after its pools get empty.
Definition: sched.c:373
ABT_POOL_ACCESS_PRIV
@ ABT_POOL_ACCESS_PRIV
Definition: abt.h:526
ABTI_sched::used
ABTI_sched_used used
Definition: abti.h:290
ABT_sched
struct ABT_sched_opaque * ABT_sched
Scheduler handle type.
Definition: abt.h:808
ABTD_atomic_acquire_load_int32
static int32_t ABTD_atomic_acquire_load_int32(const ABTD_atomic_int32 *ptr)
Definition: abtd_atomic.h:911
ABTI_pool
Definition: abti.h:327
ABTI_sched_get_basic_wait_def
ABT_sched_def * ABTI_sched_get_basic_wait_def(void)
Definition: basic_wait.c:27
ABT_POOL_NULL
#define ABT_POOL_NULL
Definition: abt.h:1059
ABTI_sched_config_get_handle
static ABT_sched_config ABTI_sched_config_get_handle(ABTI_sched_config *p_config)
Definition: abti_config.h:28
ABTI_sched_get_total_size
size_t ABTI_sched_get_total_size(ABTI_sched *p_sched)
Definition: sched.c:912
ABTI_sched_get_migration_pool
ABTU_ret_err int ABTI_sched_get_migration_pool(ABTI_sched *p_sched, ABTI_pool *source_pool, ABTI_pool **pp_pool)
Definition: sched.c:895
abti.h
ABTI_pool_free
void ABTI_pool_free(ABTI_pool *p_pool)
Definition: pool.c:891
sched_get_kind
static ABTI_sched_kind sched_get_kind(ABT_sched_def *def)
Definition: sched.c:1042
ABTI_SCHED_REQ_REPLACE
#define ABTI_SCHED_REQ_REPLACE
Definition: abti.h:40
ABTD_atomic_relaxed_store_uint32
static void ABTD_atomic_relaxed_store_uint32(ABTD_atomic_uint32 *ptr, uint32_t val)
Definition: abtd_atomic.h:1025
ABTI_sched_get_size
size_t ABTI_sched_get_size(ABTI_sched *p_sched)
Definition: sched.c:633
ABTI_SCHED_REQ_EXIT
#define ABTI_SCHED_REQ_EXIT
Definition: abti.h:39
ABTI_HANDLE_ERROR
#define ABTI_HANDLE_ERROR(n)
Definition: abti_error.h:114
ABTU_malloc
static ABTU_ret_err int ABTU_malloc(size_t size, void **p_ptr)
Definition: abtu.h:262
LOG_DEBUG
#define LOG_DEBUG(fmt,...)
Definition: abti_log.h:26
ABT_ERR_SCHED
#define ABT_ERR_SCHED
Error code: error related to a scheduler.
Definition: abt.h:272
ABTI_sched::free
ABT_sched_free_fn free
Definition: abti.h:306
sched_create
static ABTU_ret_err int sched_create(ABT_sched_def *def, int num_pools, ABT_pool *pools, ABTI_sched_config *p_config, ABT_bool def_automatic, ABTI_sched **pp_newsched)
Definition: sched.c:1047
ABT_POOL_FIFO
@ ABT_POOL_FIFO
Definition: abt.h:506
ABTD_ATOMIC_UINT64_STATIC_INITIALIZER
#define ABTD_ATOMIC_UINT64_STATIC_INITIALIZER(val)
Definition: abtd_atomic.h:67
ABTI_pool_create_basic
ABTU_ret_err int ABTI_pool_create_basic(ABT_pool_kind kind, ABT_pool_access access, ABT_bool automatic, ABTI_pool **pp_newpool)
Definition: pool.c:858
ABTI_sched::get_migr_pool
ABT_sched_get_migr_pool_fn get_migr_pool
Definition: abti.h:307
ABTI_pool_get_total_size
static size_t ABTI_pool_get_total_size(ABTI_pool *p_pool)
Definition: abti_pool.h:126
ABTI_sched_get_basic_def
ABT_sched_def * ABTI_sched_get_basic_def(void)
Definition: basic.c:30
ABT_POOL_FIFO_WAIT
@ ABT_POOL_FIFO_WAIT
Definition: abt.h:515
ABTI_sched_config_read
ABTU_ret_err int ABTI_sched_config_read(const ABTI_sched_config *p_config, int idx, void *p_val)
Definition: config.c:259
ABTI_sched_get_randws_def
ABT_sched_def * ABTI_sched_get_randws_def(void)
Definition: randws.c:31
ABT_sched_get_total_size
int ABT_sched_get_total_size(ABT_sched sched, size_t *size)
Obtain the sum of the total sizes of pools associated with a scheduler.
Definition: sched.c:616
ABTI_ASSERT
#define ABTI_ASSERT(cond)
Definition: abti_error.h:12
ABTI_sched_set_request
static void ABTI_sched_set_request(ABTI_sched *p_sched, uint32_t req)
Definition: abti_sched.h:60
ABT_ERR_MIGRATION_TARGET
#define ABT_ERR_MIGRATION_TARGET
Error code: error related to a migration target.
Definition: abt.h:360
ABTI_sched::pools
ABT_pool * pools
Definition: abti.h:298
ABT_SCHED_BASIC
@ ABT_SCHED_BASIC
Definition: abt.h:469
ABTI_local_get_local
static ABTI_local * ABTI_local_get_local(void)
Definition: abti_local.h:41
ABT_SUCCESS
#define ABT_SUCCESS
Error code: the routine returns successfully.
Definition: abt.h:92
ABT_sched_def::get_migr_pool
ABT_sched_get_migr_pool_fn get_migr_pool
Function that returns a pool for migration.
Definition: abt.h:1400
ABTU_ret_err
#define ABTU_ret_err
Definition: abtu.h:146
ABTI_sched::kind
ABTI_sched_kind kind
Definition: abti.h:292
ABT_sched_get_num_pools
int ABT_sched_get_num_pools(ABT_sched sched, int *num_pools)
Obtain the number of pools associated with a scheduler.
Definition: sched.c:275
ABTI_SCHED_MAIN
@ ABTI_SCHED_MAIN
Definition: abti.h:77
ABT_TRUE
#define ABT_TRUE
True constant for ABT_bool.
Definition: abt.h:748
ABT_SCHED_NULL
#define ABT_SCHED_NULL
Definition: abt.h:1057
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:297
ABT_POOL_ACCESS_SPMC
@ ABT_POOL_ACCESS_SPMC
Definition: abt.h:539
ABTI_sched
Definition: abti.h:289
ABT_FALSE
#define ABT_FALSE
False constant for ABT_bool.
Definition: abt.h:750
ABTI_sched_kind
uintptr_t ABTI_sched_kind
Definition: abti.h:119
ABT_sched_def::free
ABT_sched_free_fn free
Function that frees a scheduler.
Definition: abt.h:1383
ABTI_pool::access
ABT_pool_access access
Definition: abti.h:328
ABT_sched_set_data
int ABT_sched_set_data(ABT_sched sched, void *data)
Associate a user value with a scheduler.
Definition: sched.c:494
ABT_ERR_INV_ARG
#define ABT_ERR_INV_ARG
Error code: invalid user argument.
Definition: abt.h:250
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
ABT_POOL_ACCESS_SPSC
@ ABT_POOL_ACCESS_SPSC
Definition: abt.h:531
ABTU_free
static void ABTU_free(void *ptr)
Definition: abtu.h:217
ABT_sched_def
A struct that defines a scheduler.
Definition: abt.h:1302
ABT_SCHED_BASIC_WAIT
@ ABT_SCHED_BASIC_WAIT
Definition: abt.h:479
ABT_SCHED_RANDWS
@ ABT_SCHED_RANDWS
Definition: abt.h:477
ABTI_ythread::thread
ABTI_thread thread
Definition: abti.h:407
ABTI_local
struct ABTI_local ABTI_local
Definition: abti.h:110
ABTI_sched_finish
void ABTI_sched_finish(ABTI_sched *p_sched)
Definition: sched.c:645
ABTI_pool_print
void ABTI_pool_print(ABTI_pool *p_pool, FILE *p_os, int indent)
Definition: pool.c:901
ABTI_CHECK_TRUE
#define ABTI_CHECK_TRUE(cond, abt_errno)
Definition: abti_error.h:130
ABT_sched_has_to_stop
int ABT_sched_has_to_stop(ABT_sched sched, ABT_bool *stop)
Check if a scheduler needs to stop.
Definition: sched.c:456
ABTI_sched_config_get_ptr
static ABTI_sched_config * ABTI_sched_config_get_ptr(ABT_sched_config config)
Definition: abti_config.h:12
ABTI_global
Definition: abti.h:196
ABT_sched_def::init
ABT_sched_init_fn init
Function that initializes a scheduler.
Definition: abt.h:1327
ABT_sched_free
int ABT_sched_free(ABT_sched *sched)
Free a scheduler.
Definition: sched.c:234
ABTI_pool_release
static int32_t ABTI_pool_release(ABTI_pool *p_pool)
Definition: abti_pool.h:115
ABT_sched_get_pools
int ABT_sched_get_pools(ABT_sched sched, int max_pools, int idx, ABT_pool *pools)
Retrieve pools associated with a scheduler.
Definition: sched.c:320
ABTI_pool_retain
static void ABTI_pool_retain(ABTI_pool *p_pool)
Definition: abti_pool.h:108
ABT_pool_kind
ABT_pool_kind
Predefined pool type.
Definition: abt.h:504
ABT_sched_get_data
int ABT_sched_get_data(ABT_sched sched, void **data)
Retrieve a user value associated with a scheduler.
Definition: sched.c:526
ABTI_pool::num_scheds
ABTD_atomic_int32 num_scheds
Definition: abti.h:332
ABTI_SCHED_REQ_FINISH
#define ABTI_SCHED_REQ_FINISH
Definition: abti.h:38
ABTI_pool_get_handle
static ABT_pool ABTI_pool_get_handle(ABTI_pool *p_pool)
Definition: abti_pool.h:26
ABTI_sched_has_to_stop
ABT_bool ABTI_sched_has_to_stop(ABTI_local **pp_local, ABTI_sched *p_sched)
Definition: sched.c:871
ABT_sched_create
int ABT_sched_create(ABT_sched_def *def, int num_pools, ABT_pool *pools, ABT_sched_config config, ABT_sched *newsched)
Create a new scheduler with a scheduler definition.
Definition: sched.c:91
ABT_sched_config_var::idx
int idx
Definition: abt.h:1242
ABT_sched_get_size
int ABT_sched_get_size(ABT_sched sched, size_t *size)
Obtain the sum of sizes of pools associated with a scheduler.
Definition: sched.c:568
ABTI_sched_get_prio_def
ABT_sched_def * ABTI_sched_get_prio_def(void)
Definition: prio.c:29
ABT_SCHED_PRIO
@ ABT_SCHED_PRIO
Definition: abt.h:473
ABT_pool_access
ABT_pool_access
Pool access type.
Definition: abt.h:522
ABTI_sched_exit
void ABTI_sched_exit(ABTI_sched *p_sched)
Definition: sched.c:650