Пример #1
0
/**
 *  Initializes Java monitor.
 *
 *  Monitor is a recursive lock with one conditional variable associated with it.
 *  Implementation may use the knowledge of internal object layout in order to allocate lock
 *  and conditional variable in the most efficient manner.
 *
 *  @param[in] monitor object where monitor needs to be initialized.
 */
IDATA VMCALL jthread_monitor_init(jobject monitor)
{
    assert(monitor);

    hythread_suspend_disable();
    hythread_thin_monitor_t *lockword = vm_object_get_lockword_addr(monitor);
    IDATA status = hythread_thin_monitor_create(lockword);
    hythread_suspend_enable();
    return status;
} // jthread_monitor_init
Пример #2
0
/**
 * Completely releases the ownership over monitor.
 *
 * @param[in] monitor monitor
 */
IDATA VMCALL jthread_monitor_release(jobject monitor)
{
    assert(monitor);

    hythread_suspend_disable();
    hythread_thin_monitor_t *lockword = vm_object_get_lockword_addr(monitor);
    IDATA status = hythread_thin_monitor_release(lockword);
    assert(status == TM_ERROR_NONE);
    hythread_suspend_enable();

    return TM_ERROR_NONE;
} // jthread_monitor_release
Пример #3
0
/**
 * Attempt to gain the ownership over monitor without blocking.
 *
 * @param[in] monitor object where monitor is located
 */
IDATA VMCALL jthread_monitor_try_enter(jobject monitor)
{
    assert(monitor);

    hythread_suspend_disable();
    hythread_thin_monitor_t *lockword = vm_object_get_lockword_addr(monitor);
    IDATA status = hythread_thin_monitor_try_enter(lockword);
    hythread_suspend_enable();

    if (status == TM_ERROR_NONE && ti_is_enabled()) {
        jthread_add_owned_monitor(monitor);
    }
    return status;
} // jthread_monitor_try_enter
Пример #4
0
/**
 * Releases the ownership over monitor.
 *
 * @param[in] monitor monitor
 * @sa JNI::MonitorExit()
 */
IDATA VMCALL jthread_monitor_exit(jobject monitor)
{
    assert(monitor);

    hythread_suspend_disable();
    hythread_thin_monitor_t *lockword = vm_object_get_lockword_addr(monitor);
    IDATA status = hythread_thin_monitor_exit(lockword);
    hythread_suspend_enable();

    if (status == TM_ERROR_NONE && ti_is_enabled()) {
        jthread_remove_owned_monitor(monitor);
    }
    if (status == TM_ERROR_ILLEGAL_STATE) {
        jthread_throw_exception("java/lang/IllegalMonitorStateException",
                                "Illegal monitor state");
    }
    return status;
} // jthread_monitor_exit
Пример #5
0
/**
 * Returns the number of times given thread have entered given monitor;
 *
 * If the given monitor is not owned by this thread, 0 is returned.
 *
 * @param[in] monitor monitor those owner needs to be determined
 * @param[in] owner thread which owns the monitor
 */
IDATA VMCALL jthread_get_lock_recursion(jobject monitor, jthread owner)
{
    assert(monitor);

    hythread_t given_thread = owner ? jthread_get_native_thread(owner) : NULL;

    hythread_suspend_disable();
    hythread_thin_monitor_t *lockword = vm_object_get_lockword_addr(monitor);
    hythread_t lock_owner = hythread_thin_monitor_get_owner(lockword);

    IDATA recursion = 0;
    if (lock_owner
        && (!given_thread
            || hythread_get_id(lock_owner) == hythread_get_id(given_thread)))
    {
        recursion = hythread_thin_monitor_get_recursion(lockword);
    }
    hythread_suspend_enable();

    return recursion;
} // jthread_get_lock_recursion
Пример #6
0
/**
 * Returns the owner of the lock associated with the given monitor.
 *
 * If the given monitor is not owned by any thread, NULL is returned.
 *
 * @param[in] monitor monitor those owner needs to be determined
 * @param[out] lock_owner thread which owns the monitor
 */
IDATA VMCALL jthread_get_lock_owner(jobject monitor, jthread * lock_owner)
{
    assert(monitor);
    assert(lock_owner);

    *lock_owner = NULL;
    IDATA status = TM_ERROR_NONE;

    hythread_suspend_disable();
    hythread_thin_monitor_t *lockword = vm_object_get_lockword_addr(monitor);
    hythread_t native_thread = hythread_thin_monitor_get_owner(lockword);
    if (native_thread) {
        vm_thread_t vm_thread = jthread_get_vm_thread(native_thread);
        if (vm_thread) {
            *lock_owner = vm_thread->java_thread;
        } else {
            status = TM_ERROR_ILLEGAL_STATE;
        }
    }
    hythread_suspend_enable();

    return status;
} // jthread_get_lock_owner
Пример #7
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
Пример #8
0
/**
 * Wait on the <code>object</code>'s monitor with the specified timeout.
 *
 * This function instructs the current thread to be scheduled off 
 * the processor and wait on the monitor until the following occurs: 
 * <UL>
 * <LI>another thread invokes <code>thread_notify(object)</code>
 * and VM chooses this thread to wake up;
 * <LI>another thread invokes <code>thread_notifyAll(object);</code>
 * <LI>another thread invokes <code>thread_interrupt(thread);</code>
 * <LI>real time elapsed from the waiting begin is
 * greater or equal the timeout specified.
 * </UL>
 *
 * @param[in] monitor object where monitor is located
 * @param[in] millis time to wait (in milliseconds)
 * @param[in] nanos time to wait (in nanoseconds)
 * @sa java.lang.Object.wait()
 */
IDATA VMCALL
jthread_monitor_timed_wait(jobject monitor, jlong millis, jint nanos)
{
    assert(monitor);

    hythread_suspend_disable();
    hythread_t native_thread = hythread_self();
    hythread_thin_monitor_t *lockword = vm_object_get_lockword_addr(monitor);
    if (!hythread_is_fat_lock(*lockword)) {
        if (!hythread_owns_thin_lock(native_thread, *lockword)) {
            CTRACE(("ILLEGAL_STATE wait %x\n", lockword));
            hythread_suspend_enable();
            return TM_ERROR_ILLEGAL_STATE;
        }
        hythread_inflate_lock(lockword);
    }

    apr_time_t wait_begin;
    if (ti_is_enabled()) {
        int disable_count = hythread_reset_suspend_disable();
        jthread_set_wait_monitor(monitor);
        jthread_set_owned_monitor(monitor);
        if(jvmti_should_report_event(JVMTI_EVENT_MONITOR_WAIT)) {
            jvmti_send_wait_monitor_event(monitor, (jlong) millis);
        }
        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);

        // should be moved to event handler
        wait_begin = apr_time_now();
        jthread_remove_owned_monitor(monitor);
    }

    hythread_thread_lock(native_thread);
    IDATA state = hythread_get_state(native_thread);
    state &= ~TM_THREAD_STATE_RUNNABLE;
    state |= TM_THREAD_STATE_WAITING | TM_THREAD_STATE_IN_MONITOR_WAIT;
    if ((millis > 0) || (nanos > 0)) {
        state |= TM_THREAD_STATE_WAITING_WITH_TIMEOUT;
    }
    else {
        state |= TM_THREAD_STATE_WAITING_INDEFINITELY;
    }
    IDATA status = hythread_set_state(native_thread, state);
    assert(status == TM_ERROR_NONE);
    hythread_thread_unlock(native_thread);

    status =
        hythread_thin_monitor_wait_interruptable(lockword, millis, nanos);

    hythread_thread_lock(native_thread);
    state = hythread_get_state(native_thread);
    if ((millis > 0) || (nanos > 0)) {
        state &= ~TM_THREAD_STATE_WAITING_WITH_TIMEOUT;
    }
    else {
        state &= ~TM_THREAD_STATE_WAITING_INDEFINITELY;
    }
    state &= ~(TM_THREAD_STATE_WAITING | TM_THREAD_STATE_IN_MONITOR_WAIT);
    state |= TM_THREAD_STATE_RUNNABLE;
    hythread_set_state(native_thread, state);
    hythread_thread_unlock(native_thread);

    hythread_suspend_enable();
    if (ti_is_enabled()) {
        jthread_add_owned_monitor(monitor);
        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);
        }
        if(jvmti_should_report_event(JVMTI_EVENT_MONITOR_WAITED)) {
            jvmti_send_waited_monitor_event(monitor,
                ((status == APR_TIMEUP) ? (jboolean) 1 : (jboolean) 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->waited_time += apr_time_now() - wait_begin;
    }
    return status;
} // jthread_monitor_timed_wait