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); }
size_t ABTI_sched_get_size(ABTI_sched *p_sched) { size_t pool_size = 0; int p; for (p = 0; p < p_sched->num_pools; p++) { size_t s; ABT_pool pool = p_sched->pools[p]; ABT_pool_get_size(pool, &s); pool_size += s; } return pool_size; }
static ABT_bool verify_exec_order(int es_id, int my_prio) { if (my_prio == 0) return ABT_TRUE; ABT_pool *my_pools = g_data.pools[es_id]; size_t pool_size; int i, ret; for (i = 0; i < my_prio; i++) { ret = ABT_pool_get_size(my_pools[i], &pool_size); ABT_TEST_ERROR(ret, "ABT_pool_get_size"); if (pool_size > 0) return ABT_FALSE; } return ABT_TRUE; }
int main(int argc, char *argv[]) { int i, j; int ntasks; int start, end; int num_xstreams; ABT_xstream *xstreams; vector_scal_task_args_t *args; struct timeval t_start, t_end, t_end2; char *str, *endptr; float *a; num_xstreams = argc > 1 ? atoi(argv[1]) : NUM_XSTREAMS; if (argc > 2) { str = argv[2]; } ntasks = argc > 2 ? strtoll(str, &endptr, 10) : NUM_TASKS; if (ntasks < num_xstreams) { ntasks = num_xstreams; } printf("# of ESs: %d\n", num_xstreams); xstreams = (ABT_xstream *)malloc(sizeof(ABT_xstream) * num_xstreams); args = (vector_scal_task_args_t *)malloc(sizeof(vector_scal_task_args_t) * num_xstreams); g_pools = (ABT_pool *)malloc(sizeof(ABT_pool) * num_xstreams); a = malloc(sizeof(float) * ntasks); for (i = 0; i < ntasks; i++) { a[i] = i + 100.0f; } /* initialization */ ABT_init(argc, argv); for (i = 0; i < num_xstreams; i++) { ABT_pool_create_basic(ABT_POOL_FIFO, ABT_POOL_ACCESS_MPMC, ABT_TRUE, &g_pools[i]); } /* ES creation */ ABT_xstream_self(&xstreams[0]); ABT_xstream_set_main_sched_basic(xstreams[0], ABT_SCHED_DEFAULT, 1, &g_pools[0]); for (i = 1; i < num_xstreams; i++) { ABT_xstream_create_basic(ABT_SCHED_DEFAULT, 1, &g_pools[i], ABT_SCHED_CONFIG_NULL, &xstreams[i]); ABT_xstream_start(xstreams[i]); } /* Work here */ start = end = 0; int bloc = ntasks / num_xstreams; int rest = ntasks % num_xstreams; gettimeofday(&t_start, NULL); for (j = 0; j < num_xstreams; j++) { start = end; end = start + bloc; if (j < rest) { end++; } args[j].ptr = a; args[j].value = 0.9f; args[j].start = start; args[j].end = end; args[j].id = j; ABT_thread_create_on_xstream(xstreams[j], task_creator, (void *)&args[j], ABT_THREAD_ATTR_NULL, NULL); } gettimeofday(&t_end2, NULL); for (i = 0; i < num_xstreams; i++) { size_t size; do { ABT_thread_yield(); ABT_pool_get_size(g_pools[i], &size); } while (size != 0); } gettimeofday(&t_end, NULL); for (i = 0; i < ntasks; i++) { if (a[i] != (i + 100.0f) * 0.9f) { printf("error: a[%d]\n", i); } } double time = (t_end.tv_sec * 1000000 + t_end.tv_usec) - (t_start.tv_sec * 1000000 + t_start.tv_usec); double time2 = (t_end2.tv_sec * 1000000 + t_end2.tv_usec) - (t_start.tv_sec * 1000000 + t_start.tv_usec); printf("nxstreams: %d\nntasks %d\nTime(s): %f\n", num_xstreams, ntasks, time / 1000000.0); /* join ESs */ for (i = 1; i < num_xstreams; i++) { ABT_xstream_join(xstreams[i]); ABT_xstream_free(&xstreams[i]); } printf("Creation time=%f\n", time2 / 1000000.0); ABT_finalize(); free(xstreams); return EXIT_SUCCESS; }