Example #1
0
static void thread_hello(void *arg)
{
    int old_rank, cur_rank;
    ABT_thread self;
    ABT_thread_id id;
    char *msg;

    ABT_xstream_self_rank(&cur_rank);
    ABT_thread_self(&self);
    ABT_thread_get_id(self, &id);
    ABT_thread_release(self);

    test_printf("[U%lu:E%d] Hello, world!\n", id, cur_rank);

    ABT_thread_yield();

    old_rank = cur_rank;
    ABT_xstream_self_rank(&cur_rank);
    msg = (cur_rank == old_rank) ? "" : " (stolen)";
    test_printf("[U%lu:E%d] Hello again #1.%s\n", id, cur_rank, msg);

    ABT_thread_yield();

    old_rank = cur_rank;
    ABT_xstream_self_rank(&cur_rank);
    msg = (cur_rank == old_rank) ? "" : " (stolen)";
    test_printf("[U%lu:E%d] Hello again #2.%s\n", id, cur_rank, msg);

    ABT_thread_yield();

    old_rank = cur_rank;
    ABT_xstream_self_rank(&cur_rank);
    msg = (cur_rank == old_rank) ? "" : " (stolen)";
    test_printf("[U%lu:E%d] Goodbye, world!%s\n", id, cur_rank, msg);
}
Example #2
0
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();
}
Example #3
0
void
ds_mgmt_hdlr_svc_rip(crt_rpc_t *rpc)
{
	struct mgmt_svc_rip_in	*murderer;
	int			 sig;
	bool			 force;
	d_rank_t		 rank = -1;

	murderer = crt_req_get(rpc);
	if (murderer == NULL)
		return;

	force = (murderer->rip_flags != 0);

	/*
	 * the yield below is to workaround an ofi err msg at client-side -
	 * fi_cq_readerr got err: 5(Input/output error) ..
	 */
	int i;
	for (i = 0; i < 200; i++) {
		ABT_thread_yield();
		usleep(10);
	}

	/** ... adieu */
	if (force)
		sig = SIGKILL;
	else
		sig = SIGTERM;
	crt_group_rank(NULL, &rank);
	D_PRINT("Service rank %d is being killed by signal %d... farewell\n",
		rank, sig);
	kill(getpid(), sig);
}
Example #4
0
void thread_func_migrate_to_xstream(void *arg)
{
    arg_t *my_arg = (arg_t *)arg;
    int eid = my_arg->eid;
    ABT_xstream cur_xstream, tar_xstream;
    ABT_thread self;
    int i, next;

    ABT_thread_self(&self);

    for (i = 0; i < iter; i++) {
        next = (eid + 1) % num_xstreams;
        tar_xstream = g_xstreams[next];

        ABT_thread_migrate_to_xstream(self, tar_xstream);
        while (1) {
            ABT_bool flag;
            ABT_xstream_self(&cur_xstream);
            ABT_xstream_equal(cur_xstream, tar_xstream, &flag);
            if (flag == ABT_TRUE) {
                break;
            }
            ABT_thread_yield();
        }
        eid = next;
    }
}
Example #5
0
void thread_func_yield(void *arg)
{
    ABT_TEST_UNUSED(arg);
    int i;
    for (i = 0; i < iter; i++) {
        ABT_thread_yield();
    }
}
Example #6
0
void accalt_yield() {
#ifdef ARGOBOTS
    ABT_thread_yield();
#endif
#ifdef MASSIVETHREADS
    myth_yield(0);
#endif
#ifdef QTHREADS
    qthread_yield();
#endif
}
Example #7
0
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;
}
Example #8
0
void test_create_unnamed(void *arg)
{
    int eid = (int)(size_t)arg;
    ABT_pool my_pool = g_pools[eid];
    int i, t;

    for (i = 0; i < iter; i++) {
        for (t = 0; t < num_threads; t++) {
            ABT_thread_create(my_pool, thread_func, NULL,
                              ABT_THREAD_ATTR_NULL, NULL);
        }
        ABT_thread_yield();
    }
}
Example #9
0
void thread_func_yield_to_overhead(void *arg)
{
    arg_t *my_arg = (arg_t *)arg;
    int eid = my_arg->eid;
    int tid = my_arg->tid;
    int nid = (tid + 1) % num_threads;
    ABT_thread next = g_threads[eid][nid];
    ABT_TEST_UNUSED(next);
    int i;

    for (i = 0; i < iter; i++) {
    }
    ABT_thread_yield();
}
Example #10
0
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);
}
Example #11
0
/* Daemon ULT for processing RPC replies */
void
rdb_recvd(void *arg)
{
	struct rdb *db = arg;

	D_DEBUG(DB_MD, DF_DB": recvd starting\n", DP_DB(db));
	for (;;) {
		struct rdb_raft_rpc    *rrpc = NULL;
		bool			stop;

		ABT_mutex_lock(db->d_mutex);
		for (;;) {
			stop = db->d_stop;
			if (!d_list_empty(&db->d_replies)) {
				rrpc = d_list_entry(db->d_replies.next,
						    struct rdb_raft_rpc,
						    drc_entry);
				d_list_del_init(&rrpc->drc_entry);
				break;
			}
			if (stop)
				break;
			ABT_cond_wait(db->d_replies_cv, db->d_mutex);
		}
		ABT_mutex_unlock(db->d_mutex);
		if (rrpc == NULL) {
			D_ASSERT(stop);
			/* The queue is empty and we are asked to stop. */
			break;
		}
		/*
		 * The queue has pending replies. If we are asked to stop, skip
		 * the processing but still free the RPCs until the queue
		 * become empty.
		 */
		if (!stop)
			rdb_raft_process_reply(db, rrpc->drc_rpc);
		rdb_raft_free_request(db, rrpc->drc_rpc);
		rdb_free_raft_rpc(rrpc);
		ABT_thread_yield();
	}
Example #12
0
static void thread_join_xstream(void *arg)
{
    char send_buf[SEND_BUF_LEN];
    int idx = num_xstreams - 1;
    int n;
    ABT_xstream_state state;

    g_signal[idx] = 1;
    while (1) {
        ABT_xstream_get_state(g_xstreams[idx], &state);
        if (state == ABT_XSTREAM_STATE_TERMINATED) break;
        ABT_thread_yield();
    }
    ABT_xstream_free(&g_xstreams[idx]);
    num_xstreams--;

    if (abt_alive) {
        printf("# of ESs: %d\n", num_xstreams);
        sprintf(send_buf, "done (%d)", num_xstreams);
        n = write(abt_pfd.fd, send_buf, strlen(send_buf));
        assert(n == strlen(send_buf));
    }
}
Example #13
0
void rt1_finalize(void)
{
    int i;

    while (rt1_data->num_xstreams > 0) {
        ABT_thread_yield();
    }

    for (i = 0; i < rt1_data->max_xstreams; i++) {
        assert(rt1_data->xstreams[i] == ABT_XSTREAM_NULL);
    }

    /* Delete registered callbacks */
    ABT_event_del_callback(ABT_EVENT_STOP_XSTREAM, rt1_data->stop_cb_id);
    ABT_event_del_callback(ABT_EVENT_ADD_XSTREAM, rt1_data->add_cb_id);

    ABT_mutex_lock(rt1_data->mutex);
    ABT_mutex_free(&rt1_data->mutex);
    ABT_barrier_free(&rt1_data->bar);
    free(rt1_data->xstreams);
    free(rt1_data->app_data);
    free(rt1_data);
    rt1_data = NULL;
}
Example #14
0
void rt1_launcher(void *arg)
{
    int idx = (int)(intptr_t)arg;
    ABT_thread cur_thread;
    ABT_pool cur_pool;
    ABT_sched_config config;
    ABT_sched sched;
    size_t size;
    double t_start, t_end;

    ABT_sched_config_var cv_event_freq = {
        .idx = 0,
        .type = ABT_SCHED_CONFIG_INT
    };

    ABT_sched_config_var cv_idx = {
        .idx = 1,
        .type = ABT_SCHED_CONFIG_INT
    };

    ABT_sched_def sched_def = {
        .type = ABT_SCHED_TYPE_ULT,
        .init = sched_init,
        .run = sched_run,
        .free = sched_free,
        .get_migr_pool = NULL
    };

    /* Create a scheduler */
    ABT_sched_config_create(&config,
                            cv_event_freq, 10,
                            cv_idx, idx,
                            ABT_sched_config_var_end);
    ABT_sched_create(&sched_def, 1, &rt1_data->pool, config, &sched);

    /* Push the scheduler to the current pool */
    ABT_thread_self(&cur_thread);
    ABT_thread_get_last_pool(cur_thread, &cur_pool);
    ABT_pool_add_sched(cur_pool, sched);

    /* Free */
    ABT_sched_config_free(&config);

    t_start = ABT_get_wtime();
    while (1) {
        rt1_app(idx);

        ABT_pool_get_total_size(cur_pool, &size);
        if (size == 0) {
            ABT_sched_free(&sched);
            int rank;
            ABT_xstream_self_rank(&rank);
            printf("ES%d: finished\n", rank);
            ABT_mutex_lock(rt1_data->mutex);
            rt1_data->xstreams[rank] = ABT_XSTREAM_NULL;
            rt1_data->num_xstreams--;
            ABT_mutex_unlock(rt1_data->mutex);
            break;
        }

        t_end = ABT_get_wtime();
        if ((t_end - t_start) > g_timeout) {
            ABT_sched_finish(sched);
        }
    }
}

static void rt1_app(int eid)
{
    int i, num_comps;
    size_t size;
    ABT_thread cur_thread;
    ABT_pool cur_pool;

    ABT_thread_self(&cur_thread);
    ABT_thread_get_last_pool(cur_thread, &cur_pool);

    if (eid == 0) ABT_event_prof_start();

    num_comps = rt1_data->num_comps;
    for (i = 0; i < num_comps * 2; i += 2) {
        ABT_thread_create(rt1_data->pool, rt1_app_compute,
                          (void *)(intptr_t)(eid * num_comps * 2 + i),
                          ABT_THREAD_ATTR_NULL, NULL);
        ABT_task_create(rt1_data->pool, rt1_app_compute,
                        (void *)(intptr_t)(eid * num_comps * 2 + i + 1),
                        NULL);
    }

    do {
        ABT_thread_yield();

        /* If the size of cur_pool is zero, it means the stacked scheduler has
         * been terminated because of the shrinking event. */
        ABT_pool_get_total_size(cur_pool, &size);
        if (size == 0) break;

        ABT_pool_get_total_size(rt1_data->pool, &size);
    } while (size > 0);

    if (eid == 0) {
        ABT_event_prof_stop();

        int cnt = __atomic_exchange_n(&rt1_data->cnt, 0, __ATOMIC_SEQ_CST);
        double local_work = (double)(cnt * rt1_data->num_iters);
        ABT_event_prof_publish("ops", local_work, local_work);
    }
}

static void rt1_app_compute(void *arg)
{
    int pos = (int)(intptr_t)arg;
    int i;

    rt1_data->app_data[pos] = 0;
    for (i = 0; i < rt1_data->num_iters; i++) {
        rt1_data->app_data[pos] += sin((double)pos);
    }

    __atomic_fetch_add(&rt1_data->cnt, 1, __ATOMIC_SEQ_CST);
}
Example #15
0
int main(int argc, char *argv[])
{
    int i, j;
    int ret;
    int num_xstreams = DEFAULT_NUM_XSTREAMS;
    int num_threads = DEFAULT_NUM_THREADS;
    if (argc > 1) num_xstreams = atoi(argv[1]);
    assert(num_xstreams >= 0);
    if (argc > 2) num_threads = atoi(argv[2]);
    assert(num_threads >= 0);

    ABT_xstream *xstreams;
    ABT_thread **threads;
    thread_arg_t **args;
    xstreams = (ABT_xstream *)malloc(sizeof(ABT_xstream) * num_xstreams);
    threads = (ABT_thread **)malloc(sizeof(ABT_thread *) * num_xstreams);
    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;
        }
        args[i] = (thread_arg_t *)malloc(sizeof(thread_arg_t) * num_threads);
    }

    /* 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;
            args[i][j].id = tid;
            args[i][j].num_threads = num_threads;
            args[i][j].threads = &threads[i][0];
            ret = ABT_thread_create(pools[i],
                    thread_func, (void *)&args[i][j], ABT_THREAD_ATTR_NULL,
                    &threads[i][j]);
            ABT_TEST_ERROR(ret, "ABT_thread_create");
        }
    }

    /* Switch to other user level threads */
    ABT_thread_yield();

    /* Join Execution Streams */
    for (i = 1; i < num_xstreams; i++) {
        ret = ABT_xstream_join(xstreams[i]);
        ABT_TEST_ERROR(ret, "ABT_xstream_join");
    }

    /* Free threads and 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(args[i]);
        free(threads[i]);
    }
    free(args);
    free(threads);
    free(pools);
    free(xstreams);

    return ret;
}
/* Main function */
int main(int argc, char *argv[])
{
    int n, i, result, expected;
    int num_xstreams;
    ABT_xstream *xstreams;

    ABT_thread thread;
    thread_args args_thread;
    ABT_task task;
    task_args *args_task;

    if (argc > 1 && strcmp(argv[1], "-h") == 0) {
        printf("Usage: %s [N=10] [num_ES=4]\n", argv[0]);
        return EXIT_SUCCESS;
    }
    n = argc > 1 ? atoi(argv[1]) : N;
    num_xstreams = argc > 2 ? atoi(argv[2]) : NUM_XSTREAMS;
    printf("# of ESs: %d\n", num_xstreams);

    if (n <= 2) {
        result = 1;
        goto fn_result;
    }

    /* initialization */
    ABT_init(argc, argv);

    /* shared pool creation */
    ABT_pool_create_basic(ABT_POOL_FIFO, ABT_POOL_ACCESS_MPMC, ABT_TRUE,
                          &g_pool);

    /* ES creation */
    xstreams = (ABT_xstream *)malloc(sizeof(ABT_xstream) * num_xstreams);
    ABT_xstream_self(&xstreams[0]);
    ABT_xstream_set_main_sched_basic(xstreams[0], ABT_SCHED_DEFAULT,
                                     1, &g_pool);
    for (i = 1; i < num_xstreams; i++) {
        ABT_xstream_create_basic(ABT_SCHED_DEFAULT, 1, &g_pool,
                                 ABT_SCHED_CONFIG_NULL, &xstreams[i]);
        ABT_xstream_start(xstreams[i]);
    }

    /* creating thread */
    args_thread.n = n - 1;
    args_thread.eventual = ABT_EVENTUAL_NULL;
    ABT_thread_create(g_pool, fibonacci_thread, &args_thread, ABT_THREAD_ATTR_NULL, &thread);

    /* creating task */
    args_task = (task_args *)malloc(sizeof(task_args));
    args_task->n = n - 2;
    args_task->result = 0;
    ABT_mutex_create(&args_task->mutex);
    args_task->parent = NULL;
    ABT_task_create(g_pool, fibonacci_task, args_task, &task);

    /* switch to other user-level threads */
    ABT_thread_yield();

    /* join other threads */
    ABT_thread_join(thread);
    ABT_thread_free(&thread);

    /* join ESs */
    for (i = 1; i < num_xstreams; i++) {
        ABT_xstream_join(xstreams[i]);
        ABT_xstream_free(&xstreams[i]);
    }

    result = args_thread.result + args_task->result;
    free(args_task);

    ABT_finalize();

    free(xstreams);

  fn_result:
    printf("Fib(%d): %d\n", n, result);
    expected = verify(n);
    if (result != expected) {
        fprintf(stderr, "ERROR: expected=%d\n", expected);
        exit(EXIT_FAILURE);
    }

    return EXIT_SUCCESS;
}
Example #17
0
/* Create a work-stealing scheduler and push it to the pool */
static void thread_add_sched(void *arg)
{
    int idx = (int)(intptr_t)arg;
    int i;
    ABT_thread cur_thread;
    ABT_pool cur_pool;
    ABT_pool *my_pools;
    ABT_sched_config config;
    ABT_sched sched;
    size_t size;
    double t_start, t_end;

    ABT_sched_config_var cv_event_freq = {
        .idx = 0,
        .type = ABT_SCHED_CONFIG_INT
    };

    ABT_sched_config_var cv_idx = {
        .idx = 1,
        .type = ABT_SCHED_CONFIG_INT
    };

    ABT_sched_def sched_def = {
        .type = ABT_SCHED_TYPE_ULT,
        .init = sched_init,
        .run = sched_run,
        .free = sched_free,
        .get_migr_pool = NULL
    };

    /* Create a scheduler */
    ABT_sched_config_create(&config,
                            cv_event_freq, 10,
                            cv_idx, idx,
                            ABT_sched_config_var_end);
    my_pools = (ABT_pool *)malloc(sizeof(ABT_pool) * max_xstreams);
    for (i = 0; i < max_xstreams; i++) {
        my_pools[i] = g_pools[(idx + i) % max_xstreams];
    }
    ABT_sched_create(&sched_def, max_xstreams, my_pools, config, &sched);

    /* Create a ULT for the new scheduler */
    ABT_thread_create(my_pools[0], thread_work, arg, ABT_THREAD_ATTR_NULL,
                      NULL);

    /* Push the scheduler to the current pool */
    ABT_thread_self(&cur_thread);
    ABT_thread_get_last_pool(cur_thread, &cur_pool);
    ABT_pool_add_sched(cur_pool, sched);

    /* Free */
    ABT_thread_release(cur_thread);
    ABT_sched_config_free(&config);
    free(my_pools);

    t_start = ABT_get_wtime();
    while (1) {
        ABT_thread_yield();

        ABT_pool_get_total_size(cur_pool, &size);
        if (size == 0) {
            ABT_sched_free(&sched);
            break;
        }

        t_end = ABT_get_wtime();
        if ((t_end - t_start) > g_timeout) {
            ABT_sched_finish(sched);
        }
    }
}

static void thread_work(void *arg)
{
    int idx = (int)(intptr_t)arg;
    int i;
    ABT_thread cur_thread;
    ABT_pool cur_pool;
    ABT_thread *threads;
    int num_threads;
    double t_start, t_end;

    ABT_thread_self(&cur_thread);
    ABT_thread_get_last_pool(cur_thread, &cur_pool);
    ABT_thread_release(cur_thread);

    t_start = ABT_get_wtime();
    while (1) {
        num_threads = 2;
        threads = (ABT_thread *)malloc(sizeof(ABT_thread) * num_threads);
        for (i = 0; i < num_threads; i++) {
            ABT_thread_create(cur_pool, thread_hello, NULL,
                              ABT_THREAD_ATTR_NULL, &threads[i]);
        }
        for (i = 0; i < num_threads; i++) {
            ABT_thread_free(&threads[i]);
        }
        free(threads);

        if (g_signal[idx]) {
            ABT_xstream xstream;
            ABT_xstream_self(&xstream);
            ABT_xstream_cancel(xstream);
            g_signal[idx] = 0;
            break;
        }

        t_end = ABT_get_wtime();
        if ((t_end - t_start) > g_timeout) {
            break;
        }
    }
}

static void test_printf(const char *format, ...)
{
#if 0
    va_start(list, format);
    vprintf(format, list);
    va_end(list);
    fflush(stdout);
#endif
}
Example #18
0
/**
 * @ingroup COND
 * @brief   Wait on the condition.
 *
 * The ULT calling \c ABT_cond_timedwait() waits on the condition variable
 * until it is signaled or the absolute time specified by \c abstime passes.
 * If system time equals or exceeds \c abstime before \c cond is signaled,
 * the error code \c ABT_ERR_COND_TIMEDOUT is returned.
 *
 * The user should call this routine while the mutex specified as \c mutex is
 * locked. The mutex will be automatically released while waiting. After signal
 * is received and the waiting ULT is awakened, the mutex will be
 * automatically locked for use by the ULT. The user is then responsible for
 * unlocking mutex when the ULT is finished with it.
 *
 * @param[in] cond     handle to the condition variable
 * @param[in] mutex    handle to the mutex
 * @param[in] abstime  absolute time for timeout
 * @return Error code
 * @retval ABT_SUCCESS            on success
 * @retval ABT_ERR_COND_TIMEDOUT  timeout
 */
int ABT_cond_timedwait(ABT_cond cond, ABT_mutex mutex,
                       const struct timespec *abstime)
{
    int abt_errno = ABT_SUCCESS;
    ABTI_cond *p_cond = ABTI_cond_get_ptr(cond);
    ABTI_CHECK_NULL_COND_PTR(p_cond);
    ABTI_mutex *p_mutex = ABTI_mutex_get_ptr(mutex);
    ABTI_CHECK_NULL_MUTEX_PTR(p_mutex);

    double tar_time = convert_timespec_to_sec(abstime);

    ABTI_unit *p_unit;
    volatile int ext_signal = 0;

    p_unit = (ABTI_unit *)ABTU_calloc(1, sizeof(ABTI_unit));
    p_unit->pool = (ABT_pool)&ext_signal;
    p_unit->type = ABT_UNIT_TYPE_EXT;

    ABTI_mutex_spinlock(&p_cond->mutex);

    if (p_cond->p_waiter_mutex == NULL) {
        p_cond->p_waiter_mutex = p_mutex;
    } else {
        ABT_bool result = ABTI_mutex_equal(p_cond->p_waiter_mutex, p_mutex);
        if (result == ABT_FALSE) {
            ABTI_mutex_unlock(&p_cond->mutex);
            abt_errno = ABT_ERR_INV_MUTEX;
            goto fn_fail;
        }
    }

    if (p_cond->num_waiters == 0) {
        p_unit->p_prev = p_unit;
        p_unit->p_next = p_unit;
        p_cond->p_head = p_unit;
        p_cond->p_tail = p_unit;
    } else {
        p_cond->p_tail->p_next = p_unit;
        p_cond->p_head->p_prev = p_unit;
        p_unit->p_prev = p_cond->p_tail;
        p_unit->p_next = p_cond->p_head;
        p_cond->p_tail = p_unit;
    }

    p_cond->num_waiters++;

    ABTI_mutex_unlock(&p_cond->mutex);

    /* Unlock the mutex that the calling ULT is holding */
    ABTI_mutex_unlock(p_mutex);

    while (!ext_signal) {
        double cur_time = get_cur_time();
        if (cur_time >= tar_time) {
            remove_unit(p_cond, p_unit);
            abt_errno = ABT_ERR_COND_TIMEDOUT;
            break;
        }
        ABT_thread_yield();
    }
    ABTU_free(p_unit);

    /* Lock the mutex again */
    ABTI_mutex_spinlock(p_mutex);

  fn_exit:
    return abt_errno;

  fn_fail:
    HANDLE_ERROR_FUNC_WITH_CODE(abt_errno);
    goto fn_exit;
}
Example #19
0
int main(int argc, char *argv[])
{
    int i, j;
    int ret, expected;
    int num_xstreams = DEFAULT_NUM_XSTREAMS;
    int num_threads = DEFAULT_NUM_THREADS;
    if (argc > 1) num_xstreams = atoi(argv[1]);
    assert(num_xstreams >= 0);
    if (argc > 2) num_threads = atoi(argv[2]);
    assert(num_threads >= 0);

    ABT_mutex mutex;
    ABT_xstream *xstreams;
    thread_arg_t **args;
    xstreams = (ABT_xstream *)malloc(sizeof(ABT_xstream) * num_xstreams);
    assert(xstreams != NULL);
    args = (thread_arg_t **)malloc(sizeof(thread_arg_t *) * num_xstreams);
    assert(args != NULL);
    for (i = 0; i < num_xstreams; i++) {
        args[i] = (thread_arg_t *)malloc(sizeof(thread_arg_t) * num_threads);
    }

    /* 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 a mutex */
    ret = ABT_mutex_create(&mutex);
    ABT_TEST_ERROR(ret, "ABT_mutex_create");

    /* Create threads */
    for (i = 0; i < num_xstreams; i++) {
        for (j = 0; j < num_threads; j++) {
            int tid = i * num_threads + j + 1;
            args[i][j].id = tid;
            args[i][j].mutex = mutex;
            ret = ABT_thread_create(pools[i],
                    thread_func, (void *)&args[i][j], ABT_THREAD_ATTR_NULL,
                    NULL);
            ABT_TEST_ERROR(ret, "ABT_thread_create");
        }
    }

    /* Switch to other user level threads */
    ABT_thread_yield();

    /* Join Execution Streams */
    for (i = 1; i < num_xstreams; i++) {
        ret = ABT_xstream_join(xstreams[i]);
        ABT_TEST_ERROR(ret, "ABT_xstream_join");
    }

    /* Free the mutex */
    ret = ABT_mutex_free(&mutex);
    ABT_TEST_ERROR(ret, "ABT_mutex_free");

    /* Free Execution Streams */
    for (i = 1; i < num_xstreams; i++) {
        ret = ABT_xstream_free(&xstreams[i]);
        ABT_TEST_ERROR(ret, "ABT_xstream_free");
    }

    /* Validation */
    expected = num_xstreams * num_threads;
    if (g_counter != expected) {
        printf("g_counter = %d\n", g_counter);
    }

    /* Finalize */
    ret = ABT_test_finalize(g_counter != expected);

    for (i = 0; i < num_xstreams; i++) {
        free(args[i]);
    }
    free(args);
    free(xstreams);
    free(pools);

    return ret;
}
Example #20
0
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[])
{
    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;
}