ARGOBOTS  4dc37e16e1b227a480715ab67dae1dcfb4d2d4e0
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 {
95  ABTI_UB_ASSERT(def);
96  ABTI_UB_ASSERT(def->run);
97  ABTI_UB_ASSERT(pools || num_pools == 0);
98 
99  ABTI_sched *p_sched;
100 #ifndef ABT_CONFIG_ENABLE_VER_20_API
101  *newsched = ABT_SCHED_NULL;
102  ABTI_CHECK_TRUE(newsched != NULL, ABT_ERR_SCHED);
103 #else
104  ABTI_UB_ASSERT(newsched);
105 #endif
106  ABTI_CHECK_TRUE(num_pools >= 0, ABT_ERR_INV_ARG);
107 
108  /* The default automatic is different from ABT_sched_create_basic(). */
109  const ABT_bool def_automatic = ABT_FALSE;
110  ABTI_sched_config *p_config = ABTI_sched_config_get_ptr(config);
111  int abt_errno =
112  sched_create(def, num_pools, pools, p_config, def_automatic, &p_sched);
113  ABTI_CHECK_ERROR(abt_errno);
114 
115  /* Return value */
116  *newsched = ABTI_sched_get_handle(p_sched);
117  return ABT_SUCCESS;
118 }
119 
181 int ABT_sched_create_basic(ABT_sched_predef predef, int num_pools,
182  ABT_pool *pools, ABT_sched_config config,
183  ABT_sched *newsched)
184 {
186 
187 #ifndef ABT_CONFIG_ENABLE_VER_20_API
188  *newsched = ABT_SCHED_NULL;
189  ABTI_CHECK_TRUE(newsched != NULL, ABT_ERR_SCHED);
190 #else
191  ABTI_UB_ASSERT(newsched);
192 #endif
193  ABTI_CHECK_TRUE(num_pools >= 0, ABT_ERR_INV_ARG);
194 
195  ABTI_sched *p_newsched;
196  ABTI_sched_config *p_config = ABTI_sched_config_get_ptr(config);
197  int abt_errno = ABTI_sched_create_basic(predef, num_pools, pools, p_config,
198  &p_newsched);
199  ABTI_CHECK_ERROR(abt_errno);
200  *newsched = ABTI_sched_get_handle(p_newsched);
201  return ABT_SUCCESS;
202 }
203 
246 {
248  ABTI_UB_ASSERT(sched);
249 
250  ABTI_global *p_global;
251  ABTI_SETUP_GLOBAL(&p_global);
252  ABTI_local *p_local = ABTI_local_get_local();
253  ABTI_sched *p_sched = ABTI_sched_get_ptr(*sched);
254  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
255 #ifndef ABT_CONFIG_ENABLE_VER_20_API
257 #else
259 #endif
260 
261  /* Free the scheduler */
262  ABTI_sched_free(p_global, p_local, p_sched, ABT_FALSE);
263 
264  /* Return value */
265  *sched = ABT_SCHED_NULL;
266  return ABT_SUCCESS;
267 }
268 
291 int ABT_sched_get_num_pools(ABT_sched sched, int *num_pools)
292 {
294  ABTI_UB_ASSERT(num_pools);
295 
296  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
297  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
298 
299  *num_pools = p_sched->num_pools;
300  return ABT_SUCCESS;
301 }
302 
339 int ABT_sched_get_pools(ABT_sched sched, int max_pools, int idx,
340  ABT_pool *pools)
341 {
343  ABTI_UB_ASSERT(pools || max_pools > 0);
344 
345  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
346  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
347  ABTI_CHECK_TRUE(max_pools >= 0, ABT_ERR_INV_ARG);
348  ABTI_CHECK_TRUE(idx >= 0, ABT_ERR_INV_ARG);
349 #ifndef ABT_CONFIG_ENABLE_VER_20_API
350  ABTI_CHECK_TRUE((size_t)(idx + max_pools) <= p_sched->num_pools,
351  ABT_ERR_SCHED);
352 #endif
353 
354  size_t p;
355  for (p = idx; p < (size_t)idx + max_pools; p++) {
356  if (p >= p_sched->num_pools) {
357  /* Out of range. */
358  break;
359  }
360  pools[p - idx] = p_sched->pools[p];
361  }
362  return ABT_SUCCESS;
363 }
364 
396 {
398 
399  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
400  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
401 
402  ABTI_sched_finish(p_sched);
403  return ABT_SUCCESS;
404 }
405 
435 {
437 
438  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
439  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
440 
441  ABTI_sched_exit(p_sched);
442  return ABT_SUCCESS;
443 }
444 
483 {
485  ABTI_UB_ASSERT(stop);
486 
487 #ifndef ABT_CONFIG_ENABLE_VER_20_API
488  *stop = ABT_FALSE;
489 #endif
490  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
491  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
492 #ifndef ABT_CONFIG_ENABLE_VER_20_API
494 #endif
495 
496  *stop = ABTI_sched_has_to_stop(p_sched);
497  return ABT_SUCCESS;
498 }
499 
523 {
525 
526  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
527  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
528 
529  p_sched->data = data;
530  return ABT_SUCCESS;
531 }
532 
557 {
560 
561  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
562  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
563 
564  *data = p_sched->data;
565  return ABT_SUCCESS;
566 }
603 int ABT_sched_get_size(ABT_sched sched, size_t *size)
604 {
606  ABTI_UB_ASSERT(size);
607 
608 #ifndef ABT_CONFIG_ENABLE_VER_20_API
609  *size = 0;
610 #endif
611 
612  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
613  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
614  /* Check availability of p_get_size() */
615  size_t p;
616  for (p = 0; p < p_sched->num_pools; p++) {
617  ABTI_pool *p_pool = ABTI_pool_get_ptr(p_sched->pools[p]);
619  }
620 
621  /* Sum up all the sizes */
622  size_t pool_size = 0;
623  for (p = 0; p < p_sched->num_pools; p++) {
624  ABTI_pool *p_pool = ABTI_pool_get_ptr(p_sched->pools[p]);
625  pool_size += ABTI_pool_get_size(p_pool);
626  }
627  *size = pool_size;
628  return ABT_SUCCESS;
629 }
630 
668 int ABT_sched_get_total_size(ABT_sched sched, size_t *size)
669 {
671  ABTI_UB_ASSERT(size);
672 
673 #ifndef ABT_CONFIG_ENABLE_VER_20_API
674  *size = 0;
675 #endif
676 
677  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
678  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
679  /* Check availability of p_get_size() */
680  size_t p;
681  for (p = 0; p < p_sched->num_pools; p++) {
682  ABTI_pool *p_pool = ABTI_pool_get_ptr(p_sched->pools[p]);
684  }
685 
686  /* Sum up all the sizes */
687  size_t pool_size = 0;
688  for (p = 0; p < p_sched->num_pools; p++) {
689  ABTI_pool *p_pool = ABTI_pool_get_ptr(p_sched->pools[p]);
690  pool_size += ABTI_pool_get_total_size(p_pool);
691  }
692  *size = pool_size;
693  return ABT_SUCCESS;
694 }
695 
696 /*****************************************************************************/
697 /* Private APIs */
698 /*****************************************************************************/
699 
701 {
703 }
704 
706 {
708 }
709 
711  ABT_pool *pools,
712  ABTI_sched_config *p_config,
713  ABTI_sched **pp_newsched)
714 {
715  int abt_errno;
717  /* The default value is different from ABT_sched_create. */
718  const ABT_bool def_automatic = ABT_TRUE;
719  /* Always use MPMC pools */
720  const ABT_pool_access def_access = ABT_POOL_ACCESS_MPMC;
721 
722  /* A pool array is provided, predef has to be compatible */
723  if (pools != NULL) {
724  /* Copy of the contents of pools */
725  ABT_pool *pool_list;
726  if (num_pools > 0) {
727  abt_errno =
728  ABTU_malloc(num_pools * sizeof(ABT_pool), (void **)&pool_list);
729  ABTI_CHECK_ERROR(abt_errno);
730 
731  int p;
732  for (p = 0; p < num_pools; p++) {
733  if (pools[p] == ABT_POOL_NULL) {
734  ABTI_pool *p_newpool;
735  abt_errno =
737  ABT_TRUE, &p_newpool);
739  abt_errno != ABT_SUCCESS) {
740  /* Remove pools that are already created. */
741  int i;
742  for (i = 0; i < p; i++) {
743  if (pools[i] != ABT_POOL_NULL)
744  continue; /* User given pool. */
745  /* Free a pool created in this function. */
746  ABTI_pool_free(ABTI_pool_get_ptr(pool_list[i]));
747  }
748  ABTU_free(pool_list);
749  ABTI_HANDLE_ERROR(abt_errno);
750  }
751  pool_list[p] = ABTI_pool_get_handle(p_newpool);
752  } else {
753  pool_list[p] = pools[p];
754  }
755  }
756  } else {
757  /* TODO: Check if it works. */
758  pool_list = NULL;
759  }
760 
761  /* Creation of the scheduler */
762  switch (predef) {
763  case ABT_SCHED_DEFAULT:
764  case ABT_SCHED_BASIC:
765  abt_errno = sched_create(ABTI_sched_get_basic_def(), num_pools,
766  pool_list, p_config, def_automatic,
767  pp_newsched);
768  break;
771  num_pools, pool_list, p_config,
772  def_automatic, pp_newsched);
773  break;
774  case ABT_SCHED_PRIO:
775  abt_errno = sched_create(ABTI_sched_get_prio_def(), num_pools,
776  pool_list, p_config, def_automatic,
777  pp_newsched);
778  break;
779  case ABT_SCHED_RANDWS:
780  abt_errno = sched_create(ABTI_sched_get_randws_def(), num_pools,
781  pool_list, p_config, def_automatic,
782  pp_newsched);
783  break;
784  default:
785  abt_errno = ABT_ERR_INV_SCHED_PREDEF;
786  break;
787  }
788  if (ABTI_IS_ERROR_CHECK_ENABLED && abt_errno != ABT_SUCCESS) {
789  /* Remove pools that are already created. */
790  int i;
791  for (i = 0; i < num_pools; i++) {
792  if (pools[i] != ABT_POOL_NULL)
793  continue; /* User given pool. */
794  /* Free a pool created in this function. */
795  ABTI_pool_free(ABTI_pool_get_ptr(pool_list[i]));
796  }
797  ABTU_free(pool_list);
798  ABTI_HANDLE_ERROR(abt_errno);
799  }
800  ABTU_free(pool_list);
801  } else { /* No pool array is provided, predef has to be compatible */
802  /* Set the number of pools */
803  switch (predef) {
804  case ABT_SCHED_DEFAULT:
805  case ABT_SCHED_BASIC:
806  num_pools = 1;
807  break;
809  /* FIFO_WAIT is default pool for use with BASIC_WAIT sched */
810  kind = ABT_POOL_FIFO_WAIT;
811  num_pools = 1;
812  break;
813  case ABT_SCHED_PRIO:
814  num_pools = ABTI_SCHED_NUM_PRIO;
815  break;
816  case ABT_SCHED_RANDWS:
817  num_pools = 1;
818  break;
819  default:
820  abt_errno = ABT_ERR_INV_SCHED_PREDEF;
821  ABTI_CHECK_ERROR(abt_errno);
822  break;
823  }
824 
825  /* Creation of the pools */
826  /* To avoid the malloc overhead, we use a stack array. */
827  ABT_pool pool_list[ABTI_SCHED_NUM_PRIO];
828  int p;
829  /* ICC 19 warns an unused variable in the following error path. To
830  * suppress the warning, let's initialize the array member here. */
831  for (p = 0; p < num_pools; p++)
832  pool_list[p] = ABT_POOL_NULL;
833  for (p = 0; p < num_pools; p++) {
834  ABTI_pool *p_newpool;
835  abt_errno =
836  ABTI_pool_create_basic(kind, def_access, ABT_TRUE, &p_newpool);
837  if (ABTI_IS_ERROR_CHECK_ENABLED && abt_errno != ABT_SUCCESS) {
838  /* Remove pools that are already created. */
839  int i;
840  for (i = 0; i < p; i++) {
841  /* Free a pool created in this function. */
842  ABTI_pool_free(ABTI_pool_get_ptr(pool_list[i]));
843  }
844  ABTI_HANDLE_ERROR(abt_errno);
845  }
846  pool_list[p] = ABTI_pool_get_handle(p_newpool);
847  }
848 
849  /* Creation of the scheduler */
850  switch (predef) {
851  case ABT_SCHED_DEFAULT:
852  case ABT_SCHED_BASIC:
853  abt_errno = sched_create(ABTI_sched_get_basic_def(), num_pools,
854  pool_list, p_config, def_automatic,
855  pp_newsched);
856  break;
859  num_pools, pool_list, p_config,
860  def_automatic, pp_newsched);
861  break;
862  case ABT_SCHED_PRIO:
863  abt_errno = sched_create(ABTI_sched_get_prio_def(), num_pools,
864  pool_list, p_config, def_automatic,
865  pp_newsched);
866  break;
867  case ABT_SCHED_RANDWS:
868  abt_errno = sched_create(ABTI_sched_get_randws_def(), num_pools,
869  pool_list, p_config, def_automatic,
870  pp_newsched);
871  break;
872  default:
873  abt_errno = ABT_ERR_INV_SCHED_PREDEF;
874  break;
875  }
876  if (ABTI_IS_ERROR_CHECK_ENABLED && abt_errno != ABT_SUCCESS) {
877  /* Remove pools that are already created. */
878  int i;
879  for (i = 0; i < num_pools; i++) {
880  /* Free a pool created in this function. */
881  ABTI_pool_free(ABTI_pool_get_ptr(pool_list[i]));
882  }
883  ABTI_HANDLE_ERROR(abt_errno);
884  }
885  }
886  return ABT_SUCCESS;
887 }
888 
889 void ABTI_sched_free(ABTI_global *p_global, ABTI_local *p_local,
890  ABTI_sched *p_sched, ABT_bool force_free)
891 {
892  ABTI_ASSERT(p_sched->used == ABTI_SCHED_NOT_USED);
893  /* Free the scheduler first. */
894  if (p_sched->free) {
895  p_sched->free(ABTI_sched_get_handle(p_sched));
896  }
897  /* If sched is a default provided one, it should free its pool here.
898  * Otherwise, freeing the pool is the user's responsibility. */
899  size_t p;
900  for (p = 0; p < p_sched->num_pools; p++) {
901  ABTI_pool *p_pool = ABTI_pool_get_ptr(p_sched->pools[p]);
902  if (!p_pool) {
903  /* p_pool can be set to NULL when that p_pool must be preserved,
904  * for example, when this function is called because
905  * ABT_xstream_create_basic() fails. */
906  continue;
907  }
908  int32_t num_scheds = ABTI_pool_release(p_pool);
909  if ((p_pool->automatic == ABT_TRUE && num_scheds == 0) || force_free) {
910  ABTI_pool_free(p_pool);
911  }
912  }
913  ABTU_free(p_sched->pools);
914 
915  /* Free the associated work unit */
916  if (p_sched->p_ythread) {
917  ABTI_thread_free(p_global, p_local, &p_sched->p_ythread->thread);
918  }
919 
920  p_sched->data = NULL;
921 
922  ABTU_free(p_sched);
923 }
924 
926 {
927  /* Check exit request */
930  return ABT_TRUE;
931  }
932 
933  if (!ABTI_sched_has_unit(p_sched)) {
936  /* Check join request */
937  if (!ABTI_sched_has_unit(p_sched))
938  return ABT_TRUE;
939  } else if (p_sched->used == ABTI_SCHED_IN_POOL) {
940  /* Let's finish it anyway.
941  * TODO: think about the condition. */
942  return ABT_TRUE;
943  }
944  }
945  return ABT_FALSE;
946 }
947 
949 {
950  /* ABTI_sched_has_unit() does not count the number of blocked ULTs if a pool
951  * has more than one consumer or the caller ES is not the latest consumer.
952  * This is necessary when the ES associated with the target scheduler has to
953  * be joined and the pool is shared between different schedulers associated
954  * with different ESs. */
955  size_t p, num_pools = p_sched->num_pools;
956  for (p = 0; p < num_pools; p++) {
957  ABT_pool pool = p_sched->pools[p];
958  ABTI_pool *p_pool = ABTI_pool_get_ptr(pool);
959  if (!ABTI_pool_is_empty(p_pool))
960  return ABT_TRUE;
961  switch (p_pool->access) {
964  return ABT_TRUE;
965  break;
970  if (ABTD_atomic_acquire_load_int32(&p_pool->num_scheds) == 1) {
972  return ABT_TRUE;
973  }
974  break;
975  default:
976  break;
977  }
978  }
979  return ABT_FALSE;
980 }
981 
982 /* Get the pool suitable for receiving a migrating thread */
984  ABTI_pool *source_pool,
985  ABTI_pool **pp_pool)
986 {
987  /* Find a pool. If get_migr_pool is not defined, we pick the first pool */
988  if (p_sched->get_migr_pool == NULL) {
990  *pp_pool = ABTI_pool_get_ptr(p_sched->pools[0]);
991  } else {
992  ABT_sched sched = ABTI_sched_get_handle(p_sched);
993  ABTI_pool *p_pool = ABTI_pool_get_ptr(p_sched->get_migr_pool(sched));
995  *pp_pool = p_pool;
996  }
997  return ABT_SUCCESS;
998 }
999 
1000 void ABTI_sched_print(ABTI_sched *p_sched, FILE *p_os, int indent,
1001  ABT_bool print_sub)
1002 {
1003  if (p_sched == NULL) {
1004  fprintf(p_os, "%*s== NULL SCHED ==\n", indent, "");
1005  } else {
1006  ABTI_sched_kind kind;
1007  const char *kind_str, *used;
1008 
1009  kind = p_sched->kind;
1010  if (kind == sched_get_kind(ABTI_sched_get_basic_def())) {
1011  kind_str = "BASIC";
1012  } else if (kind == sched_get_kind(ABTI_sched_get_basic_wait_def())) {
1013  kind_str = "BASIC_WAIT";
1014  } else if (kind == sched_get_kind(ABTI_sched_get_prio_def())) {
1015  kind_str = "PRIO";
1016  } else if (kind == sched_get_kind(ABTI_sched_get_randws_def())) {
1017  kind_str = "RANDWS";
1018  } else {
1019  kind_str = "USER";
1020  }
1021 
1022  switch (p_sched->used) {
1023  case ABTI_SCHED_NOT_USED:
1024  used = "NOT_USED";
1025  break;
1026  case ABTI_SCHED_MAIN:
1027  used = "MAIN";
1028  break;
1029  case ABTI_SCHED_IN_POOL:
1030  used = "IN_POOL";
1031  break;
1032  default:
1033  used = "UNKNOWN";
1034  break;
1035  }
1036 
1037  fprintf(p_os,
1038  "%*s== SCHED (%p) ==\n"
1039 #ifdef ABT_CONFIG_USE_DEBUG_LOG
1040  "%*sid : %" PRIu64 "\n"
1041 #endif
1042  "%*skind : %" PRIxPTR " (%s)\n"
1043  "%*sused : %s\n"
1044  "%*sautomatic: %s\n"
1045  "%*srequest : 0x%x\n"
1046  "%*snum_pools: %zu\n"
1047  "%*shas_unit : %s\n"
1048  "%*sthread : %p\n"
1049  "%*sdata : %p\n",
1050  indent, "", (void *)p_sched,
1051 #ifdef ABT_CONFIG_USE_DEBUG_LOG
1052  indent, "", p_sched->id,
1053 #endif
1054  indent, "", p_sched->kind, kind_str, indent, "", used, indent,
1055  "", (p_sched->automatic == ABT_TRUE) ? "TRUE" : "FALSE", indent,
1056  "", ABTD_atomic_acquire_load_uint32(&p_sched->request), indent,
1057  "", p_sched->num_pools, indent, "",
1058  (ABTI_sched_has_unit(p_sched) ? "TRUE" : "FALSE"), indent, "",
1059  (void *)p_sched->p_ythread, indent, "", p_sched->data);
1060  if (print_sub == ABT_TRUE) {
1061  size_t i;
1062  for (i = 0; i < p_sched->num_pools; i++) {
1063  ABTI_pool *p_pool = ABTI_pool_get_ptr(p_sched->pools[i]);
1064  ABTI_pool_print(p_pool, p_os, indent + 2);
1065  }
1066  }
1067  }
1068  fflush(p_os);
1069 }
1070 
1073 {
1075 }
1076 
1077 /*****************************************************************************/
1078 /* Internal static functions */
1079 /*****************************************************************************/
1080 
1082 {
1083  return (ABTI_sched_kind)def;
1084 }
1085 
1086 ABTU_ret_err static int sched_create(ABT_sched_def *def, int num_pools,
1087  ABT_pool *pools,
1088  ABTI_sched_config *p_config,
1089  ABT_bool def_automatic,
1090  ABTI_sched **pp_newsched)
1091 {
1092  ABTI_sched *p_sched;
1093  int p, abt_errno;
1094 
1095  abt_errno = ABTU_malloc(sizeof(ABTI_sched), (void **)&p_sched);
1096  ABTI_CHECK_ERROR(abt_errno);
1097 
1098  /* We read the config and set the configured parameters */
1099  ABT_bool automatic = def_automatic;
1100  if (p_config) {
1101  int automatic_val = 0;
1102  abt_errno =
1104  &automatic_val);
1105  if (abt_errno == ABT_SUCCESS) {
1106  automatic = (automatic_val == 0) ? ABT_FALSE : ABT_TRUE;
1107  }
1108  }
1109 
1110  /* Copy of the contents of pools */
1111  ABT_pool *pool_list;
1112  abt_errno = ABTU_malloc(num_pools * sizeof(ABT_pool), (void **)&pool_list);
1113  if (ABTI_IS_ERROR_CHECK_ENABLED && abt_errno != ABT_SUCCESS) {
1114  ABTU_free(p_sched);
1115  return abt_errno;
1116  }
1117  for (p = 0; p < num_pools; p++) {
1118  if (pools[p] == ABT_POOL_NULL) {
1119  ABTI_pool *p_newpool;
1120  abt_errno =
1122  ABT_TRUE, &p_newpool);
1123  if (ABTI_IS_ERROR_CHECK_ENABLED && abt_errno != ABT_SUCCESS) {
1124  int i;
1125  for (i = 0; i < p; i++) {
1126  if (pools[i] == ABT_POOL_NULL)
1127  ABTI_pool_free(ABTI_pool_get_ptr(pool_list[i]));
1128  }
1129  ABTU_free(pool_list);
1130  ABTU_free(p_sched);
1131  return abt_errno;
1132  }
1133  pool_list[p] = ABTI_pool_get_handle(p_newpool);
1134  } else {
1135  pool_list[p] = pools[p];
1136  }
1137  }
1138  /* Check if the pools are available */
1139  for (p = 0; p < num_pools; p++) {
1140  ABTI_pool_retain(ABTI_pool_get_ptr(pool_list[p]));
1141  }
1142 
1143  p_sched->used = ABTI_SCHED_NOT_USED;
1144  p_sched->automatic = automatic;
1145  p_sched->kind = sched_get_kind(def);
1146  p_sched->p_replace_sched = NULL;
1147  p_sched->p_replace_waiter = NULL;
1148  ABTD_atomic_relaxed_store_uint32(&p_sched->request, 0);
1149  p_sched->pools = pool_list;
1150  p_sched->num_pools = num_pools;
1151  p_sched->type = def->type;
1152  p_sched->p_ythread = NULL;
1153  p_sched->data = NULL;
1154 
1155  p_sched->init = def->init;
1156  p_sched->run = def->run;
1157  p_sched->free = def->free;
1158  p_sched->get_migr_pool = def->get_migr_pool;
1159 
1160 #ifdef ABT_CONFIG_USE_DEBUG_LOG
1161  p_sched->id = sched_get_new_id();
1162 #endif
1163 
1164  /* Return value */
1165  ABT_sched newsched = ABTI_sched_get_handle(p_sched);
1166 
1167  /* Specific initialization */
1168  if (p_sched->init) {
1170  abt_errno = p_sched->init(newsched, config);
1171  if (ABTI_IS_ERROR_CHECK_ENABLED && abt_errno != ABT_SUCCESS) {
1172  for (p = 0; p < num_pools; p++) {
1173  if (pools[p] == ABT_POOL_NULL) {
1174  ABTI_pool_free(ABTI_pool_get_ptr(pool_list[p]));
1175  } else {
1176  ABTI_pool_release(ABTI_pool_get_ptr(pool_list[p]));
1177  }
1178  }
1179  ABTU_free(pool_list);
1180  ABTU_free(p_sched);
1181  return abt_errno;
1182  }
1183  }
1184 
1185  *pp_newsched = p_sched;
1186 
1187  return ABT_SUCCESS;
1188 }
1189 
1190 #ifdef ABT_CONFIG_USE_DEBUG_LOG
1191 static inline uint64_t sched_get_new_id(void)
1192 {
1194 }
1195 #endif
ABTI_pool_optional_def::p_get_size
ABT_pool_user_get_size_fn p_get_size
Definition: abti.h:361
ABTI_CHECK_NULL_SCHED_PTR
#define ABTI_CHECK_NULL_SCHED_PTR(p)
Definition: abti_error.h:211
ABTI_sched::data
void * data
Definition: abti.h:331
ABT_sched_predef
ABT_sched_predef
Predefined scheduler type.
Definition: abt.h:475
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:1072
ABTI_pool::num_blocked
ABTD_atomic_int32 num_blocked
Definition: abti.h:395
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:181
ABT_bool
int ABT_bool
Boolean type.
Definition: abt.h:1043
ABTI_SCHED_NOT_USED
@ ABTI_SCHED_NOT_USED
Definition: abti.h:71
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:1418
ABTI_SETUP_GLOBAL
#define ABTI_SETUP_GLOBAL(pp_global)
Definition: abti_error.h:75
ABTI_sched_print
void ABTI_sched_print(ABTI_sched *p_sched, FILE *p_os, int indent, ABT_bool print_sub)
Definition: sched.c:1000
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:710
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:42
ABT_ERR_POOL
#define ABT_ERR_POOL
Error code: error related to a pool.
Definition: abt.h:292
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:889
ABTI_CHECK_ERROR
#define ABTI_CHECK_ERROR(abt_errno)
Definition: abti_error.h:136
data
Definition: fifo.c:45
ABT_sched_exit
int ABT_sched_exit(ABT_sched sched)
Request a scheduler to finish.
Definition: sched.c:434
ABTI_sched::num_pools
size_t num_pools
Definition: abti.h:329
ABTI_sched_has_unit
ABT_bool ABTI_sched_has_unit(ABTI_sched *p_sched)
Definition: sched.c:948
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:575
ABT_sched_def::run
ABT_sched_run_fn run
Function that defines a kernel of a scheduler.
Definition: abt.h:1476
ABT_sched_config
struct ABT_sched_config_opaque * ABT_sched_config
Scheduler configuration handle type.
Definition: abt.h:852
ABT_SCHED_DEFAULT
@ ABT_SCHED_DEFAULT
Definition: abt.h:477
ABTI_pool::automatic
ABT_bool automatic
Definition: abti.h:391
ABTI_thread_free
void ABTI_thread_free(ABTI_global *p_global, ABTI_local *p_local, ABTI_thread *p_thread)
Definition: thread.c:2616
ABTI_pool_get_size
static size_t ABTI_pool_get_size(ABTI_pool *p_pool)
Definition: abti_pool.h:141
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:1071
ABTI_sched_config
Definition: abti.h:344
ABT_pool
struct ABT_pool_opaque * ABT_pool
Pool handle type.
Definition: abt.h:878
ABTI_sched::p_ythread
ABTI_ythread * p_ythread
Definition: abti.h:330
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: sched_config.c:47
ABT_POOL_ACCESS_MPSC
@ ABT_POOL_ACCESS_MPSC
Definition: abt.h:569
ABTI_SCHED_IN_POOL
@ ABTI_SCHED_IN_POOL
Definition: abti.h:73
ABT_sched_finish
int ABT_sched_finish(ABT_sched sched)
Request a scheduler to finish after its pools get empty.
Definition: sched.c:395
ABT_POOL_ACCESS_PRIV
@ ABT_POOL_ACCESS_PRIV
Definition: abt.h:560
ABTI_sched::used
ABTI_sched_used used
Definition: abti.h:320
ABT_sched
struct ABT_sched_opaque * ABT_sched
Scheduler handle type.
Definition: abt.h:845
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:389
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:1102
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:983
abti.h
ABTI_pool_free
void ABTI_pool_free(ABTI_pool *p_pool)
Definition: pool.c:1433
sched_get_kind
static ABTI_sched_kind sched_get_kind(ABT_sched_def *def)
Definition: sched.c:1081
ABTI_SCHED_REQ_REPLACE
#define ABTI_SCHED_REQ_REPLACE
Definition: abti.h:46
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_config_get_handle
static ABT_sched_config ABTI_sched_config_get_handle(ABTI_sched_config *p_config)
Definition: abti_sched_config.h:28
ABTI_SCHED_REQ_EXIT
#define ABTI_SCHED_REQ_EXIT
Definition: abti.h:45
ABTI_HANDLE_ERROR
#define ABTI_HANDLE_ERROR(n)
Definition: abti_error.h:130
ABTU_malloc
static ABTU_ret_err int ABTU_malloc(size_t size, void **p_ptr)
Definition: abtu.h:235
ABT_ERR_SCHED
#define ABT_ERR_SCHED
Error code: error related to a scheduler.
Definition: abt.h:282
ABTI_sched::free
ABT_sched_free_fn free
Definition: abti.h:336
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:1086
ABT_POOL_FIFO
@ ABT_POOL_FIFO
Definition: abt.h:516
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:1389
ABTI_sched::get_migr_pool
ABT_sched_get_migr_pool_fn get_migr_pool
Definition: abti.h:337
ABTI_pool_get_total_size
static size_t ABTI_pool_get_total_size(ABTI_pool *p_pool)
Definition: abti_pool.h:147
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:525
ABTI_sched_config_read
ABTU_ret_err int ABTI_sched_config_read(const ABTI_sched_config *p_config, int idx, void *p_val)
Definition: sched_config.c:415
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:668
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
ABTI_initialized
ABT_bool ABTI_initialized(void)
Definition: global.c:187
ABT_ERR_MIGRATION_TARGET
#define ABT_ERR_MIGRATION_TARGET
Error code: error related to a migration target.
Definition: abt.h:370
ABTI_sched::pools
ABT_pool * pools
Definition: abti.h:328
ABT_SCHED_BASIC
@ ABT_SCHED_BASIC
Definition: abt.h:479
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:1509
ABTU_ret_err
#define ABTU_ret_err
Definition: abtu.h:155
ABTI_sched::kind
ABTI_sched_kind kind
Definition: abti.h:322
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:291
ABTI_SCHED_MAIN
@ ABTI_SCHED_MAIN
Definition: abti.h:72
ABT_TRUE
#define ABT_TRUE
True constant for ABT_bool.
Definition: abt.h:784
ABT_SCHED_NULL
#define ABT_SCHED_NULL
Definition: abt.h:1100
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:327
ABT_POOL_ACCESS_SPMC
@ ABT_POOL_ACCESS_SPMC
Definition: abt.h:573
ABTI_sched
Definition: abti.h:319
ABT_FALSE
#define ABT_FALSE
False constant for ABT_bool.
Definition: abt.h:786
ABTI_sched_kind
uintptr_t ABTI_sched_kind
Definition: abti.h:140
ABT_sched_def::free
ABT_sched_free_fn free
Function that frees a scheduler.
Definition: abt.h:1492
ABTI_pool::access
ABT_pool_access access
Definition: abti.h:390
ABT_sched_set_data
int ABT_sched_set_data(ABT_sched sched, void *data)
Associate a user value with a scheduler.
Definition: sched.c:522
ABTI_UB_ASSERT
#define ABTI_UB_ASSERT(cond)
Definition: abti_error.h:19
ABT_ERR_INV_ARG
#define ABT_ERR_INV_ARG
Error code: invalid user argument.
Definition: abt.h:260
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:565
ABTU_free
static void ABTU_free(void *ptr)
Definition: abtu.h:228
ABTI_sched_has_to_stop
ABT_bool ABTI_sched_has_to_stop(ABTI_sched *p_sched)
Definition: sched.c:925
ABT_sched_def
A struct that defines a scheduler.
Definition: abt.h:1411
ABT_SCHED_BASIC_WAIT
@ ABT_SCHED_BASIC_WAIT
Definition: abt.h:489
ABT_SCHED_RANDWS
@ ABT_SCHED_RANDWS
Definition: abt.h:487
ABTI_ythread::thread
ABTI_thread thread
Definition: abti.h:457
ABTI_local
struct ABTI_local ABTI_local
Definition: abti.h:132
ABTI_sched_finish
void ABTI_sched_finish(ABTI_sched *p_sched)
Definition: sched.c:700
ABTI_pool_print
void ABTI_pool_print(ABTI_pool *p_pool, FILE *p_os, int indent)
Definition: pool.c:1459
ABTI_pool_is_empty
static ABT_bool ABTI_pool_is_empty(ABTI_pool *p_pool)
Definition: abti_pool.h:136
ABTI_CHECK_TRUE
#define ABTI_CHECK_TRUE(cond, abt_errno)
Definition: abti_error.h:146
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:482
ABTI_global
Definition: abti.h:223
ABT_sched_def::init
ABT_sched_init_fn init
Function that initializes a scheduler.
Definition: abt.h:1436
ABT_sched_free
int ABT_sched_free(ABT_sched *sched)
Free a scheduler.
Definition: sched.c:245
ABTI_pool::optional_def
ABTI_pool_optional_def optional_def
Definition: abti.h:400
ABTI_pool_release
static int32_t ABTI_pool_release(ABTI_pool *p_pool)
Definition: abti_pool.h:130
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:339
ABTI_pool_retain
static void ABTI_pool_retain(ABTI_pool *p_pool)
Definition: abti_pool.h:123
ABT_pool_kind
ABT_pool_kind
Predefined pool type.
Definition: abt.h:514
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:556
ABTI_pool::num_scheds
ABTD_atomic_int32 num_scheds
Definition: abti.h:394
ABTI_SCHED_REQ_FINISH
#define ABTI_SCHED_REQ_FINISH
Definition: abti.h:44
ABTI_pool_get_handle
static ABT_pool ABTI_pool_get_handle(ABTI_pool *p_pool)
Definition: abti_pool.h:26
ABTI_sched_config_get_ptr
static ABTI_sched_config * ABTI_sched_config_get_ptr(ABT_sched_config config)
Definition: abti_sched_config.h:12
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:1351
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:603
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:483
ABT_pool_access
ABT_pool_access
Pool access type.
Definition: abt.h:556
ABTI_sched_exit
void ABTI_sched_exit(ABTI_sched *p_sched)
Definition: sched.c:705