void thread_func(void *arg) { ABT_thread my_handle; ABT_thread_state my_state; ABT_thread_self(&my_handle); ABT_thread_get_state(my_handle, &my_state); if (my_state != ABT_THREAD_STATE_RUNNING) { fprintf(stderr, "ERROR: not in the RUNNUNG state\n"); } ABT_thread_release(my_handle); thread_arg_t *t_arg = (thread_arg_t *)arg; ABT_thread next; ABT_test_printf(1, "[TH%d]: before yield\n", t_arg->id); next = pick_one(t_arg->threads, t_arg->num_threads); ABT_thread_yield_to(next); ABT_test_printf(1, "[TH%d]: doing something ...\n", t_arg->id); next = pick_one(t_arg->threads, t_arg->num_threads); ABT_thread_yield_to(next); ABT_test_printf(1, "[TH%d]: after yield\n", t_arg->id); ABT_task task; ABT_task_self(&task); if (task != ABT_TASK_NULL) { fprintf(stderr, "ERROR: should not be tasklet\n"); } }
void thread_func(void *arg) { int ret; arg_t *my_arg = (arg_t *)arg; ABT_test_printf(3, "[U%d:E%d] %s\n", my_arg->tid, my_arg->eid, my_arg->op_type == OP_WAIT ? "wait" : "set"); if (my_arg->op_type == OP_WAIT) { if (my_arg->nbytes == 0) { ret = ABT_eventual_wait(my_arg->ev, NULL); } else { void *val; ret = ABT_eventual_wait(my_arg->ev, &val); assert(*(int *)val == 1); } ABT_TEST_ERROR(ret, "ABT_eventual_wait"); } else if (my_arg->op_type == OP_SET) { if (my_arg->nbytes == 0) { ret = ABT_eventual_set(my_arg->ev, NULL, 0); } else { int val = 1; ret = ABT_eventual_set(my_arg->ev, &val, sizeof(int)); } ABT_TEST_ERROR(ret, "ABT_eventual_set"); } ABT_test_printf(3, "[U%d:E%d] done\n", my_arg->tid, my_arg->eid); }
void fn3(void *args) { ABT_TEST_UNUSED(args); int i = 0; ABT_test_printf(1, "Thread 3 iteration %d signal eventual \n", i); char *data = (char *) malloc(EVENTUAL_SIZE); ABT_eventual_set(myeventual, data, EVENTUAL_SIZE); ABT_test_printf(1, "Thread 3 continue iteration %d \n", i); }
void fn2(void *args) { ABT_TEST_UNUSED(args); int i = 0; void *data = malloc(EVENTUAL_SIZE); ABT_test_printf(1, "Thread 2 iteration %d waiting from eventual\n", i); ABT_eventual_wait(myeventual,&data); ABT_test_printf(1, "Thread 2 continue iteration %d returning from " "eventual\n", i); }
void thread_create(void *arg) { int rank, i, ret; ABT_thread self; ABT_thread_id id; ABT_pool my_pool; ABT_thread *threads; assert((size_t)arg == 0); ret = ABT_xstream_self_rank(&rank); ABT_TEST_ERROR(ret, "ABT_xstream_self_rank"); ret = ABT_thread_self(&self); ABT_TEST_ERROR(ret, "ABT_thread_self"); ret = ABT_thread_get_id(self, &id); ABT_TEST_ERROR(ret, "ABT_thread_get_id"); ret = ABT_thread_get_last_pool(self, &my_pool); ABT_TEST_ERROR(ret, "ABT_thread_get_last_pool"); threads = (ABT_thread *)malloc(num_threads * sizeof(ABT_thread)); /* Create ULTs */ for (i = 0; i < num_threads; i++) { ret = ABT_thread_create(my_pool, thread_func, (void *)1, ABT_THREAD_ATTR_NULL, &threads[i]); ABT_TEST_ERROR(ret, "ABT_thread_create"); } ABT_test_printf(1, "[U%lu:E%u]: created %d ULTs\n", id, rank, num_threads); /* Join ULTs */ for (i = 0; i < num_threads; i++) { ret = ABT_thread_join(threads[i]); ABT_TEST_ERROR(ret, "ABT_thread_join"); } ABT_test_printf(1, "[U%lu:E%u]: joined %d ULTs\n", id, rank, num_threads); /* Revive ULTs with a different function */ for (i = 0; i < num_threads; i++) { ret = ABT_thread_revive(my_pool, thread_func2, (void *)2, &threads[i]); ABT_TEST_ERROR(ret, "ABT_thread_revive"); } ABT_test_printf(1, "[U%lu:E%u]: revived %d ULTs\n", id, rank, num_threads); /* Join and free ULTs */ for (i = 0; i < num_threads; i++) { ret = ABT_thread_free(&threads[i]); ABT_TEST_ERROR(ret, "ABT_thread_free"); } ABT_test_printf(1, "[U%lu:E%u]: freed %d ULTs\n", id, rank, num_threads); free(threads); }
int main(int argc, char *argv[]) { int ret; ABT_xstream xstream; /* init and thread creation */ ABT_test_init(argc, argv); ret = ABT_xstream_self(&xstream); ABT_TEST_ERROR(ret, "ABT_xstream_self"); /* Get the pools attached to an execution stream */ ABT_pool pool; ret = ABT_xstream_get_main_pools(xstream, 1, &pool); ABT_TEST_ERROR(ret, "ABT_xstream_get_main_pools"); ret = ABT_thread_create(pool, fn1, NULL, ABT_THREAD_ATTR_NULL, &th1); ABT_TEST_ERROR(ret, "ABT_thread_create"); ret = ABT_thread_create(pool, fn2, NULL, ABT_THREAD_ATTR_NULL, &th2); ABT_TEST_ERROR(ret, "ABT_thread_create"); ret = ABT_thread_create(pool, fn3, NULL, ABT_THREAD_ATTR_NULL, &th3); ABT_TEST_ERROR(ret, "ABT_thread_create"); ret = ABT_eventual_create(EVENTUAL_SIZE, &myeventual); ABT_TEST_ERROR(ret, "ABT_eventual_create"); ABT_test_printf(1, "START\n"); void *data; ABT_test_printf(1, "Thread main iteration %d waiting for eventual\n", 0); ABT_eventual_wait(myeventual,&data); ABT_test_printf(1, "Thread main continue iteration %d returning from " "eventual\n", 0); /* switch to other user-level threads */ ABT_thread_yield(); /* join other threads */ ret = ABT_thread_join(th1); ABT_TEST_ERROR(ret, "ABT_thread_join"); ret = ABT_thread_join(th2); ABT_TEST_ERROR(ret, "ABT_thread_join"); ret = ABT_thread_join(th3); ABT_TEST_ERROR(ret, "ABT_thread_join"); ABT_test_printf(1, "END\n"); ret = ABT_test_finalize(0); return ret; }
void thread_func(void *arg) { thread_arg_t *t_arg = (thread_arg_t *)arg; ABT_thread next; ABT_test_printf(1, "[TH%d]: before yield\n", t_arg->id); next = pick_one(t_arg->threads, t_arg->num_threads); ABT_thread_yield_to(next); ABT_test_printf(1, "[TH%d]: doing something ...\n", t_arg->id); next = pick_one(t_arg->threads, t_arg->num_threads); ABT_thread_yield_to(next); ABT_test_printf(1, "[TH%d]: after yield\n", t_arg->id); }
static void thread_func(void *arg) { unit_arg_t *my_arg = (unit_arg_t *)arg; ABT_bool valid; valid = verify_exec_order(my_arg->es_id, my_arg->prio); assert(valid == ABT_TRUE); ABT_test_printf(1, "[E%d:U%d:P%d] before yield\n", my_arg->es_id, my_arg->my_id, my_arg->prio); ABT_thread_yield(); valid = verify_exec_order(my_arg->es_id, my_arg->prio); assert(valid == ABT_TRUE); ABT_test_printf(1, "[E%d:U%d:P%d] after yield\n", my_arg->es_id, my_arg->my_id, my_arg->prio); free(my_arg); }
static void task_func(void *arg) { unit_arg_t *my_arg = (unit_arg_t *)arg; ABT_bool valid; valid = verify_exec_order(my_arg->es_id, my_arg->prio); assert(valid == ABT_TRUE); ABT_test_printf(1, "[E%d:T%d:P%d] running\n", my_arg->es_id, my_arg->my_id, my_arg->prio); free(my_arg); }
void thread_func(void *arg) { thread_arg_t *t_arg = (thread_arg_t *)arg; ABT_thread_yield(); ABT_mutex_lock(t_arg->mutex); g_counter++; ABT_mutex_unlock(t_arg->mutex); ABT_test_printf(1, "[TH%d] increased\n", t_arg->id); ABT_thread_yield(); }
static void gen_work(void *arg) { int idx = (size_t)arg; int num_pools = g_data.num_pools[idx]; ABT_pool *my_pools = g_data.pools[idx]; ABT_bool flag; int i, ret; unsigned seed = time(NULL); ABT_test_printf(1, "[E%d] creating work units\n", idx); /* Create work units on the current ES */ /* TODO: add work units to pools of other ESs */ for (i = 0; i < num_units; i++) { unit_arg_t *my_arg = (unit_arg_t *)malloc(sizeof(unit_arg_t)); my_arg->es_id = idx; my_arg->my_id = i; my_arg->prio = rand_r(&seed) % num_pools; if (i & 1) { ret = ABT_thread_create(my_pools[my_arg->prio], thread_func, (void *)my_arg, ABT_THREAD_ATTR_NULL, NULL); ABT_TEST_ERROR(ret, "ABT_thread_create"); } else { ret = ABT_task_create(my_pools[my_arg->prio], task_func, (void *)my_arg, NULL); ABT_TEST_ERROR(ret, "ABT_task_create"); } } /* Stack the priority scheduler if it is associated with PW pools */ ret = ABT_self_on_primary_xstream(&flag); ABT_TEST_ERROR(ret, "ABT_self_on_primary_stream"); if (flag == ABT_FALSE) { if (accesses[idx] == ABT_POOL_ACCESS_PRIV || accesses[idx] == ABT_POOL_ACCESS_SPSC || accesses[idx] == ABT_POOL_ACCESS_SPMC) { ABT_pool main_pool; ret = ABT_xstream_get_main_pools(g_data.xstreams[idx], 1, &main_pool); ABT_TEST_ERROR(ret, "ABT_xstream_get_main_pools"); ret = ABT_pool_add_sched(main_pool, g_data.scheds[idx]); ABT_TEST_ERROR(ret, "ABT_pool_add_sched"); } } }
void thread_func2(void *arg) { int rank, ret; ABT_thread self; ABT_thread_id id; assert((size_t)arg == 2); ret = ABT_xstream_self_rank(&rank); ABT_TEST_ERROR(ret, "ABT_xstream_self_rank"); ret = ABT_thread_self(&self); ABT_TEST_ERROR(ret, "ABT_thread_self"); ret = ABT_thread_get_id(self, &id); ABT_TEST_ERROR(ret, "ABT_thread_get_id"); ABT_test_printf(1, "[U%lu:E%u]: Good-bye, world!\n", id, rank); }
void task_func1(void *arg) { ABT_task my_handle; ABT_task_state my_state; ABT_task_self(&my_handle); ABT_task_get_state(my_handle, &my_state); if (my_state != ABT_TASK_STATE_RUNNING) { fprintf(stderr, "ERROR: not in the RUNNUNG state\n"); } ABT_task_release(my_handle); size_t i; size_t num = (size_t)arg; unsigned long long result = 1; for (i = 2; i <= num; i++) { result += i; } ABT_test_printf(1, "task_func1: num=%lu result=%llu\n", num, result); }
int main(int argc, char *argv[]) { int i, ret; ABT_xstream *xstreams; ABT_pool *pools; ABT_thread *threads; int num_xstreams = DEFAULT_NUM_XSTREAMS; /* Initialize */ ABT_test_init(argc, argv); if (argc >= 2) { num_xstreams = ABT_test_get_arg_val(ABT_TEST_ARG_N_ES); num_threads = ABT_test_get_arg_val(ABT_TEST_ARG_N_ULT); } ABT_test_printf(1, "# of ESs : %d\n", num_xstreams); ABT_test_printf(1, "# of ULTs/ES: %d\n", num_threads); xstreams = (ABT_xstream *)malloc(num_xstreams * sizeof(ABT_xstream)); pools = (ABT_pool *)malloc(num_xstreams * sizeof(ABT_pool)); threads = (ABT_thread *)malloc(num_xstreams * sizeof(ABT_thread)); /* Create Execution Streams */ ret = ABT_xstream_self(&xstreams[0]); ABT_TEST_ERROR(ret, "ABT_xstream_self"); for (i = 1; i < num_xstreams; i++) { ret = ABT_xstream_create(ABT_SCHED_NULL, &xstreams[i]); ABT_TEST_ERROR(ret, "ABT_xstream_create"); } /* Get the first pool of each ES */ for (i = 0; i < num_xstreams; i++) { ret = ABT_xstream_get_main_pools(xstreams[i], 1, &pools[i]); ABT_TEST_ERROR(ret, "ABT_xstream_get_main_pools"); } /* Create one ULT for each ES */ for (i = 1; i < num_xstreams; i++) { ret = ABT_thread_create(pools[i], thread_create, (void *)0, ABT_THREAD_ATTR_NULL, &threads[i]); ABT_TEST_ERROR(ret, "ABT_thread_create"); } thread_create((void *)0); /* Join and free ULTs */ for (i = 1; i < num_xstreams; i++) { ret = ABT_thread_free(&threads[i]); ABT_TEST_ERROR(ret, "ABT_thread_free"); } /* Join and free ESs */ for (i = 1; i < num_xstreams; i++) { ret = ABT_xstream_join(xstreams[i]); ABT_TEST_ERROR(ret, "ABT_xstream_join"); ret = ABT_xstream_free(&xstreams[i]); ABT_TEST_ERROR(ret, "ABT_xstream_free"); } /* Finalize */ ret = ABT_test_finalize(0); free(xstreams); free(pools); free(threads); return ret; }
int main(int argc, char *argv[]) { int i, j, ret; int num_xstreams = DEFAULT_NUM_XSTREAMS; int num_threads = DEFAULT_NUM_THREADS; int num_tasks = DEFAULT_NUM_TASKS; if (argc > 1) num_xstreams = atoi(argv[1]); assert(num_xstreams >= 0); if (argc > 2) num_threads = atoi(argv[2]); assert(num_threads >= 0); if (argc > 3) num_tasks = atoi(argv[3]); assert(num_tasks >= 0); ABT_xstream *xstreams; ABT_thread **threads; thread_arg_t **thread_args; ABT_task *tasks; task_arg_t *task_args; xstreams = (ABT_xstream *)malloc(sizeof(ABT_xstream) * num_xstreams); threads = (ABT_thread **)malloc(sizeof(ABT_thread *) * num_xstreams); thread_args = (thread_arg_t **)malloc(sizeof(thread_arg_t*) * num_xstreams); for (i = 0; i < num_xstreams; i++) { threads[i] = (ABT_thread *)malloc(sizeof(ABT_thread) * num_threads); for (j = 0; j < num_threads; j++) { threads[i][j] = ABT_THREAD_NULL; } thread_args[i] = (thread_arg_t *)malloc(sizeof(thread_arg_t) * num_threads); } tasks = (ABT_task *)malloc(sizeof(ABT_task) * num_tasks); task_args = (task_arg_t *)malloc(sizeof(task_arg_t) * num_tasks); /* Initialize */ ABT_test_init(argc, argv); /* Create Execution Streams */ ret = ABT_xstream_self(&xstreams[0]); ABT_TEST_ERROR(ret, "ABT_xstream_self"); for (i = 1; i < num_xstreams; i++) { ret = ABT_xstream_create(ABT_SCHED_NULL, &xstreams[i]); ABT_TEST_ERROR(ret, "ABT_xstream_create"); } /* Get the pools attached to an execution stream */ ABT_pool *pools; pools = (ABT_pool *)malloc(sizeof(ABT_pool) * num_xstreams); for (i = 0; i < num_xstreams; i++) { ret = ABT_xstream_get_main_pools(xstreams[i], 1, pools+i); ABT_TEST_ERROR(ret, "ABT_xstream_get_main_pools"); } /* Create threads */ for (i = 0; i < num_xstreams; i++) { for (j = 0; j < num_threads; j++) { int tid = i * num_threads + j + 1; thread_args[i][j].id = tid; thread_args[i][j].num_threads = num_threads; thread_args[i][j].threads = &threads[i][0]; ret = ABT_thread_create(pools[i], thread_func, (void *)&thread_args[i][j], ABT_THREAD_ATTR_NULL, &threads[i][j]); ABT_TEST_ERROR(ret, "ABT_thread_create"); } } /* Create tasks with task_func1 */ for (i = 0; i < num_tasks; i++) { size_t num = 100 + i; ret = ABT_task_create(pools[i % num_xstreams], task_func1, (void *)num, NULL); ABT_TEST_ERROR(ret, "ABT_task_create"); } /* Create tasks with task_func2 */ for (i = 0; i < num_tasks; i++) { task_args[i].num = 100 + i; ret = ABT_task_create(pools[i % num_xstreams], task_func2, (void *)&task_args[i], &tasks[i]); ABT_TEST_ERROR(ret, "ABT_task_create"); } /* Switch to other work units */ ABT_thread_yield(); /* Results of task_funcs2 */ for (i = 0; i < num_tasks; i++) { ABT_task_state state; do { ABT_task_get_state(tasks[i], &state); ABT_thread_yield(); } while (state != ABT_TASK_STATE_TERMINATED); ABT_test_printf(1, "task_func2: num=%lu result=%llu\n", task_args[i].num, task_args[i].result); /* Free named tasks */ ret = ABT_task_free(&tasks[i]); ABT_TEST_ERROR(ret, "ABT_task_free"); } /* Join Execution Streams */ for (i = 1; i < num_xstreams; i++) { ret = ABT_xstream_join(xstreams[i]); ABT_TEST_ERROR(ret, "ABT_xstream_join"); } /* Free Execution Streams */ for (i = 0; i < num_xstreams; i++) { for (j = 0; j < num_threads; j++) { ret = ABT_thread_free(&threads[i][j]); ABT_TEST_ERROR(ret, "ABT_thread_free"); } if (i == 0) continue; ret = ABT_xstream_free(&xstreams[i]); ABT_TEST_ERROR(ret, "ABT_xstream_free"); } /* Finalize */ ret = ABT_test_finalize(0); for (i = 0; i < num_xstreams; i++) { free(thread_args[i]); free(threads[i]); } free(thread_args); free(threads); free(task_args); free(tasks); free(pools); free(xstreams); return ret; }
int main(int argc, char *argv[]) { ABT_xstream *xstreams; ABT_pool *pools; ABT_thread *threads; int num_xstreams; int es = 0; int *args; int i, j, iter, t; int ret; /* Initialize */ ABT_test_init(argc, argv); if (argc < 2) { num_xstreams = 4; N = 10; iter = 100; } else { num_xstreams = ABT_test_get_arg_val(ABT_TEST_ARG_N_ES); N = ABT_test_get_arg_val(ABT_TEST_ARG_N_ULT); iter = ABT_test_get_arg_val(ABT_TEST_ARG_N_ITER); } ABT_test_printf(1, "# of ESs : %d\n", num_xstreams); ABT_test_printf(1, "# of ULTs: %d\n", N * N); ABT_test_printf(1, "# of iter: %d\n", iter); xstreams = (ABT_xstream *)malloc(num_xstreams * sizeof(ABT_xstream)); pools = (ABT_pool *)malloc(num_xstreams * sizeof(ABT_pool)); threads = (ABT_thread *)malloc(N * N * sizeof(ABT_thread)); values = (int *)malloc(N * sizeof(int)); row_barrier = (ABT_barrier *)malloc(N * sizeof(ABT_barrier)); col_barrier = (ABT_barrier *)malloc(N * sizeof(ABT_barrier)); /* Create the values and barriers */ for (i = 0; i < N; i++) { ret = ABT_barrier_create((size_t)N, &row_barrier[i]); ABT_TEST_ERROR(ret, "ABT_barrier_create"); ret = ABT_barrier_create((size_t)N, &col_barrier[i]); ABT_TEST_ERROR(ret, "ABT_barrier_create"); } ret = ABT_barrier_create((size_t)N * N, &global_barrier); ABT_TEST_ERROR(ret, "ABT_barrier_create"); args = (int *)malloc(2 * N * N * sizeof(int)); /* Create ESs */ for (t = 0; t < iter; t++) { ABT_test_printf(1, "iter=%d\n", t); ret = ABT_xstream_self(&xstreams[0]); ABT_TEST_ERROR(ret, "ABT_xstream_self"); for (i = 1; i < num_xstreams; i++) { ret = ABT_xstream_create(ABT_SCHED_NULL, &xstreams[i]); ABT_TEST_ERROR(ret, "ABT_xstream_create"); } /* Get the first pool of each ES */ for (i = 0; i < num_xstreams; i++) { ret = ABT_xstream_get_main_pools(xstreams[i], 1, &pools[i]); ABT_TEST_ERROR(ret, "ABT_xstream_get_main_pools"); } /* Create ULTs */ for (i = 0; i < N; i++) { values[i] = i; } for (i = 0; i < N; i++) { for (j = 0; j < N; j++) { args[2*(i*N+j)] = i; args[2*(i*N+j)+1] = j; ret = ABT_thread_create(pools[es], run, (void *)&args[2*(i*N+j)], ABT_THREAD_ATTR_NULL, &threads[i*N+j]); ABT_TEST_ERROR(ret, "ABT_thread_create"); es = (es + 1) % num_xstreams; } } /* Join and free ULTs */ for (i = 0; i < N; i++) { for (j = 0; j < N; j++) { ret = ABT_thread_free(&threads[i*N+j]); ABT_TEST_ERROR(ret, "ABT_thread_free"); } } /* Join ESs */ for (i = 1; i < num_xstreams; i++) { ret = ABT_xstream_join(xstreams[i]); ABT_TEST_ERROR(ret, "ABT_xstream_join"); } /* Free ESs */ for (i = 1; i < num_xstreams; i++) { ret = ABT_xstream_free(&xstreams[i]); ABT_TEST_ERROR(ret, "ABT_xstream_free"); } } /* Free the barriers */ for (i = 0; i < N; i++) { ret = ABT_barrier_free(&row_barrier[i]); ABT_TEST_ERROR(ret, "ABT_barrier_create"); ret = ABT_barrier_free(&col_barrier[i]); ABT_TEST_ERROR(ret, "ABT_barrier_create"); } ret = ABT_barrier_free(&global_barrier); ABT_TEST_ERROR(ret, "ABT_barrier_free"); /* Finalize */ ret = ABT_test_finalize(0); free(xstreams); free(pools); free(threads); free(values); free(row_barrier); free(col_barrier); free(args); return ret; }
void eventual_test(void *arg) { int i, t, ret; size_t pid = (size_t)arg; int eid = (int)pid; ABT_thread *threads; arg_t *thread_args; int *nbytes; ABT_eventual *evs1; ABT_thread *waiters; arg_t *waiter_args; ABT_task *tasks; arg_t *task_args; ABT_eventual *evs2; ABT_test_printf(1, "[M%u] start\n", (unsigned)(size_t)arg); assert(num_tasks * 2 == num_threads); threads = (ABT_thread *)malloc(num_threads * sizeof(ABT_thread)); thread_args = (arg_t *)malloc(num_threads * sizeof(arg_t)); nbytes = (int *)malloc(num_tasks * sizeof(int)); evs1 = (ABT_eventual *)malloc(num_tasks * sizeof(ABT_eventual)); assert(threads && thread_args && nbytes && evs1); waiters = (ABT_thread *)malloc(num_tasks * sizeof(ABT_thread)); waiter_args = (arg_t *)malloc(num_tasks * sizeof(arg_t)); tasks = (ABT_task *)malloc(num_tasks * sizeof(ABT_task)); task_args = (arg_t *)malloc(num_tasks * sizeof(arg_t)); evs2 = (ABT_eventual *)malloc(num_tasks * sizeof(ABT_eventual)); assert(waiters && waiter_args && tasks && task_args && evs2); for (t = 0; t < num_tasks; t++) { nbytes[t] = (t & 1) ? sizeof(int) : 0; ret = ABT_eventual_create(nbytes[t], &evs1[t]); ABT_TEST_ERROR(ret, "ABT_eventual_create"); ret = ABT_eventual_create(nbytes[t], &evs2[t]); ABT_TEST_ERROR(ret, "ABT_eventual_create"); } for (i = 0; i < num_iter; i++) { ABT_test_printf(2, "[M%u] iter=%d\n", (unsigned)(size_t)arg, i); /* Use eventual between ULTs */ for (t = 0; t < num_threads; t += 2) { thread_args[t].eid = eid; thread_args[t].tid = t; thread_args[t].ev = evs1[t/2]; thread_args[t].nbytes = nbytes[t/2]; thread_args[t].op_type = OP_WAIT; ret = ABT_thread_create(pools[pid], thread_func, &thread_args[t], ABT_THREAD_ATTR_NULL, &threads[t]); ABT_TEST_ERROR(ret, "ABT_thread_create"); pid = (pid + 1) % num_xstreams; thread_args[t+1].eid = eid; thread_args[t+1].tid = t + 1; thread_args[t+1].ev = evs1[t/2]; thread_args[t+1].nbytes = nbytes[t/2]; thread_args[t+1].op_type = OP_SET; ret = ABT_thread_create(pools[pid], thread_func, &thread_args[t+1], ABT_THREAD_ATTR_NULL, &threads[t+1]); ABT_TEST_ERROR(ret, "ABT_thread_create"); pid = (pid + 1) % num_xstreams; } /* Use eventual between ULT and tasklet */ for (t = 0; t < num_tasks; t++) { waiter_args[t].ev = evs2[t]; waiter_args[t].nbytes = nbytes[t]; waiter_args[t].op_type = OP_WAIT; ret = ABT_thread_create(pools[pid], thread_func, &waiter_args[t], ABT_THREAD_ATTR_NULL, &waiters[t]); ABT_TEST_ERROR(ret, "ABT_thread_create"); pid = (pid + 1) % num_xstreams; task_args[t].ev = evs2[t]; task_args[t].nbytes = nbytes[t]; task_args[t].op_type = OP_SET; ret = ABT_task_create(pools[pid], task_func, &task_args[t], &tasks[t]); ABT_TEST_ERROR(ret, "ABT_task_create"); pid = (pid + 1) % num_xstreams; } for (t = 0; t < num_threads; t++) { ret = ABT_thread_free(&threads[t]); ABT_TEST_ERROR(ret, "ABT_thread_free"); } for (t = 0; t < num_tasks; t++) { ret = ABT_thread_free(&waiters[t]); ABT_TEST_ERROR(ret, "ABT_thread_free"); ret = ABT_task_free(&tasks[t]); ABT_TEST_ERROR(ret, "ABT_task_free"); } for (t = 0; t < num_tasks; t++) { ret = ABT_eventual_reset(evs1[t]); ABT_TEST_ERROR(ret, "ABT_eventual_reset"); ret = ABT_eventual_reset(evs2[t]); ABT_TEST_ERROR(ret, "ABT_eventual_reset"); } } for (t = 0; t < num_tasks; t++) { ret = ABT_eventual_free(&evs1[t]); ABT_TEST_ERROR(ret, "ABT_eventual_free"); ret = ABT_eventual_free(&evs2[t]); ABT_TEST_ERROR(ret, "ABT_eventual_free"); } free(threads); free(thread_args); free(nbytes); free(evs1); free(waiters); free(waiter_args); free(tasks); free(task_args); free(evs2); ABT_test_printf(1, "[M%u] end\n", (unsigned)(size_t)arg); }
int main(int argc, char *argv[]) { ABT_xstream *xstreams; ABT_thread *masters; int i, ret; /* Initialize */ ABT_test_init(argc, argv); if (argc < 2) { num_xstreams = DEFAULT_NUM_XSTREAMS; num_threads = DEFAULT_NUM_THREADS; num_tasks = DEFAULT_NUM_TASKS; num_iter = DEFAULT_NUM_ITER; } else { num_xstreams = ABT_test_get_arg_val(ABT_TEST_ARG_N_ES); num_tasks = ABT_test_get_arg_val(ABT_TEST_ARG_N_TASK); num_threads = num_tasks * 2; num_iter = ABT_test_get_arg_val(ABT_TEST_ARG_N_ITER); } ABT_test_printf(1, "# of ESs : %d\n", num_xstreams); ABT_test_printf(1, "# of ULTs/ES : %d\n", num_threads + num_tasks); ABT_test_printf(1, "# of tasklets/ES: %d\n", num_tasks); ABT_test_printf(1, "# of iter : %d\n", num_iter); xstreams = (ABT_xstream *)malloc(num_xstreams * sizeof(ABT_xstream)); pools = (ABT_pool *)malloc(num_xstreams * sizeof(ABT_pool)); masters = (ABT_thread *)malloc(num_xstreams * sizeof(ABT_thread)); /* Create Execution Streams */ ret = ABT_xstream_self(&xstreams[0]); ABT_TEST_ERROR(ret, "ABT_xstream_self"); for (i = 1; i < num_xstreams; i++) { ret = ABT_xstream_create(ABT_SCHED_NULL, &xstreams[i]); ABT_TEST_ERROR(ret, "ABT_xstream_create"); } /* Get the main pool of each ES */ for (i = 0; i < num_xstreams; i++) { ret = ABT_xstream_get_main_pools(xstreams[i], 1, &pools[i]); ABT_TEST_ERROR(ret, "ABT_xstream_get_main_pools"); } /* Create a master ULT for each ES */ for (i = 1; i < num_xstreams; i++) { ret = ABT_thread_create(pools[i], eventual_test, (void *)(size_t)i, ABT_THREAD_ATTR_NULL, &masters[i]); ABT_TEST_ERROR(ret, "ABT_thread_create"); } eventual_test((void *)0); /* Join master ULTs */ for (i = 1; i < num_xstreams; i++) { ret = ABT_thread_free(&masters[i]); ABT_TEST_ERROR(ret, "ABT_thread_free"); } /* Join and free Execution Streams */ for (i = 1; i < num_xstreams; i++) { ret = ABT_xstream_join(xstreams[i]); ABT_TEST_ERROR(ret, "ABT_xstream_join"); ret = ABT_xstream_free(&xstreams[i]); ABT_TEST_ERROR(ret, "ABT_xstream_free"); } /* Finalize */ ret = ABT_test_finalize(0); free(xstreams); free(pools); free(masters); return ret; }
void thread_func(void *arg) { size_t my_id = (size_t)arg; ABT_test_printf(1, "[TH%lu]: Hello, world!\n", my_id); }