static void sched_run(ABT_sched sched) { uint32_t work_count = 0; sched_data *p_data; int num_pools; ABT_pool *p_pools; ABT_unit unit; int target; unsigned seed = time(NULL); CNT_DECL(run_cnt); ABTI_xstream *p_xstream = ABTI_local_get_xstream(); ABTI_sched *p_sched = ABTI_sched_get_ptr(sched); ABT_sched_get_data(sched, (void **)&p_data); ABT_sched_get_num_pools(sched, &num_pools); p_pools = (ABT_pool *)ABTU_malloc(num_pools * sizeof(ABT_pool)); ABT_sched_get_pools(sched, num_pools, 0, p_pools); while (1) { CNT_INIT(run_cnt, 0); /* Execute one work unit from the scheduler's pool */ ABT_pool pool = p_pools[0]; ABTI_pool *p_pool = ABTI_pool_get_ptr(pool); size_t size = ABTI_pool_get_size(p_pool); if (size > 0) { unit = ABTI_pool_pop(p_pool); if (unit != ABT_UNIT_NULL) { ABTI_xstream_run_unit(p_xstream, unit, p_pool); CNT_INC(run_cnt); } } else if (num_pools > 1) { /* Steal a work unit from other pools */ target = (num_pools == 2) ? 1 : (rand_r(&seed) % (num_pools-1) + 1); pool = p_pools[target]; p_pool = ABTI_pool_get_ptr(pool); size = ABTI_pool_get_size(p_pool); if (size > 0) { unit = ABTI_pool_pop(p_pool); LOG_EVENT_POOL_POP(p_pool, unit); if (unit != ABT_UNIT_NULL) { ABT_unit_set_associated_pool(unit, pool); ABTI_xstream_run_unit(p_xstream, unit, p_pool); CNT_INC(run_cnt); } } } if (++work_count >= p_data->event_freq) { ABT_bool stop = ABTI_sched_has_to_stop(p_sched, p_xstream); if (stop == ABT_TRUE) break; work_count = 0; ABTI_xstream_check_events(p_xstream, sched); SCHED_SLEEP(run_cnt, p_data->sleep_time); } } ABTU_free(p_pools); }
int main(int argc, char *argv[]) { ABT_xstream xstreams[NUM_XSTREAMS]; ABT_sched scheds[NUM_XSTREAMS]; int num_pools[NUM_XSTREAMS]; ABT_pool *pools[NUM_XSTREAMS]; int i, k; ABT_init(argc, argv); /* Create schedulers */ for (i = 0; i < NUM_XSTREAMS; i++) { ABT_sched_predef predef; predef = (i % 2) ? ABT_SCHED_BASIC : ABT_SCHED_PRIO; ABT_sched_create_basic(predef, 0, NULL, ABT_SCHED_CONFIG_NULL, &scheds[i]); } /* Create ESs */ ABT_xstream_self(&xstreams[0]); ABT_xstream_set_main_sched(xstreams[0], scheds[0]); for (i = 1; i < NUM_XSTREAMS; i++) { ABT_xstream_create(scheds[i], &xstreams[i]); } /* Get the pools associated with each scheduler */ for (i = 0; i < NUM_XSTREAMS; i++) { ABT_sched_get_num_pools(scheds[i], &num_pools[i]); pools[i] = (ABT_pool *)malloc(num_pools[i] * sizeof(ABT_pool)); ABT_sched_get_pools(scheds[i], num_pools[i], 0, pools[i]); } /* Create ULTs */ for (i = 0; i < NUM_XSTREAMS; i++) { for (k = num_pools[i] - 1; k >= 0; k--) { size_t tid = (i + 1) * 10 + k; ABT_thread_create(pools[i][k], thread_hello, (void *)tid, ABT_THREAD_ATTR_NULL, NULL); } } /* Join & Free */ for (i = 1; i < NUM_XSTREAMS; i++) { ABT_xstream_join(xstreams[i]); ABT_xstream_free(&xstreams[i]); } for (i = 0; i < NUM_XSTREAMS; i++) { free(pools[i]); } ABT_finalize(); return 0; }
static void sched_run(ABT_sched sched) { uint32_t work_count = 0; void *data; sched_data_t *p_data; ABT_pool my_pool; size_t size; ABT_unit unit; uint32_t event_freq; int num_pools; ABT_pool *pools; ABT_sched_get_data(sched, &data); p_data = sched_data_get_ptr(data); event_freq = p_data->event_freq; ABT_sched_get_num_pools(sched, &num_pools); pools = (ABT_pool *)malloc(sizeof(ABT_pool) * num_pools); ABT_sched_get_pools(sched, num_pools, 0, pools); my_pool = pools[0]; while (1) { /* Execute one work unit from the scheduler's pool */ ABT_pool_pop(my_pool, &unit); if (unit != ABT_UNIT_NULL) { ABT_xstream_run_unit(unit, my_pool); } else if (num_pools > 1) { /* Steal a work unit from other pools */ int target = (num_pools == 2) ? 1 : (rand() % (num_pools - 1) + 1); ABT_pool tar_pool = pools[target]; ABT_pool_get_size(tar_pool, &size); if (size > 0) { /* Pop one work unit */ ABT_pool_pop(tar_pool, &unit); if (unit != ABT_UNIT_NULL) { ABT_xstream_run_unit(unit, tar_pool); } } } if (++work_count >= event_freq) { abt_check_events(p_data->idx); ABT_bool stop; ABT_sched_has_to_stop(sched, &stop); if (stop == ABT_TRUE) break; work_count = 0; ABT_xstream_check_events(sched); } } free(pools); }
static void sched_run(ABT_sched sched) { uint32_t work_count = 0; sched_data_t *p_data; ABT_pool my_pool; int num_pools; ABT_pool *pools; ABT_unit unit; int target; ABT_bool stop; unsigned seed = time(NULL); ABT_sched_get_data(sched, (void **)&p_data); ABT_sched_get_num_pools(sched, &num_pools); pools = (ABT_pool *)malloc(sizeof(ABT_pool) * num_pools); ABT_sched_get_pools(sched, num_pools, 0, pools); my_pool = pools[0]; while (1) { /* Execute one work unit from the scheduler's pool */ ABT_pool_pop(my_pool, &unit); if (unit != ABT_UNIT_NULL) { ABT_xstream_run_unit(unit, my_pool); } else if (num_pools > 1) { /* Steal a work unit from other pools */ target = (num_pools == 2) ? 1 : (rand_r(&seed) % (num_pools-1) + 1); ABT_pool_pop(pools[target], &unit); if (unit != ABT_UNIT_NULL) { ABT_xstream_run_unit(unit, pools[target]); } } if (++work_count >= p_data->event_freq) { work_count = 0; ABT_xstream_check_events(sched); ABT_sched_has_to_stop(sched, &stop); if (stop == ABT_TRUE) { /* TODO: Migrate work units if we have private pools */ break; } } } free(pools); }
static void create_scheds_and_xstreams(void) { int i, k, ret; int num_scheds = g_data.num_scheds; ABT_sched *scheds = g_data.scheds; int *num_pools = g_data.num_pools; ABT_pool **pools = g_data.pools; ABT_xstream *xstreams = g_data.xstreams; for (i = 0; i < num_scheds; i++) { if (i == num_scheds-1) { /* Create pools and then create a scheduler */ num_pools[i] = 2; pools[i] = (ABT_pool *)malloc(num_pools[i] * sizeof(ABT_pool)); pools[i][0] = ABT_POOL_NULL; for (k = 1; k < num_pools[i]; k++) { ret = ABT_pool_create_basic(ABT_POOL_FIFO, ABT_POOL_ACCESS_MPSC, ABT_TRUE, &pools[i][k]); ABT_TEST_ERROR(ret, "ABT_pool_create_basic"); } ret = ABT_sched_create_basic(ABT_SCHED_PRIO, num_pools[i], pools[i], ABT_SCHED_CONFIG_NULL, &scheds[i]); ABT_TEST_ERROR(ret, "ABT_sched_create_basic"); } else { /* Create a scheduler and then get the list of pools */ ABT_sched_config config; ret = ABT_sched_config_create(&config, ABT_sched_config_access, accesses[i], ABT_sched_config_var_end); ABT_TEST_ERROR(ret, "ABT_sched_config_create"); ret = ABT_sched_create_basic(ABT_SCHED_PRIO, 0, NULL, config, &scheds[i]); ABT_TEST_ERROR(ret, "ABT_sched_create_basic"); ret = ABT_sched_config_free(&config); ABT_TEST_ERROR(ret, "ABT_sched_config_free"); ret = ABT_sched_get_num_pools(scheds[i], &num_pools[i]); ABT_TEST_ERROR(ret, "ABT_sched_get_num_pools"); pools[i] = (ABT_pool *)malloc(num_pools[i] * sizeof(ABT_pool)); } ret = ABT_sched_get_pools(scheds[i], num_pools[i], 0, pools[i]); ABT_TEST_ERROR(ret, "ABT_sched_get_pools"); /* Create ES */ if (i == 0) { ret = ABT_xstream_self(&xstreams[i]); ABT_TEST_ERROR(ret, "ABT_xstream_self"); ret = ABT_xstream_set_main_sched(xstreams[i], scheds[i]); ABT_TEST_ERROR(ret, "ABT_xstream_set_main_sched"); } else { /* If the predefined scheduler is associated with PW pools, we will stack it so that the primary ULT can add the initial work unit. */ if (accesses[i] == ABT_POOL_ACCESS_PRIV || accesses[i] == ABT_POOL_ACCESS_SPSC || accesses[i] == ABT_POOL_ACCESS_SPMC) { ret = ABT_xstream_create(ABT_SCHED_NULL, &xstreams[i]); ABT_TEST_ERROR(ret, "ABT_xstream_create"); } else { ret = ABT_xstream_create(scheds[i], &xstreams[i]); ABT_TEST_ERROR(ret, "ABT_xstream_create"); } } } }