ARGOBOTS  c6511494322293e01714f56f341b8d2b22c1e3c1
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
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, ABT_sched_config config,
10  ABT_bool automatic,
11  ABTI_sched **pp_newsched);
12 static inline ABTI_sched_kind sched_get_kind(ABT_sched_def *def);
13 #ifdef ABT_CONFIG_USE_DEBUG_LOG
14 static inline uint64_t sched_get_new_id(void);
15 #endif
16 
41 int ABT_sched_create(ABT_sched_def *def, int num_pools, ABT_pool *pools,
42  ABT_sched_config config, ABT_sched *newsched)
43 {
44  ABTI_sched *p_sched;
45  ABTI_CHECK_TRUE(newsched != NULL, ABT_ERR_SCHED);
46 
47  /* TODO: the default value of automatic is different from
48  * ABT_sched_create_basic(). Make it consistent. */
49  const ABT_bool def_automatic = ABT_FALSE;
50  int abt_errno =
51  sched_create(def, num_pools, pools, config, def_automatic, &p_sched);
52  ABTI_CHECK_ERROR(abt_errno);
53 
54  /* Return value */
55  *newsched = ABTI_sched_get_handle(p_sched);
56  return ABT_SUCCESS;
57 }
58 
90 int ABT_sched_create_basic(ABT_sched_predef predef, int num_pools,
91  ABT_pool *pools, ABT_sched_config config,
92  ABT_sched *newsched)
93 {
94  ABTI_sched *p_newsched;
95  int abt_errno =
96  ABTI_sched_create_basic(predef, num_pools, pools, config, &p_newsched);
97  ABTI_CHECK_ERROR(abt_errno);
98  *newsched = ABTI_sched_get_handle(p_newsched);
99  return ABT_SUCCESS;
100 }
101 
117 {
118  ABTI_local *p_local = ABTI_local_get_local();
119  ABTI_sched *p_sched = ABTI_sched_get_ptr(*sched);
120  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
121  ABTI_CHECK_TRUE(p_sched->used == ABTI_SCHED_NOT_USED, ABT_ERR_SCHED);
122 
123  /* Free the scheduler */
124  ABTI_sched_free(p_local, p_sched, ABT_FALSE);
125 
126  /* Return value */
127  *sched = ABT_SCHED_NULL;
128  return ABT_SUCCESS;
129 }
130 
144 int ABT_sched_get_num_pools(ABT_sched sched, int *num_pools)
145 {
146  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
147  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
148 
149  *num_pools = p_sched->num_pools;
150  return ABT_SUCCESS;
151 }
152 
164 int ABT_sched_get_pools(ABT_sched sched, int max_pools, int idx,
165  ABT_pool *pools)
166 {
167  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
168  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
169  ABTI_CHECK_TRUE(idx + max_pools <= p_sched->num_pools, ABT_ERR_SCHED);
170 
171  int p;
172  for (p = idx; p < idx + max_pools; p++) {
173  pools[p - idx] = p_sched->pools[p];
174  }
175  return ABT_SUCCESS;
176 }
177 
189 {
190  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
191  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
192 
193  ABTI_sched_finish(p_sched);
194  return ABT_SUCCESS;
195 }
196 
210 {
211  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
212  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
213 
214  ABTI_sched_exit(p_sched);
215  return ABT_SUCCESS;
216 }
217 
236 {
237  ABTI_local *p_local = ABTI_local_get_local();
238  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
239  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
240 
241  *stop = ABTI_sched_has_to_stop(&p_local, p_sched);
242  return ABT_SUCCESS;
243 }
244 
257 int ABT_sched_set_data(ABT_sched sched, void *data)
258 {
259  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
260  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
261 
262  p_sched->data = data;
263  return ABT_SUCCESS;
264 }
265 
278 int ABT_sched_get_data(ABT_sched sched, void **data)
279 {
280  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
281  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
282 
283  *data = p_sched->data;
284  return ABT_SUCCESS;
285 }
286 
298 int ABT_sched_get_size(ABT_sched sched, size_t *size)
299 {
300  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
301  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
302 
303  *size = ABTI_sched_get_size(p_sched);
304  return ABT_SUCCESS;
305 }
306 
307 size_t ABTI_sched_get_size(ABTI_sched *p_sched)
308 {
309  size_t pool_size = 0;
310  int p;
311 
312  for (p = 0; p < p_sched->num_pools; p++) {
313  ABTI_pool *p_pool = ABTI_pool_get_ptr(p_sched->pools[p]);
314  pool_size += ABTI_pool_get_size(p_pool);
315  }
316 
317  return pool_size;
318 }
319 
331 int ABT_sched_get_total_size(ABT_sched sched, size_t *size)
332 {
333  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
334  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
335 
336  *size = ABTI_sched_get_total_size(p_sched);
337  return ABT_SUCCESS;
338 }
339 
340 /*****************************************************************************/
341 /* Private APIs */
342 /*****************************************************************************/
343 
344 void ABTI_sched_finish(ABTI_sched *p_sched)
345 {
346  ABTI_sched_set_request(p_sched, ABTI_SCHED_REQ_FINISH);
347 }
348 
349 void ABTI_sched_exit(ABTI_sched *p_sched)
350 {
351  ABTI_sched_set_request(p_sched, ABTI_SCHED_REQ_EXIT);
352 }
353 
354 ABTU_ret_err int ABTI_sched_create_basic(ABT_sched_predef predef, int num_pools,
355  ABT_pool *pools,
356  ABT_sched_config config,
357  ABTI_sched **pp_newsched)
358 {
359  int abt_errno;
360  ABT_pool_access access;
362  ABT_bool automatic;
363 
364  ABTI_CHECK_TRUE(!pools || num_pools > 0, ABT_ERR_SCHED);
365 
366  /* We set the access to the default one */
367  access = ABT_POOL_ACCESS_MPSC;
368  /* TODO: the default value is different from ABT_sched_create().
369  * Make it consistent. */
370  automatic = ABT_TRUE;
371  /* We read the config and set the configured parameters */
372  abt_errno = ABTI_sched_config_read_global(config, &access, &automatic);
373  ABTI_CHECK_ERROR(abt_errno);
374 
375  /* A pool array is provided, predef has to be compatible */
376  if (pools != NULL) {
377  /* Copy of the contents of pools */
378  ABT_pool *pool_list;
379  abt_errno =
380  ABTU_malloc(num_pools * sizeof(ABT_pool), (void **)&pool_list);
381  ABTI_CHECK_ERROR(abt_errno);
382 
383  int p;
384  for (p = 0; p < num_pools; p++) {
385  if (pools[p] == ABT_POOL_NULL) {
386  ABTI_pool *p_newpool;
387  abt_errno = ABTI_pool_create_basic(ABT_POOL_FIFO, access,
388  ABT_TRUE, &p_newpool);
389  ABTI_CHECK_ERROR(abt_errno);
390  pool_list[p] = ABTI_pool_get_handle(p_newpool);
391  } else {
392  pool_list[p] = pools[p];
393  }
394  }
395 
396  /* Creation of the scheduler */
397  switch (predef) {
398  case ABT_SCHED_DEFAULT:
399  case ABT_SCHED_BASIC:
400  abt_errno = sched_create(ABTI_sched_get_basic_def(), num_pools,
401  pool_list, ABT_SCHED_CONFIG_NULL,
402  automatic, pp_newsched);
403  break;
405  abt_errno =
406  sched_create(ABTI_sched_get_basic_wait_def(), num_pools,
407  pool_list, ABT_SCHED_CONFIG_NULL, automatic,
408  pp_newsched);
409  break;
410  case ABT_SCHED_PRIO:
411  abt_errno = sched_create(ABTI_sched_get_prio_def(), num_pools,
412  pool_list, ABT_SCHED_CONFIG_NULL,
413  automatic, pp_newsched);
414  break;
415  case ABT_SCHED_RANDWS:
416  abt_errno = sched_create(ABTI_sched_get_randws_def(), num_pools,
417  pool_list, ABT_SCHED_CONFIG_NULL,
418  automatic, pp_newsched);
419  break;
420  default:
421  abt_errno = ABT_ERR_INV_SCHED_PREDEF;
422  break;
423  }
424  ABTI_CHECK_ERROR(abt_errno);
425  ABTU_free(pool_list);
426  }
427 
428  /* No pool array is provided, predef has to be compatible */
429  else {
430  /* Set the number of pools */
431  switch (predef) {
432  case ABT_SCHED_DEFAULT:
433  case ABT_SCHED_BASIC:
434  num_pools = 1;
435  break;
437  /* FIFO_WAIT is default pool for use with BASIC_WAIT sched */
438  kind = ABT_POOL_FIFO_WAIT;
439  num_pools = 1;
440  break;
441  case ABT_SCHED_PRIO:
442  num_pools = ABTI_SCHED_NUM_PRIO;
443  break;
444  case ABT_SCHED_RANDWS:
445  num_pools = 1;
446  break;
447  default:
448  abt_errno = ABT_ERR_INV_SCHED_PREDEF;
449  ABTI_CHECK_ERROR(abt_errno);
450  break;
451  }
452 
453  /* Creation of the pools */
454  /* To avoid the malloc overhead, we use a stack array. */
455  ABT_pool pool_list[ABTI_SCHED_NUM_PRIO];
456  int p;
457  for (p = 0; p < num_pools; p++) {
458  ABTI_pool *p_newpool;
459  abt_errno =
460  ABTI_pool_create_basic(kind, access, ABT_TRUE, &p_newpool);
461  ABTI_CHECK_ERROR(abt_errno);
462  pool_list[p] = ABTI_pool_get_handle(p_newpool);
463  }
464 
465  /* Creation of the scheduler */
466  switch (predef) {
467  case ABT_SCHED_DEFAULT:
468  case ABT_SCHED_BASIC:
469  abt_errno =
470  sched_create(ABTI_sched_get_basic_def(), num_pools,
471  pool_list, config, automatic, pp_newsched);
472  break;
474  abt_errno =
475  sched_create(ABTI_sched_get_basic_wait_def(), num_pools,
476  pool_list, config, automatic, pp_newsched);
477  break;
478  case ABT_SCHED_PRIO:
479  abt_errno =
480  sched_create(ABTI_sched_get_prio_def(), num_pools,
481  pool_list, config, automatic, pp_newsched);
482  break;
483  case ABT_SCHED_RANDWS:
484  abt_errno =
485  sched_create(ABTI_sched_get_randws_def(), num_pools,
486  pool_list, config, automatic, pp_newsched);
487  break;
488  default:
489  abt_errno = ABT_ERR_INV_SCHED_PREDEF;
490  break;
491  }
492  ABTI_CHECK_ERROR(abt_errno);
493  }
494  return ABT_SUCCESS;
495 }
496 
497 void ABTI_sched_free(ABTI_local *p_local, ABTI_sched *p_sched,
498  ABT_bool force_free)
499 {
500  ABTI_ASSERT(p_sched->used == ABTI_SCHED_NOT_USED);
501  /* If sched is a default provided one, it should free its pool here.
502  * Otherwise, freeing the pool is the user's responsibility. */
503  int p;
504  for (p = 0; p < p_sched->num_pools; p++) {
505  ABTI_pool *p_pool = ABTI_pool_get_ptr(p_sched->pools[p]);
506  int32_t num_scheds = ABTI_pool_release(p_pool);
507  if ((p_pool->automatic == ABT_TRUE && num_scheds == 0) || force_free) {
508  ABTI_pool_free(p_pool);
509  }
510  }
511  ABTU_free(p_sched->pools);
512 
513  /* Free the associated work unit */
514  if (p_sched->p_ythread) {
515  ABTI_thread_free(p_local, &p_sched->p_ythread->thread);
516  }
517 
518  LOG_DEBUG("[S%" PRIu64 "] freed\n", p_sched->id);
519 
520  p_sched->free(ABTI_sched_get_handle(p_sched));
521  p_sched->data = NULL;
522 
523  ABTU_free(p_sched);
524 }
525 
526 ABT_bool ABTI_sched_has_to_stop(ABTI_local **pp_local, ABTI_sched *p_sched)
527 {
528  /* Check exit request */
529  if (ABTD_atomic_acquire_load_uint32(&p_sched->request) &
530  ABTI_SCHED_REQ_EXIT) {
531  return ABT_TRUE;
532  }
533 
534  if (ABTI_sched_get_effective_size(*pp_local, p_sched) == 0) {
535  if (ABTD_atomic_acquire_load_uint32(&p_sched->request) &
536  ABTI_SCHED_REQ_FINISH) {
537  /* Check join request */
538  if (ABTI_sched_get_effective_size(*pp_local, p_sched) == 0)
539  return ABT_TRUE;
540  } else if (p_sched->used == ABTI_SCHED_IN_POOL) {
541  /* If the scheduler is a stacked one, we have to escape from the
542  * scheduling function. The scheduler will be stopped if it is a
543  * tasklet type. However, if the scheduler is a ULT type, we
544  * context switch to the parent scheduler. */
545  if (p_sched->type == ABT_SCHED_TYPE_TASK)
546  return ABT_TRUE;
547  /* If the current caller cannot yield, let's finish it */
548  ABTI_xstream *p_local_xstream =
549  ABTI_local_get_xstream_or_null(*pp_local);
550  if (ABTI_IS_EXT_THREAD_ENABLED && p_local_xstream == NULL)
551  return ABT_TRUE;
552  /* If the current caller is not the scheduler, let's finish. */
553  if (&p_sched->p_ythread->thread != p_local_xstream->p_thread)
554  return ABT_TRUE;
555  /* Yield this scheduler. */
556  ABTI_ythread_context_switch_to_parent(&p_local_xstream,
557  p_sched->p_ythread,
559  NULL);
560  *pp_local = ABTI_xstream_get_local(p_local_xstream);
561  }
562  }
563  return ABT_FALSE;
564 }
565 
566 /* Get the pool suitable for receiving a migrating ULT */
567 ABTU_ret_err int ABTI_sched_get_migration_pool(ABTI_sched *p_sched,
568  ABTI_pool *source_pool,
569  ABTI_pool **pp_pool)
570 {
571  ABT_sched sched = ABTI_sched_get_handle(p_sched);
572 
573  /* Find a pool. If get_migr_pool is not defined, we pick the first pool */
574  if (p_sched->get_migr_pool == NULL) {
575  *pp_pool = ABTI_pool_get_ptr(p_sched->pools[0]);
576  } else {
577  ABTI_pool *p_pool = ABTI_pool_get_ptr(p_sched->get_migr_pool(sched));
578  if (ABTI_IS_ERROR_CHECK_ENABLED && p_pool == NULL) {
579  return ABT_ERR_SCHED;
580  }
581  *pp_pool = p_pool;
582  }
583  return ABT_SUCCESS;
584 }
585 
586 size_t ABTI_sched_get_total_size(ABTI_sched *p_sched)
587 {
588  size_t pool_size = 0;
589  int p;
590 
591  for (p = 0; p < p_sched->num_pools; p++) {
592  ABTI_pool *p_pool = ABTI_pool_get_ptr(p_sched->pools[p]);
593  pool_size += ABTI_pool_get_total_size(p_pool);
594  }
595 
596  return pool_size;
597 }
598 
599 /* Compared to \c ABTI_sched_get_total_size, ABTI_sched_get_effective_size does
600  * not count the number of blocked ULTs if a pool has more than one consumer or
601  * the caller ES is not the latest consumer. This is necessary when the ES
602  * associated with the target scheduler has to be joined and the pool is shared
603  * between different schedulers associated with different ESs. */
604 size_t ABTI_sched_get_effective_size(ABTI_local *p_local, ABTI_sched *p_sched)
605 {
606  size_t pool_size = 0;
607  int p;
608 
609  for (p = 0; p < p_sched->num_pools; p++) {
610  ABT_pool pool = p_sched->pools[p];
611  ABTI_pool *p_pool = ABTI_pool_get_ptr(pool);
612  pool_size += ABTI_pool_get_size(p_pool);
613  pool_size += ABTD_atomic_acquire_load_int32(&p_pool->num_migrations);
614  switch (p_pool->access) {
616  pool_size +=
617  ABTD_atomic_acquire_load_int32(&p_pool->num_blocked);
618  break;
623  if (ABTD_atomic_acquire_load_int32(&p_pool->num_scheds) == 1) {
624  pool_size +=
625  ABTD_atomic_acquire_load_int32(&p_pool->num_blocked);
626  }
627  break;
628  default:
629  break;
630  }
631  }
632 
633  return pool_size;
634 }
635 
636 void ABTI_sched_print(ABTI_sched *p_sched, FILE *p_os, int indent,
637  ABT_bool print_sub)
638 {
639  if (p_sched == NULL) {
640  fprintf(p_os, "%*s== NULL SCHED ==\n", indent, "");
641  } else {
642  ABTI_sched_kind kind;
643  const char *kind_str, *type, *used;
644 
645  kind = p_sched->kind;
646  if (kind == sched_get_kind(ABTI_sched_get_basic_def())) {
647  kind_str = "BASIC";
648  } else if (kind == sched_get_kind(ABTI_sched_get_basic_wait_def())) {
649  kind_str = "BASIC_WAIT";
650  } else if (kind == sched_get_kind(ABTI_sched_get_prio_def())) {
651  kind_str = "PRIO";
652  } else {
653  kind_str = "USER";
654  }
655 
656  switch (p_sched->type) {
657  case ABT_SCHED_TYPE_ULT:
658  type = "ULT";
659  break;
660  case ABT_SCHED_TYPE_TASK:
661  type = "TASKLET";
662  break;
663  default:
664  type = "UNKNOWN";
665  break;
666  }
667  switch (p_sched->used) {
668  case ABTI_SCHED_NOT_USED:
669  used = "NOT_USED";
670  break;
671  case ABTI_SCHED_MAIN:
672  used = "MAIN";
673  break;
674  case ABTI_SCHED_IN_POOL:
675  used = "IN_POOL";
676  break;
677  default:
678  used = "UNKNOWN";
679  break;
680  }
681 
682  fprintf(p_os,
683  "%*s== SCHED (%p) ==\n"
684 #ifdef ABT_CONFIG_USE_DEBUG_LOG
685  "%*sid : %" PRIu64 "\n"
686 #endif
687  "%*skind : %" PRIxPTR " (%s)\n"
688  "%*stype : %s\n"
689  "%*sused : %s\n"
690  "%*sautomatic: %s\n"
691  "%*srequest : 0x%x\n"
692  "%*snum_pools: %d\n"
693  "%*ssize : %zu\n"
694  "%*stot_size : %zu\n"
695  "%*sdata : %p\n",
696  indent, "", (void *)p_sched,
697 #ifdef ABT_CONFIG_USE_DEBUG_LOG
698  indent, "", p_sched->id,
699 #endif
700  indent, "", p_sched->kind, kind_str, indent, "", type, indent,
701  "", used, indent, "",
702  (p_sched->automatic == ABT_TRUE) ? "TRUE" : "FALSE", indent, "",
703  ABTD_atomic_acquire_load_uint32(&p_sched->request), indent, "",
704  p_sched->num_pools, indent, "", ABTI_sched_get_size(p_sched),
705  indent, "", ABTI_sched_get_total_size(p_sched), indent, "",
706  p_sched->data);
707  if (print_sub == ABT_TRUE) {
708  int i;
709  for (i = 0; i < p_sched->num_pools; i++) {
710  ABTI_pool *p_pool = ABTI_pool_get_ptr(p_sched->pools[i]);
711  ABTI_pool_print(p_pool, p_os, indent + 2);
712  }
713  }
714  }
715  fflush(p_os);
716 }
717 
718 static ABTD_atomic_uint64 g_sched_id = ABTD_ATOMIC_UINT64_STATIC_INITIALIZER(0);
719 void ABTI_sched_reset_id(void)
720 {
721  ABTD_atomic_relaxed_store_uint64(&g_sched_id, 0);
722 }
723 
724 /*****************************************************************************/
725 /* Internal static functions */
726 /*****************************************************************************/
727 
728 static inline ABTI_sched_kind sched_get_kind(ABT_sched_def *def)
729 {
730  return (ABTI_sched_kind)def;
731 }
732 
733 ABTU_ret_err static int sched_create(ABT_sched_def *def, int num_pools,
734  ABT_pool *pools, ABT_sched_config config,
735  ABT_bool automatic,
736  ABTI_sched **pp_newsched)
737 {
738  ABTI_sched *p_sched;
739  int p, abt_errno;
740 
741  abt_errno = ABTU_malloc(sizeof(ABTI_sched), (void **)&p_sched);
742  ABTI_CHECK_ERROR(abt_errno);
743 
744  /* Copy of the contents of pools */
745  ABT_pool *pool_list;
746  abt_errno = ABTU_malloc(num_pools * sizeof(ABT_pool), (void **)&pool_list);
747  if (ABTI_IS_ERROR_CHECK_ENABLED && abt_errno != ABT_SUCCESS) {
748  ABTU_free(p_sched);
749  return abt_errno;
750  }
751  for (p = 0; p < num_pools; p++) {
752  if (pools[p] == ABT_POOL_NULL) {
753  ABTI_pool *p_newpool;
754  abt_errno =
755  ABTI_pool_create_basic(ABT_POOL_FIFO, ABT_POOL_ACCESS_MPSC,
756  ABT_TRUE, &p_newpool);
757  if (ABTI_IS_ERROR_CHECK_ENABLED && abt_errno != ABT_SUCCESS) {
758  int i;
759  for (i = 0; i < p; i++) {
760  if (pools[i] == ABT_POOL_NULL)
761  ABTI_pool_free(ABTI_pool_get_ptr(pool_list[i]));
762  }
763  ABTU_free(pool_list);
764  ABTU_free(p_sched);
765  return abt_errno;
766  }
767  pool_list[p] = ABTI_pool_get_handle(p_newpool);
768  } else {
769  pool_list[p] = pools[p];
770  }
771  }
772  /* Check if the pools are available */
773  for (p = 0; p < num_pools; p++) {
774  ABTI_pool_retain(ABTI_pool_get_ptr(pool_list[p]));
775  }
776 
777  p_sched->used = ABTI_SCHED_NOT_USED;
778  p_sched->automatic = automatic;
779  p_sched->kind = sched_get_kind(def);
780  ABTD_atomic_relaxed_store_uint32(&p_sched->request, 0);
781  p_sched->pools = pool_list;
782  p_sched->num_pools = num_pools;
783  p_sched->type = def->type;
784  p_sched->p_ythread = NULL;
785  p_sched->data = NULL;
786 
787  p_sched->init = def->init;
788  p_sched->run = def->run;
789  p_sched->free = def->free;
790  p_sched->get_migr_pool = def->get_migr_pool;
791 
792 #ifdef ABT_CONFIG_USE_DEBUG_LOG
793  p_sched->id = sched_get_new_id();
794 #endif
795  LOG_DEBUG("[S%" PRIu64 "] created\n", p_sched->id);
796 
797  /* Return value */
798  ABT_sched newsched = ABTI_sched_get_handle(p_sched);
799 
800  /* Specific initialization */
801  abt_errno = p_sched->init(newsched, config);
802  if (ABTI_IS_ERROR_CHECK_ENABLED && abt_errno != ABT_SUCCESS) {
803  for (p = 0; p < num_pools; p++) {
804  if (pools[p] == ABT_POOL_NULL) {
805  ABTI_pool_free(ABTI_pool_get_ptr(pool_list[p]));
806  } else {
807  ABTI_pool_release(ABTI_pool_get_ptr(pool_list[p]));
808  }
809  }
810  ABTU_free(pool_list);
811  ABTU_free(p_sched);
812  return abt_errno;
813  }
814 
815  *pp_newsched = p_sched;
816 
817  return ABT_SUCCESS;
818 }
819 
820 #ifdef ABT_CONFIG_USE_DEBUG_LOG
821 static inline uint64_t sched_get_new_id(void)
822 {
823  return ABTD_atomic_fetch_add_uint64(&g_sched_id, 1);
824 }
825 #endif
ABT_sched_free_fn free
Definition: abt.h:465
int ABT_sched_get_size(ABT_sched sched, size_t *size) ABT_API_PUBLIC
Get the sum of the sizes of the pool of sched.
Definition: sched.c:298
#define ABT_POOL_NULL
Definition: abt.h:413
ABT_sched_predef
Definition: abt.h:143
struct ABT_sched_opaque * ABT_sched
Definition: abt.h:319
int ABT_sched_finish(ABT_sched sched) ABT_API_PUBLIC
Ask a scheduler to finish.
Definition: sched.c:188
static ABTU_ret_err int sched_create(ABT_sched_def *def, int num_pools, ABT_pool *pools, ABT_sched_config config, ABT_bool automatic, ABTI_sched **pp_newsched)
Definition: sched.c:733
ABT_sched_init_fn init
Definition: abt.h:463
int ABT_bool
Definition: abt.h:373
int ABT_sched_create(ABT_sched_def *def, int num_pools, ABT_pool *pools, ABT_sched_config config, ABT_sched *newsched) ABT_API_PUBLIC
Create a new user-defined scheduler and return its handle through newsched.
Definition: sched.c:41
static ABTI_sched_kind sched_get_kind(ABT_sched_def *def)
Definition: sched.c:728
#define ABT_ERR_SCHED
Definition: abt.h:97
struct ABT_pool_opaque * ABT_pool
Definition: abt.h:329
int ABT_sched_exit(ABT_sched sched) ABT_API_PUBLIC
Ask a scheduler to stop as soon as possible.
Definition: sched.c:209
static ABTU_ret_err int ABTU_malloc(size_t size, void **p_ptr)
Definition: abtu.h:129
#define ABT_FALSE
Definition: abt.h:285
int ABT_sched_get_num_pools(ABT_sched sched, int *num_pools) ABT_API_PUBLIC
Get the number of pools associated with scheduler.
Definition: sched.c:144
int ABT_sched_get_total_size(ABT_sched sched, size_t *size) ABT_API_PUBLIC
Get the sum of the sizes of the pool of sched.
Definition: sched.c:331
#define ABT_SUCCESS
Definition: abt.h:64
int ABT_sched_free(ABT_sched *sched) ABT_API_PUBLIC
Release the scheduler object associated with sched handle.
Definition: sched.c:116
ABT_pool_access
Definition: abt.h:161
#define ABT_TRUE
Definition: abt.h:284
#define ABT_SCHED_NULL
Definition: abt.h:411
ABT_sched_type type
Definition: abt.h:460
ABT_pool_kind
Definition: abt.h:156
int ABT_sched_get_data(ABT_sched sched, void **data) ABT_API_PUBLIC
Retrieve the specific data of the target user-defined scheduler.
Definition: sched.c:278
int ABT_sched_get_pools(ABT_sched sched, int max_pools, int idx, ABT_pool *pools) ABT_API_PUBLIC
Get the pools of the scheduler sched.
Definition: sched.c:164
int ABT_sched_create_basic(ABT_sched_predef predef, int num_pools, ABT_pool *pools, ABT_sched_config config, ABT_sched *newsched) ABT_API_PUBLIC
Create a predefined scheduler.
Definition: sched.c:90
static ABTD_atomic_uint64 g_sched_id
Definition: sched.c:718
#define LOG_DEBUG(fmt,...)
Definition: abti_log.h:26
struct ABT_sched_config_opaque * ABT_sched_config
Definition: abt.h:321
ABT_sched_get_migr_pool_fn get_migr_pool
Definition: abt.h:466
#define ABT_SCHED_CONFIG_NULL
Definition: abt.h:412
ABT_sched_run_fn run
Definition: abt.h:464
int ABT_sched_set_data(ABT_sched sched, void *data) ABT_API_PUBLIC
Set the specific data of the target user-defined scheduler.
Definition: sched.c:257
static void ABTU_free(void *ptr)
Definition: abtu.h:122
int ABT_sched_has_to_stop(ABT_sched sched, ABT_bool *stop) ABT_API_PUBLIC
Check if the scheduler needs to stop.
Definition: sched.c:235
#define ABTU_ret_err
Definition: abtu.h:49
#define ABT_ERR_INV_SCHED_PREDEF
Definition: abt.h:73