void tested_threads_init(int mode){
        
    tested_thread_sturct_t *tts;
    jobject monitor;
    jrawMonitorID raw_monitor;
    JNIEnv * jni_env;
    IDATA status; 
    int i;
    
    jni_env = jthread_get_JNI_env(jthread_self());
        
    if (mode != TTS_INIT_DIFFERENT_MONITORS){
        monitor = new_jobject();
        status = jthread_monitor_init(monitor);
        tf_assert_same_v(status, TM_ERROR_NONE);
    }
    status = jthread_raw_monitor_create(&raw_monitor);
    tf_assert_same_v(status, TM_ERROR_NONE);

    reset_tested_thread_iterator(&tts);
    for (i = 0; i < MAX_TESTED_THREAD_NUMBER; i++){
        tts = &tested_threads[i];
        tts->my_index = i;
        tts->java_thread = new_jobject_thread(jni_env);
        tts->native_thread = NULL;
        tts->jvmti_start_proc_arg = &tts->jvmti_start_proc_arg;
        hysem_create(&tts->started, 0, 1);
        hysem_create(&tts->running, 0, 1);
        hysem_create(&tts->stop_request, 0, 1);
        hysem_create(&tts->ended, 0, 1);
        tts->phase = TT_PHASE_NONE;
        if (mode == TTS_INIT_DIFFERENT_MONITORS){
            monitor = new_jobject();
            status = jthread_monitor_init(monitor);
            tf_assert_same_v(status, TM_ERROR_NONE);
        }
        tts->monitor = monitor;
        tts->raw_monitor = raw_monitor;
        tts->excn = NULL;
    }
}
int test_jthread_holds_lock(void) {

    tested_thread_sturct_t *tts;
    tested_thread_sturct_t *critical_tts = NULL;
    int blocked_count;
    int i;

    hysem_create(&mon_enter, 0, 1);

    // Initialize tts structures and run all tested threads
    tested_threads_run(run_for_test_jthread_holds_lock);
    

    for (i = 0; i < MAX_TESTED_THREAD_NUMBER; i++){
        blocked_count = 0;
        critical_tts = NULL;

        hysem_wait(mon_enter);

        reset_tested_thread_iterator(&tts);
        while(next_tested_thread(&tts)){
            while(tts->phase == TT_PHASE_NONE) {
                // thread is not started yet
                hythread_yield();
            }
            if (tts->phase == TT_PHASE_IN_CRITICAL_SECTON){
                tf_assert(jthread_holds_lock(tts->java_thread, tts->monitor) > 0);
                tf_assert_null(critical_tts);
                critical_tts = tts;
            } else if (tts->phase != TT_PHASE_DEAD){
                check_tested_thread_phase(tts, TT_PHASE_WAITING_ON_MONITOR);
                tf_assert(jthread_holds_lock(tts->java_thread, tts->monitor) == 0);
                if (tts->phase == TT_PHASE_WAITING_ON_MONITOR){
                    blocked_count++;
                }
            }
        }
        tf_assert(critical_tts); // thread in critical section found
        tf_assert_same(blocked_count, MAX_TESTED_THREAD_NUMBER - i - 1);
        tested_thread_send_stop_request(critical_tts);
        tested_thread_wait_ended(critical_tts);
        check_tested_thread_phase(critical_tts, TT_PHASE_DEAD);
    }

    // Terminate all threads and clear tts structures
    tested_threads_destroy();

    return TEST_PASSED;
}
int test_jthread_get_owned_monitors(void) {

    tested_thread_sturct_t *tts;
    tested_thread_sturct_t *critical_tts;
    int i;
    jint owned_monitors_count;
    jobject *owned_monitors = NULL;

    hysem_create(&mon_enter, 0, 1);

    // Initialize tts structures and run all tested threads
    tested_threads_run(run_for_test_jthread_get_owned_monitors);
    
    for (i = 0; i < MAX_TESTED_THREAD_NUMBER; i++){
        critical_tts = NULL;

        hysem_wait(mon_enter);

        reset_tested_thread_iterator(&tts);
        while(next_tested_thread(&tts)) {
            while(tts->phase == TT_PHASE_NONE) {
                // thread is not started yet
                hythread_yield();
            }
            if (tts->phase == TT_PHASE_IN_CRITICAL_SECTON){
                tf_assert_same(jthread_get_owned_monitors (tts->java_thread,
                    &owned_monitors_count, &owned_monitors), TM_ERROR_NONE);
                tf_assert(critical_tts == NULL);
                critical_tts = tts;
                tf_assert_same(owned_monitors_count, 1);
                tf_assert_same(owned_monitors[0]->object, tts->monitor->object);
            } else if (tts->phase == TT_PHASE_WAITING_ON_MONITOR){
                tf_assert_same(jthread_get_owned_monitors (tts->java_thread,
                    &owned_monitors_count, &owned_monitors), TM_ERROR_NONE);
                tf_assert_same(owned_monitors_count, 0);
            }
        }
        tf_assert(critical_tts);
        tested_thread_send_stop_request(critical_tts);
        tested_thread_wait_ended(critical_tts);
    }
    // Terminate all threads and clear tts structures
    tested_threads_destroy();

    return TEST_PASSED;
}
int test_jthread_get_contended_monitor(void) {

    tested_thread_sturct_t *tts;
    tested_thread_sturct_t *critical_tts = NULL;
    jobject contended_monitor;
    int i;

    hysem_create(&mon_enter, 0, 1);

    // Initialize tts structures and run all tested threads
    tested_threads_run(run_for_test_jthread_get_contended_monitor);
    
    for (i = 0; i < MAX_TESTED_THREAD_NUMBER; i++){
        critical_tts = NULL;
        
        hysem_wait(mon_enter);

        reset_tested_thread_iterator(&tts);
        while(next_tested_thread(&tts)){
            while(tts->phase == TT_PHASE_NONE) {
                // thread is not started yet
                hythread_yield();
            }
            if (tts->phase == TT_PHASE_IN_CRITICAL_SECTON){
                tf_assert_same(jthread_get_contended_monitor(tts->java_thread,
                    &contended_monitor), TM_ERROR_NONE);
                tf_assert_null(contended_monitor);
                tf_assert_null(critical_tts);
                critical_tts = tts;
            } else if (tts->phase != TT_PHASE_DEAD) {
                check_tested_thread_phase(tts, TT_PHASE_WAITING_ON_MONITOR);
                // This can't be guaranteed
                //tf_assert(vm_objects_are_equal(contended_monitor, tts->monitor));
            }
        }
        tested_thread_send_stop_request(critical_tts);
        tested_thread_wait_ended(critical_tts);
        check_tested_thread_phase(critical_tts, TT_PHASE_DEAD);
    }
    // Terminate all threads and clear tts structures
    tested_threads_destroy();

    return TEST_PASSED;
}
Exemplo n.º 5
0
/**
 * Initializes a new thread structure.
 */
IDATA VMCALL hythread_struct_init(hythread_t new_thread) 
{
    char jstatus;
    IDATA status;

    assert(new_thread);
    jstatus = new_thread->java_status;
    if (!new_thread->os_handle) {
        // new thread, create thread primitives
        memset(new_thread, 0, sizeof(HyThread));
        status = hysem_create(&new_thread->resume_event, 0, 1);
        assert(status == TM_ERROR_NONE);
        status = port_mutex_create(&new_thread->mutex, APR_THREAD_MUTEX_NESTED);
        assert(status == TM_ERROR_NONE);
        status = hythread_monitor_init(&new_thread->monitor, 0);
        assert(status == TM_ERROR_NONE);
    } else {
        // old thread, reset structure
        int result;
        hysem_t resume;
        osmutex_t mutex;
        hythread_monitor_t monitor;

        // release thread OS handle
        result = port_thread_free_handle(new_thread->os_handle);
        assert(0 == result);

        resume = new_thread->resume_event;
        mutex = new_thread->mutex;
        monitor = new_thread->monitor;

        // zero new thread
        memset(new_thread, 0, sizeof(HyThread));

        new_thread->resume_event = resume;
        new_thread->mutex = mutex;
        new_thread->monitor = monitor;
    }
    assert(new_thread->os_handle == 0);

    new_thread->java_status = jstatus;
    new_thread->priority   = HYTHREAD_PRIORITY_NORMAL;


#ifdef ORDER
    new_thread->alloc_count = 0;
    new_thread->thread_create_count = 0;
    new_thread->p_tid = 0;
    new_thread->p_count = 0;
//    new_thread->isInVMRegistry = 0;
#endif


    port_mutex_lock(&new_thread->mutex);
    new_thread->state = TM_THREAD_STATE_NEW;
    port_mutex_unlock(&new_thread->mutex);

    status = hysem_set(new_thread->resume_event, 0);
    assert(status == TM_ERROR_NONE);

    return TM_ERROR_NONE;
}