static void * bct_thread(void *unused) { int res; ethr_mutex_lock(&bct_mutex); while (!bct_done) { bct_waiting++; if (bct_waiting == BCT_THREADS) ethr_cond_signal(&bct_cntrl_cond); do { res = ethr_cond_wait(&bct_cond, &bct_mutex); } while (res == EINTR); ASSERT(res == 0); bct_woken++; if (bct_woken == BCT_THREADS) ethr_cond_signal(&bct_cntrl_cond); } ethr_mutex_unlock(&bct_mutex); return NULL; }
static void * tlmt_thread(void *unused) { int res; ethr_mutex_lock(&tlmt_mtx1); ethr_mutex_lock(&tlmt_mtx2); tlmt_mtx1_locked = 1; ethr_cond_signal(&tlmt_cnd2); while (!tlmt_mtx1_do_unlock) { res = ethr_cond_wait(&tlmt_cnd2, &tlmt_mtx2); ASSERT(res == 0 || res == EINTR); } ethr_mutex_unlock(&tlmt_mtx2); ethr_mutex_unlock(&tlmt_mtx1); ethr_mutex_lock(&tlmt_mtx2); tlmt_mtx1_locked = 0; ethr_cond_signal(&tlmt_cnd2); ethr_mutex_unlock(&tlmt_mtx2); return NULL; }
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); }
void erl_drv_cond_signal(ErlDrvCond *dcnd) { #ifdef USE_THREADS if (!dcnd) fatal_error(EINVAL, "erl_drv_cond_signal()"); ethr_cond_signal(&dcnd->cnd); #endif }
void erl_drv_cond_signal(ErlDrvCond *dcnd) { #ifdef USE_THREADS int res = dcnd ? ethr_cond_signal(&dcnd->cnd) : EINVAL; if (res != 0) fatal_error(res, "erl_drv_cond_signal()"); #endif }
static void * dt_thread(void *unused) { ethr_mutex_lock(&dt_mutex); dt_count++; if (dt_count >= dt_limit) ethr_cond_signal(&dt_cond); ethr_mutex_unlock(&dt_mutex); return NULL; }
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 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); }