コード例 #1
0
ファイル: ethread_tests.c プロジェクト: 0x00evil/otp
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);
}
コード例 #2
0
ファイル: erl_lock_count.c プロジェクト: DavidPajaro/otp
void erts_lcnt_init() {
    erts_lcnt_thread_data_t *eltd = NULL;
    
    /* init lock */
    if (ethr_mutex_init(&lcnt_data_lock) != 0) abort();

    /* init tsd */    
    lcnt_n_thr = 0;

    ethr_tsd_key_create(&lcnt_thr_data_key);

    lcnt_lock();

    erts_lcnt_rt_options = ERTS_LCNT_OPT_PROCLOCK | ERTS_LCNT_OPT_LOCATION;
    
    eltd = lcnt_thread_data_alloc();

    ethr_tsd_set(lcnt_thr_data_key, eltd);
    
    /* init lcnt structure */
    erts_lcnt_data = (erts_lcnt_data_t*)malloc(sizeof(erts_lcnt_data_t));
    erts_lcnt_data->current_locks = erts_lcnt_list_init();
    erts_lcnt_data->deleted_locks = erts_lcnt_list_init();

    lcnt_unlock();

    /* set start timer and zero statistics */
    erts_lcnt_clear_counters();
}
コード例 #3
0
ファイル: erl_lock_check.c プロジェクト: system/erlang-otp
void
erts_lc_init(void)
{
#ifdef ERTS_LC_STATIC_ALLOC
    int i;
    static erts_lc_free_block_t fbs[ERTS_LC_FB_CHUNK_SIZE];
    for (i = 0; i < ERTS_LC_FB_CHUNK_SIZE - 1; i++) {
#ifdef DEBUG
        memset((void *) &fbs[i], 0xdf, sizeof(erts_lc_free_block_t));
#endif
        fbs[i].next = &fbs[i+1];
    }
#ifdef DEBUG
    memset((void *) &fbs[ERTS_LC_FB_CHUNK_SIZE-1],
           0xdf, sizeof(erts_lc_free_block_t));
#endif
    fbs[ERTS_LC_FB_CHUNK_SIZE-1].next = NULL;
    free_blocks = &fbs[0];
#else /* #ifdef ERTS_LC_STATIC_ALLOC */
    free_blocks = NULL;
#endif /* #ifdef ERTS_LC_STATIC_ALLOC */

#ifdef ETHR_HAVE_NATIVE_LOCKS
    if (ethr_spinlock_init(&free_blocks_lock) != 0)
        abort();
#else
    if (ethr_mutex_init(&free_blocks_lock) != 0)
        abort();
#endif

    erts_tsd_key_create(&locks_key);
}
コード例 #4
0
ファイル: ethread_tests.c プロジェクト: 0x00evil/otp
static void
max_threads_test(void)
{
    int no_threads[MTT_TIMES], i, up, down, eq, res;
    char *str;

    res = ethr_mutex_init(&mtt_mutex);
    ASSERT(res == 0);
    res = ethr_cond_init(&mtt_cond);
    ASSERT(res == 0);

    for (i = 0; i < MTT_TIMES; i++) {
	no_threads[i] = mtt_create_join_threads();
    }

    str = &mtt_string[0];
    eq = up = down = 0;
    for (i = 0; i < MTT_TIMES; i++) {
	if (i == 0) {
	    str += sprintf(str, "%d", no_threads[i]);
	    continue;
	}

	str += sprintf(str, ", %d", no_threads[i]);

	if (no_threads[i] < no_threads[i-1])
	    down++;
	else if (no_threads[i] > no_threads[i-1])
	    up++;
	else
	    eq++;
    }

    print_line("Max created threads: %s", mtt_string);

    /* We fail if the no of threads we are able to create constantly decrease */
    ASSERT(!down || up || eq);

    succeed("Max created threads: %s", mtt_string);

}
コード例 #5
0
ファイル: ethread_tests.c プロジェクト: 0x00evil/otp
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);
}
コード例 #6
0
ファイル: erl_drv_thread.c プロジェクト: AugustoFernandes/otp
ErlDrvMutex *
erl_drv_mutex_create(char *name)
{
#ifdef USE_THREADS
    ErlDrvMutex *dmtx = erts_alloc_fnf(ERTS_ALC_T_DRV_MTX,
				       (sizeof(ErlDrvMutex)
					+ (name ? sys_strlen(name) + 1 : 0)));
    if (dmtx) {
	if (ethr_mutex_init(&dmtx->mtx) != 0) {
	    erts_free(ERTS_ALC_T_DRV_MTX, (void *) dmtx);
	    dmtx = NULL;
	}
	else if (!name)
	    dmtx->name = no_name;
	else {
	    dmtx->name = ((char *) dmtx) + sizeof(ErlDrvMutex);
	    sys_strcpy(dmtx->name, name);
	}
    }
    return dmtx;
#else
    return (ErlDrvMutex *) NULL;
#endif
}
コード例 #7
0
ファイル: ethread_tests.c プロジェクト: 0x00evil/otp
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);

}
コード例 #8
0
ファイル: ethread_tests.c プロジェクト: 0x00evil/otp
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);

}
コード例 #9
0
ファイル: ethread_tests.c プロジェクト: 0x00evil/otp
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");

}
コード例 #10
0
ファイル: ethread_tests.c プロジェクト: 0x00evil/otp
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);

}