Пример #1
0
static void
tsd_test(void)
{
    void *tres;
    int i, res;
    ethr_tid tid[TT_THREADS];
    int values[TT_THREADS];

    res = ethr_tsd_key_create(&tt_key,"tsd_test");
    ASSERT(res == 0);

    for (i = 1; i < TT_THREADS; i++) {
	res = ethr_thr_create(&tid[i], tt_thread, (void *) &values[i], NULL);
	ASSERT(res == 0);
    }

    tres = tt_thread((void *) &values[0]);
    ASSERT(tres == (void *) &values[0]);

    for (i = 1; i < TT_THREADS; i++) {
	res = ethr_thr_join(tid[i], &tres);
	ASSERT(res == 0);
	ASSERT(tres == (void *) &values[i]);
    }

    res = ethr_tsd_key_delete(tt_key);
    ASSERT(res == 0);
}
Пример #2
0
static void
create_join_thread_test(void)
{
    int i, res;

    for (i = 1; i <= CJTT_NO_THREADS; i++) {
	cjtt_ix[i] = i;
	cjtt_res[i] = 0;
    }

    for (i = 1; i <= CJTT_NO_THREADS; i++) {
	res = ethr_thr_create(&cjtt_tids[i],
			      cjtt_thread,
			      (void *) &cjtt_ix[i],
			      NULL);
	ASSERT(res == 0);
    }

    for (i = 1; i <= CJTT_NO_THREADS; i++) {
	void *tres;
	res = ethr_thr_join(cjtt_tids[i], &tres);
	ASSERT(res == 0);
	ASSERT(tres == &cjtt_res[i]);
	ASSERT(cjtt_res[i] == i);
    }

}
Пример #3
0
static void
try_lock_mutex_test(void)
{
    int i, res;
    ethr_tid tid;

    res = ethr_mutex_init(&tlmt_mtx1);
    ASSERT(res == 0);
    res = ethr_mutex_init(&tlmt_mtx2);
    ASSERT(res == 0);
    res = ethr_cond_init(&tlmt_cnd2);
    ASSERT(res == 0);

    tlmt_mtx1_locked = 0;
    tlmt_mtx1_do_unlock = 0;

    res = ethr_thr_create(&tid, tlmt_thread, NULL, NULL);
    ASSERT(res == 0);

    ethr_mutex_lock(&tlmt_mtx2);

    while (!tlmt_mtx1_locked) {
	res = ethr_cond_wait(&tlmt_cnd2, &tlmt_mtx2);
	ASSERT(res == 0 || res == EINTR);
    }

    ethr_mutex_unlock(&tlmt_mtx2);

    for (i = 0; i < 10; i++) {
	res = ethr_mutex_trylock(&tlmt_mtx1);
	ASSERT(res == EBUSY);
    }

    ethr_mutex_lock(&tlmt_mtx2);

    tlmt_mtx1_do_unlock = 1;
    ethr_cond_signal(&tlmt_cnd2);

    while (tlmt_mtx1_locked) {
	res = ethr_cond_wait(&tlmt_cnd2, &tlmt_mtx2);
	ASSERT(res == 0 || res == EINTR);
    }

    ethr_mutex_unlock(&tlmt_mtx2);

    res = ethr_mutex_trylock(&tlmt_mtx1);
    ASSERT(res == 0);

    ethr_mutex_unlock(&tlmt_mtx1);

    res = ethr_thr_join(tid, NULL);
    ASSERT(res == 0);

    res = ethr_mutex_destroy(&tlmt_mtx1);
    ASSERT(res == 0);
    res = ethr_mutex_destroy(&tlmt_mtx2);
    ASSERT(res == 0);
    res = ethr_cond_destroy(&tlmt_cnd2);
    ASSERT(res == 0);
}
Пример #4
0
int
erl_drv_thread_create(char *name,
		      ErlDrvTid *tid,
		      void* (*func)(void*),
		      void* arg,
		      ErlDrvThreadOpts *opts)
{
#ifdef USE_THREADS
    int res;
    struct ErlDrvTid_ *dtid;
    ethr_thr_opts ethr_opts;
    ethr_thr_opts *use_opts;

    if (!opts)
	use_opts = NULL;
    else {
	sys_memcpy((void *) &ethr_opts,
		   (void *) &def_ethr_opts,
		   sizeof(ethr_thr_opts));
	ethr_opts.suggested_stack_size = opts->suggested_stack_size;
	use_opts = &ethr_opts;
    }

    dtid = erts_alloc_fnf(ERTS_ALC_T_DRV_TID,
			  (sizeof(struct ErlDrvTid_)
			   + (name ? sys_strlen(name) + 1 : 0)));
    if (!dtid)
	return ENOMEM;

    dtid->drv_thr = 1;
    dtid->func = func;
    dtid->arg = arg;
    dtid->tsd = NULL;
    dtid->tsd_len = 0;
    if (!name)
	dtid->name = no_name;
    else {
	dtid->name = ((char *) dtid) + sizeof(struct ErlDrvTid_);
	sys_strcpy(dtid->name, name);
    }
#ifdef ERTS_ENABLE_LOCK_COUNT
    res = erts_lcnt_thr_create(&dtid->tid, erl_drv_thread_wrapper, dtid, use_opts);
#else
    res = ethr_thr_create(&dtid->tid, erl_drv_thread_wrapper, dtid, use_opts);
#endif

    if (res != 0) {
	erts_free(ERTS_ALC_T_DRV_TID, dtid);
	return res;
    }

    *tid = (ErlDrvTid) dtid;
    return 0;
#else
    return ENOTSUP;
#endif
}
Пример #5
0
static int
mtt_create_join_threads(void)
{
    int no_tids = 100, ix = 0, res = 0, no_threads;
    ethr_tid *tids;

    mtt_terminate = 0;

    tids = (ethr_tid *) malloc(sizeof(ethr_tid)*no_tids);
    ASSERT(tids);

    print_line("Beginning to create threads");

    while (1) {
	if (ix >= no_tids) {
	    no_tids += 100;
	    if (no_tids > MTT_HARD_LIMIT) {
		print_line("Hit the hard limit on number of threads (%d)!", 
			   MTT_HARD_LIMIT);
		break;
	    }
	    tids = (ethr_tid *) realloc((void *)tids, sizeof(ethr_tid)*no_tids);
	    ASSERT(tids);
	}
	res = ethr_thr_create(&tids[ix], mtt_thread, NULL, NULL);
	if (res != 0) {
	    break;
	}
	ix++;
    }

    no_threads = ix;

    print_line("%d = ethr_thr_create()", res);
    print_line("Number of created threads: %d", no_threads);

    ethr_mutex_lock(&mtt_mutex);

    mtt_terminate = 1;

    ethr_cond_broadcast(&mtt_cond);

    ethr_mutex_unlock(&mtt_mutex);

    while (ix) {
	res = ethr_thr_join(tids[--ix], NULL);
	ASSERT(res == 0);
    }

    print_line("All created threads terminated");

    free((void *) tids);

    return no_threads;

}
Пример #6
0
static void
dw_atomic_massage_test(void)
{
    int i, res;
    ethr_tid tid[AT_DW_THREADS];
    ethr_thr_opts thr_opts = ETHR_THR_OPTS_DEFAULT_INITER;
    ethr_dw_sint_t dw;

    dw.sint[0] = dw.sint[1] = 0;

    ethr_dw_atomic_init(&at_dw_atomic, &dw);

    for (i = AT_DW_MIN; i <= AT_DW_MAX; i++) {
	ethr_sint_t val;
	memset(&val, i, sizeof(ethr_sint_t));
	res = ethr_thr_create(&tid[i-AT_DW_MIN], at_dw_thr, (void *) val, &thr_opts);
	ASSERT(res == 0);
    }
    for (i = AT_DW_MIN; i <= AT_DW_MAX; i++) {
	res = ethr_thr_join(tid[i-AT_DW_MIN], NULL);
	ASSERT(res == 0);
    }
}
Пример #7
0
static void
detached_thread_test(void)
{
    ethr_thr_opts thr_opts = ETHR_THR_OPTS_DEFAULT_INITER;
    ethr_tid tid[DT_BATCH_SIZE];
    int i, j, res;

    res = ethr_mutex_init(&dt_mutex);
    ASSERT(res == 0);
    res = ethr_cond_init(&dt_cond);
    ASSERT(res == 0);

    thr_opts.detached = 1;
    dt_count = 0;
    dt_limit = 0;

    for (i = 0; i < DT_THREADS/DT_BATCH_SIZE; i++) {

	dt_limit += DT_BATCH_SIZE;

	for (j = 0; j < DT_BATCH_SIZE; j++) {
	    res = ethr_thr_create(&tid[j], dt_thread, NULL, &thr_opts);
	    ASSERT(res == 0);
	}

	ethr_mutex_lock(&dt_mutex);
	while (dt_count < dt_limit) {
	    res = ethr_cond_wait(&dt_cond, &dt_mutex);
	    ASSERT(res == 0 || res == EINTR);
	}
	ethr_mutex_unlock(&dt_mutex);

	print_line("dt_count = %d", dt_count);
    }
    do_sleep(1);
}
Пример #8
0
static void
broadcast_test(void)
{
    int res, i;
    ethr_tid tid[BCT_THREADS];

    res = ethr_mutex_init(&bct_mutex);
    ASSERT(res == 0);
    res = ethr_cond_init(&bct_cntrl_cond);
    ASSERT(res == 0);
    res = ethr_cond_init(&bct_cond);
    ASSERT(res == 0);

    for (i = 0; i < BCT_THREADS; i++) {
	res = ethr_thr_create(&tid[i], bct_thread, NULL, NULL);
	ASSERT(res == 0);

    }

    ethr_mutex_lock(&bct_mutex);

    for (i = 0; i < BCT_NO_OF_WAITS; i++) {

	while (bct_waiting != BCT_THREADS) {
	    res = ethr_cond_wait(&bct_cntrl_cond, &bct_mutex);
	    ASSERT(res == 0 || res == EINTR);
	}

	bct_waiting = 0;
	bct_woken = 0;

	/* Wake all threads */
	ethr_cond_broadcast(&bct_cond);

	while (bct_woken != BCT_THREADS) {
	    res = ethr_cond_wait(&bct_cntrl_cond, &bct_mutex);
	    ASSERT(res == 0 || res == EINTR);
	}

    }

    bct_done = 1;

    /* Wake all threads */
    ethr_cond_broadcast(&bct_cond);

    ethr_mutex_unlock(&bct_mutex);

    for (i = 0; i < BCT_THREADS; i++) {
	res = ethr_thr_join(tid[i], NULL);
	ASSERT(res == 0);
    }

    res = ethr_mutex_destroy(&bct_mutex);
    ASSERT(res == 0);
    res = ethr_cond_destroy(&bct_cntrl_cond);
    ASSERT(res == 0);
    res = ethr_cond_destroy(&bct_cond);
    ASSERT(res == 0);

}
Пример #9
0
static void
cond_wait_test(void)
{
    ethr_tid tid1, tid2;
    int res;

    res = ethr_mutex_init(&cwt_mutex);
    ASSERT(res == 0);
    res = ethr_cond_init(&cwt_cond);
    ASSERT(res == 0);

    /* Wake with signal */

    cwt_counter = 0;

    res = ethr_thr_create(&tid1, cwt_thread, NULL, NULL);
    ASSERT(res == 0);
    res = ethr_thr_create(&tid2, cwt_thread, NULL, NULL);
    ASSERT(res == 0);

    do_sleep(1); /* Make sure threads waits on cond var */

    ethr_mutex_lock(&cwt_mutex);

    ethr_cond_signal(&cwt_cond); /* Wake one thread */

    do_sleep(1); /* Make sure awakened thread waits on mutex */

    ASSERT(cwt_counter == 0);

    ethr_mutex_unlock(&cwt_mutex);

    do_sleep(1);  /* Let awakened thread proceed */

    ethr_mutex_lock(&cwt_mutex);

    ASSERT(cwt_counter == 1);

    ethr_cond_signal(&cwt_cond); /* Wake the other thread */

    do_sleep(1); /* Make sure awakened thread waits on mutex */

    ASSERT(cwt_counter == 1);

    ethr_mutex_unlock(&cwt_mutex);

    do_sleep(1);  /* Let awakened thread proceed */

    ethr_mutex_lock(&cwt_mutex);

    ASSERT(cwt_counter == 2);

    ethr_mutex_unlock(&cwt_mutex);

    res = ethr_thr_join(tid1, NULL);
    ASSERT(res == 0);

    res = ethr_thr_join(tid2, NULL);
    ASSERT(res == 0);


    /* Wake with broadcast */

    cwt_counter = 0;

    res = ethr_thr_create(&tid1, cwt_thread, NULL, NULL);
    ASSERT(res == 0);
    res = ethr_thr_create(&tid2, cwt_thread, NULL, NULL);
    ASSERT(res == 0);

    do_sleep(1); /* Make sure threads waits on cond var */

    ethr_mutex_lock(&cwt_mutex);

    ethr_cond_broadcast(&cwt_cond); /* Wake the threads */

    do_sleep(1); /* Make sure awakened threads wait on mutex */

    ASSERT(cwt_counter == 0);

    ethr_mutex_unlock(&cwt_mutex);

    do_sleep(1);  /* Let awakened threads proceed */

    ethr_mutex_lock(&cwt_mutex);

    ASSERT(cwt_counter == 2);

    ethr_mutex_unlock(&cwt_mutex);

    res = ethr_thr_join(tid1, NULL);
    ASSERT(res == 0);

    res = ethr_thr_join(tid2, NULL);
    ASSERT(res == 0);

    res = ethr_mutex_destroy(&cwt_mutex);
    ASSERT(res == 0);
    res = ethr_cond_destroy(&cwt_cond);
    ASSERT(res == 0);

}
Пример #10
0
static void
mutex_test(void)
{
    int res;
    ethr_tid tid;

    print_line("Trying to initialize mutex");
    res = ethr_mutex_init(&mt_mutex);
    ASSERT(res == 0);
    print_line("Initialized mutex");

    mt_data = 0;

    print_line("Main thread tries to lock mutex");
    ethr_mutex_lock(&mt_mutex);
    print_line("Main thread locked mutex");

    ASSERT(mt_data == 0);

    print_line("Main thread about to create aux thread");
    res = ethr_thr_create(&tid, mt_thread, NULL, NULL);
    ASSERT(res == 0);
    print_line("Main thread created aux thread");

    print_line("Main thread goes to sleep for 1 second");
    do_sleep(1);
    print_line("Main thread woke up");

    ASSERT(mt_data == 0);

    ethr_mutex_unlock(&mt_mutex);
    print_line("Main thread unlocked mutex");

    print_line("Main thread goes to sleep for 1 second");
    do_sleep(1);
    print_line("Main thread woke up");

    print_line("Main thread tries to lock mutex");
    ethr_mutex_lock(&mt_mutex);
    print_line("Main thread locked mutex");

    ASSERT(mt_data == 1);

    print_line("Main thread goes to sleep for 1 second");
    do_sleep(1);
    print_line("Main thread woke up");

    ASSERT(mt_data == 1);

    ethr_mutex_unlock(&mt_mutex);
    print_line("Main thread unlocked mutex");

    res = ethr_thr_join(tid, NULL);
    ASSERT(res == 0);
    print_line("Main thread joined aux thread");

    res = ethr_mutex_destroy(&mt_mutex);
    ASSERT(res == 0);
    print_line("Main thread destroyed mutex");

}
Пример #11
0
static void
equal_tids_test(void)
{
    int res, i;

    res = ethr_mutex_init(&ett_mutex);
    ASSERT(res == 0);
    res = ethr_cond_init(&ett_cond);
    ASSERT(res == 0);
    ett_tids[0] = ethr_self();
    
    res = ethr_thr_create(&ett_tids[1], ett_thread, (void *) &ett_tids[1], NULL);
    ASSERT(res == 0);

    ASSERT(ethr_equal_tids(ethr_self(), ett_tids[0]));
    ASSERT(!ethr_equal_tids(ethr_self(), ett_tids[1]));

    res = ethr_thr_join(ett_tids[1], NULL);

    res = ethr_thr_create(&ett_tids[2], ett_thread, (void *) &ett_tids[2], NULL);
    ASSERT(res == 0);

    ASSERT(ethr_equal_tids(ethr_self(), ett_tids[0]));
    ASSERT(!ethr_equal_tids(ethr_self(), ett_tids[1]));
    ASSERT(!ethr_equal_tids(ethr_self(), ett_tids[2]));

#if 0
    /* This fails on some linux platforms. Until we decides if a tid
     * is allowed to be reused right away or not, we disable the test.
     */

    ASSERT(!ethr_equal_tids(ett_tids[1], ett_tids[2]));
#endif

    res = ethr_thr_join(ett_tids[2], NULL);
    ASSERT(res == 0);

    /* Second part of test */

    ett_terminate = 0;

    res = ethr_thr_create(&ett_tids[1], ett_thread2, NULL, NULL);
    ASSERT(res == 0);

    ASSERT(!ethr_equal_tids(ett_tids[0], ett_tids[1]));

    for (i = 0; i < ETT_THREADS; i++) {
	res = ethr_thr_create(&ett_tids[2], ett_thread, (void*)&ett_tids[2], NULL);
	ASSERT(res == 0);

	ASSERT(!ethr_equal_tids(ett_tids[0], ett_tids[2]));
	ASSERT(!ethr_equal_tids(ett_tids[1], ett_tids[2]));

	res = ethr_thr_join(ett_tids[2], NULL);
	ASSERT(res == 0);
    }

    ethr_mutex_lock(&ett_mutex);
    ett_terminate = 1;
    ethr_cond_signal(&ett_cond);
    ethr_mutex_unlock(&ett_mutex);
    res = ethr_thr_join(ett_tids[1], NULL);
    ASSERT(res == 0);

    res = ethr_cond_destroy(&ett_cond);
    ASSERT(res == 0);
    res = ethr_mutex_destroy(&ett_mutex);
    ASSERT(res == 0);

}
Пример #12
0
static void
atomic_test(void)
{
    long data_init, data_final, val;
    int res, i;
    ethr_tid tid[AT_THREADS];
    ethr_thr_opts thr_opts = ETHR_THR_OPTS_DEFAULT_INITER;

    atomic_basic_test();

#if ETHR_SIZEOF_PTR > 4
	at_rm_val = ((long) 1) << 57;
	at_set_val = ((long) 1) << 60;
#else
	at_rm_val = ((long) 1) << 27;
	at_set_val = ((long) 1) << 30;
#endif

    at_max_val = at_set_val + at_rm_val + ((long) AT_THREADS + 1) * 4711;
    data_init = at_rm_val + (long) 4711;
    data_final = at_set_val + (long) 4711;

    thr_opts.detached = 1;

    print_line("Initializing");
    ethr_atomic_init(&at_ready, 0);
    ethr_atomic_init(&at_go, 0);
    ethr_atomic_init(&at_done, data_init);
    ethr_atomic_init(&at_data, data_init);

    val = ethr_atomic_read(&at_data);
    ASSERT(val == data_init);
    ethr_atomic_set(&at_done, 0);
    val = ethr_atomic_read(&at_done);
    ASSERT(val == 0);

    print_line("Creating threads");
    for (i = 0; i < AT_THREADS; i++) {
	res = ethr_thr_create(&tid[i], at_thread, NULL, &thr_opts);
	ASSERT(res == 0);
    }

    print_line("Waiting for threads to ready up");
    do {
	val = ethr_atomic_read(&at_ready);
	ASSERT(val >= 0);
	ASSERT(val <= AT_THREADS);
    } while (val != AT_THREADS);

    print_line("Letting threads loose");
    val = ethr_atomic_xchg(&at_go, 17);
    ASSERT(val == 0);
    val = ethr_atomic_read(&at_go);
    ASSERT(val == 17);


    print_line("Waiting for threads to finish");
    do {
	val = ethr_atomic_read(&at_done);
	ASSERT(val >= 0);
	ASSERT(val <= AT_THREADS);
    } while (val != AT_THREADS);

    print_line("Checking result");
    val = ethr_atomic_read(&at_data);
    ASSERT(res == 0);
    ASSERT(val == data_final);
    print_line("Result ok");
    
}
Пример #13
0
static void
rwmutex_test(void)
{
    int data;
    int res;
    ethr_tid tid;

    print_line("Trying to initialize rwmutex");
    res = ethr_rwmutex_init(&rwmt_rwmutex);
    ASSERT(res == 0);
    print_line("Initialized rwmutex");

    rwmt_data = 4711;

    print_line("Main thread tries to read lock rwmutex");
    ethr_rwmutex_rlock(&rwmt_rwmutex);
    print_line("Main thread read locked rwmutex");

    ASSERT(rwmt_data == 4711);

    print_line("Main thread about to create aux thread");
    res = ethr_thr_create(&tid, rwmt_thread, NULL, NULL);
    ASSERT(res == 0);
    print_line("Main thread created aux thread");

    print_line("Main thread goes to sleep for 1 second");
    do_sleep(1);
    print_line("Main thread woke up");

    ASSERT(rwmt_data == 4711);

    print_line("Main thread tries to read unlock rwmutex");
    ethr_rwmutex_runlock(&rwmt_rwmutex);
    print_line("Main thread read unlocked rwmutex");

    print_line("Main thread tries to write lock rwmutex");
    ethr_rwmutex_rwlock(&rwmt_rwmutex);
    print_line("Main thread write locked rwmutex");

    data = ++rwmt_data;

    print_line("Main thread goes to sleep for 1 second");
    do_sleep(1);
    print_line("Main thread woke up");

    ASSERT(rwmt_data == data);
    ++rwmt_data;

    print_line("Main thread tries to write unlock rwmutex");
    ethr_rwmutex_rwunlock(&rwmt_rwmutex);
    print_line("Main thread write unlocked rwmutex");

    res = ethr_thr_join(tid, NULL);
    ASSERT(res == 0);
    print_line("Main thread joined aux thread");

    res = ethr_rwmutex_destroy(&rwmt_rwmutex);
    ASSERT(res == 0);
    print_line("Main thread destroyed rwmutex");

}
Пример #14
0
static void
spinlock_test(void)
{
    int res;
    ethr_tid tid;

    print_line("Trying to initialize spinlock");
    res = ethr_spinlock_init(&st_spinlock);
    ASSERT(res == 0);
    print_line("Initialized spinlock");

    st_data = 0;

    print_line("Main thread tries to lock spinlock");
    ethr_spin_lock(&st_spinlock);
    print_line("Main thread locked spinlock");

    ASSERT(st_data == 0);

    print_line("Main thread about to create aux thread");
    res = ethr_thr_create(&tid, st_thread, NULL, NULL);
    ASSERT(res == 0);
    print_line("Main thread created aux thread");

    print_line("Main thread goes to sleep for 1 second");
    do_sleep(1);
    print_line("Main thread woke up");

    ASSERT(st_data == 0);

    ethr_spin_unlock(&st_spinlock);
    print_line("Main thread unlocked spinlock");

    print_line("Main thread goes to sleep for 1 second");
    do_sleep(1);
    print_line("Main thread woke up");

    print_line("Main thread tries to lock spinlock");
    ethr_spin_lock(&st_spinlock);
    print_line("Main thread locked spinlock");

    ASSERT(st_data == 1);

    print_line("Main thread goes to sleep for 1 second");
    do_sleep(1);
    print_line("Main thread woke up");

    ASSERT(st_data == 1);

    ethr_spin_unlock(&st_spinlock);
    print_line("Main thread unlocked spinlock");

    res = ethr_thr_join(tid, NULL);
    ASSERT(res == 0);
    print_line("Main thread joined aux thread");

    res = ethr_spinlock_destroy(&st_spinlock);
    ASSERT(res == 0);
    print_line("Main thread destroyed spinlock");

}