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 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); }
/* Function to compute Fibonacci numbers */ void fibonacci_thread(void *arguments) { int n, *n1, *n2; thread_args a1, a2; ABT_eventual eventual, f1, f2; thread_args *args = (thread_args *)arguments; n = args->n; eventual = args->eventual; /* checking for base cases */ if (n <= 2) args->result = 1; else { ABT_eventual_create(sizeof(int), &f1); a1.n = n - 1; a1.eventual = f1; ABT_thread_create(g_pool, fibonacci_thread, &a1, ABT_THREAD_ATTR_NULL, NULL); ABT_eventual_create(sizeof(int), &f2); a2.n = n - 2; a2.eventual = f2; ABT_thread_create(g_pool, fibonacci_thread, &a2, ABT_THREAD_ATTR_NULL, NULL); ABT_eventual_wait(f1, (void **)&n1); ABT_eventual_wait(f2, (void **)&n2); args->result = *n1 + *n2; ABT_eventual_free(&f1); ABT_eventual_free(&f2); } /* checking whether to signal the eventual */ if (eventual != ABT_EVENTUAL_NULL) { ABT_eventual_set(eventual, &args->result, sizeof(int)); } }
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; }