Exemple #1
0
int start_proc(void *args)
{
    hythread_thin_monitor_t *lock_p = (hythread_thin_monitor_t*)((void**)args)[0];
    hythread_thin_monitor_t *monitor_p = (hythread_thin_monitor_t*)((void**)args)[1];
    IDATA *ret =  (IDATA*)&(((void**)args)[2]);
    IDATA status;

    // wait to start
    hythread_suspend_disable();

    status = hythread_thin_monitor_enter(monitor_p);
    if (status != TM_ERROR_NONE) {
        hythread_suspend_enable();
        tf_assert_same(status, TM_ERROR_NONE);
    }

    // notify main thread about thread start
    status = hythread_thin_monitor_enter(lock_p);
    if (status != TM_ERROR_NONE) {
        hythread_suspend_enable();
        tf_assert_same(status, TM_ERROR_NONE);
    }
    started_thread_count++;
    status = hythread_thin_monitor_notify(lock_p);
    if (status != TM_ERROR_NONE) {
        hythread_suspend_enable();
        tf_assert_same(status, TM_ERROR_NONE);
    }
    status = hythread_thin_monitor_exit(lock_p);
    if (status != TM_ERROR_NONE) {
        hythread_suspend_enable();
        tf_assert_same(status, TM_ERROR_NONE);
    }

    // fall to infinite wait
    status = hythread_thin_monitor_wait(monitor_p);
    if (status != TM_ERROR_NONE) {
        hythread_suspend_enable();
        tf_assert_same(status, TM_ERROR_NONE);
    }

    (*ret)++;

    status = hythread_thin_monitor_exit(monitor_p);
    if (status != TM_ERROR_NONE) {
        hythread_suspend_enable();
        tf_assert_same(status, TM_ERROR_NONE);
    }
    hythread_suspend_enable();

    return 0;
}
/**
 * Gains the ownership over monitor.
 *
 * Current thread blocks if the specified monitor is owned by other thread.
 *
 * @param[in] monitor object where monitor is located
 * @sa JNI::MonitorEnter()
 */
IDATA VMCALL jthread_monitor_enter(jobject monitor)
{
    IDATA state;
    hythread_t native_thread;
    apr_time_t enter_begin;

    assert(monitor);
    hythread_suspend_disable();
    hythread_thin_monitor_t *lockword = vm_object_get_lockword_addr(monitor);
    IDATA status = hythread_thin_monitor_try_enter(lockword);
    if (status != TM_ERROR_EBUSY) {
        goto entered;
    }

#ifdef LOCK_RESERVATION
    // busy unreserve lock before blocking and inflating
    while (TM_ERROR_NONE != hythread_unreserve_lock(lockword)) {
        hythread_yield();
        hythread_safe_point();
        hythread_exception_safe_point();
        lockword = vm_object_get_lockword_addr(monitor);
    }
    status = hythread_thin_monitor_try_enter(lockword);
    if (status != TM_ERROR_EBUSY) {
        goto entered;
    }
#endif //LOCK_RESERVATION

    native_thread = hythread_self();
    hythread_thread_lock(native_thread);
    state = hythread_get_state(native_thread);
    state &= ~TM_THREAD_STATE_RUNNABLE;
    state |= TM_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;
    status = hythread_set_state(native_thread, state);
    assert(status == TM_ERROR_NONE);
    hythread_thread_unlock(native_thread);

    // should be moved to event handler
    if (ti_is_enabled()) {
        enter_begin = apr_time_now();
        int disable_count = hythread_reset_suspend_disable();
        jthread_set_owned_monitor(monitor);
        if(jvmti_should_report_event(JVMTI_EVENT_MONITOR_CONTENDED_ENTER)) {
            jvmti_send_contended_enter_or_entered_monitor_event(monitor, 1);
        }
        hythread_set_suspend_disable(disable_count);
    }

    // busy wait and inflate
    // reload pointer after safepoints
    lockword = vm_object_get_lockword_addr(monitor);
    while ((status =
            hythread_thin_monitor_try_enter(lockword)) == TM_ERROR_EBUSY)
    {
        hythread_safe_point();
        hythread_exception_safe_point();
        lockword = vm_object_get_lockword_addr(monitor);

        if (hythread_is_fat_lock(*lockword)) {
            status = hythread_thin_monitor_enter(lockword);
            if (status != TM_ERROR_NONE) {
                hythread_suspend_enable();
                assert(0);
                return status;
            }
            goto contended_entered;
        }
        hythread_yield();
    }
    assert(status == TM_ERROR_NONE);
    if (!hythread_is_fat_lock(*lockword)) {
        hythread_inflate_lock(lockword);
    }

// do all ti staff here
contended_entered:
    if (ti_is_enabled()) {
        int disable_count = hythread_reset_suspend_disable();
        if(jvmti_should_report_event(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED)) {
            jvmti_send_contended_enter_or_entered_monitor_event(monitor, 0);
        }
        hythread_set_suspend_disable(disable_count);
        // should be moved to event handler
        jvmti_thread_t jvmti_thread =
            jthread_get_jvmti_thread(hythread_self());
        jvmti_thread->blocked_time += apr_time_now() - enter_begin;
    }

    hythread_thread_lock(native_thread);
    state = hythread_get_state(native_thread);
    state &= ~TM_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;
    state |= TM_THREAD_STATE_RUNNABLE;
    status = hythread_set_state(native_thread, state);
    assert(status == TM_ERROR_NONE);
    hythread_thread_unlock(native_thread);

entered:
    if (ti_is_enabled()) {
        jthread_add_owned_monitor(monitor);
    }
    hythread_suspend_enable();
    return TM_ERROR_NONE;
} // jthread_monitor_enter
Exemple #3
0
int test_hythread_thread_suspend_all(void)
{
    void **args; 
    hythread_t thread_list[THREAD_COUNT];
    hythread_thin_monitor_t lock;
    hythread_thin_monitor_t monitor;
    IDATA status;
    int i;

    // create monitors
    status = hythread_thin_monitor_create(&monitor);
    tf_assert_same(status, TM_ERROR_NONE);
    status = hythread_thin_monitor_create(&lock);
    tf_assert_same(status, TM_ERROR_NONE);

    // alloc and set thread start procedure args
    args = (void**)calloc(3, sizeof(void*));
    args[0] = &lock;
    args[1] = &monitor;
    args[2] = 0;

    // create threads
    hythread_suspend_disable();
    status = hythread_thin_monitor_enter(&lock);
    tf_assert_same(status, TM_ERROR_NONE);
    hythread_suspend_enable();

    started_thread_count = 0;
    for(i = 0; i < THREAD_COUNT; i++) {
        thread_list[i] = NULL;
        status = hythread_create(&thread_list[i], 0, 0, 0,
            (hythread_entrypoint_t)start_proc, args);
        tf_assert_same(status, TM_ERROR_NONE);
        log_info("%d thread is started", i + 1);
    } 

    // waiting start of tested thread
    hythread_suspend_disable();
    while (started_thread_count < 10) {
        status = hythread_thin_monitor_wait(&lock);
        tf_assert_same(status, TM_ERROR_NONE);
    }

    status = hythread_thin_monitor_exit(&lock);
    tf_assert_same(status, TM_ERROR_NONE);
    hythread_suspend_enable();

    // suspend tested thread
    status = hythread_suspend_all(NULL, ((HyThread_public*)hythread_self())->group);
    tf_assert_same(status, TM_ERROR_NONE);
    log_info("all threads are suspended");

    // notify tested threads
    hythread_suspend_disable();
    status = hythread_thin_monitor_enter(&monitor);
    tf_assert_same(status, TM_ERROR_NONE);
    status = hythread_thin_monitor_notify_all(&monitor);
    tf_assert_same(status, TM_ERROR_NONE);
    status = hythread_thin_monitor_exit(&monitor);
    tf_assert_same(status, TM_ERROR_NONE);
    hythread_suspend_enable();
    log_info("notify all suspended threads");

    // check tested argument
    for(i = 0; i < 1000; i++) {
        tf_assert_same(args[2], 0);
        hythread_sleep(1);
    }

    // resume thread
    status = hythread_resume_all(((HyThread_public*)hythread_self())->group);
    tf_assert_same(status, TM_ERROR_NONE);
    log_info("resume all suspended threads");

    for(i = 0; i < THREAD_COUNT; i++) {
        test_thread_join(thread_list[i], i);
        log_info("%d thread is terminated", i + 1);
    }

    tf_assert_same((IDATA)args[2], THREAD_COUNT);

    return 0;
}
Exemple #4
0
int test_hythread_thread_suspend(void){
    void **args; 
    hythread_t thread = NULL;
    hythread_thin_monitor_t lock;
    hythread_thin_monitor_t monitor;
    IDATA status;
    int i;

    // create monitors
    status = hythread_thin_monitor_create(&lock);
    tf_assert_same(status, TM_ERROR_NONE);
    status = hythread_thin_monitor_create(&monitor);
    tf_assert_same(status, TM_ERROR_NONE);

    // alloc and set thread start procedure args
    args = (void**)calloc(3, sizeof(void*));
    args[0] = &lock;
    args[1] = &monitor;
    args[2] = 0;

    // create thread
    hythread_suspend_disable();
    status = hythread_thin_monitor_enter(&lock);
    tf_assert_same(status, TM_ERROR_NONE);
    hythread_suspend_enable();

    status = hythread_create(&thread, 0, 0, 0,
        (hythread_entrypoint_t)start_proc, args);
    tf_assert_same(status, TM_ERROR_NONE);

    // waiting start of tested thread
    hythread_suspend_disable();
    status = hythread_thin_monitor_wait(&lock);
    tf_assert_same(status, TM_ERROR_NONE);

    status = hythread_thin_monitor_exit(&lock);
    tf_assert_same(status, TM_ERROR_NONE);
    hythread_suspend_enable();

    // suspend tested thread
    status = hythread_suspend_other(thread);
    tf_assert_same(status, TM_ERROR_NONE);

    // notify tested thread
    hythread_suspend_disable();
    status = hythread_thin_monitor_enter(&monitor);
    tf_assert_same(status, TM_ERROR_NONE);
    status = hythread_thin_monitor_notify_all(&monitor);
    tf_assert_same(status, TM_ERROR_NONE);
    status = hythread_thin_monitor_exit(&monitor);
    tf_assert_same(status, TM_ERROR_NONE);
    hythread_suspend_enable();

    // check tested argument
    for(i = 0; i < 1000; i++) {
        tf_assert_same(args[2], 0);
        hythread_sleep(1);
    }

    // resume thread
    hythread_resume(thread);

    test_thread_join(thread, 1);
    
    tf_assert_same((IDATA)args[2], 1);

    return 0;
}