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); } }
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); }
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); }
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; }
int erl_drv_thread_join(ErlDrvTid tid, void **respp) { #ifdef USE_THREADS int res; struct ErlDrvTid_ *dtid = (struct ErlDrvTid_ *) tid; ASSERT(dtid); if (!dtid->drv_thr) return EINVAL; res = ethr_thr_join(dtid->tid, respp); if (res == 0) erts_free(ERTS_ALC_T_DRV_TID, dtid); return res; #else return ENOTSUP; #endif }
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); } }
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); }
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); }
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"); }
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); }
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"); }
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"); }