< prev index next >

src/hotspot/share/runtime/thread.cpp

Print this page

        

*** 289,299 **** // CONSIDER: instead of using a fixed set of purpose-dedicated ParkEvents // we might instead use a stack of ParkEvents that we could provision on-demand. // The stack would act as a cache to avoid calls to ParkEvent::Allocate() // and ::Release() _ParkEvent = ParkEvent::Allocate(this); - _SleepEvent = ParkEvent::Allocate(this); _MuxEvent = ParkEvent::Allocate(this); #ifdef CHECK_UNHANDLED_OOPS if (CheckUnhandledOops) { _unhandled_oops = new UnhandledOops(this); --- 289,298 ----
*** 454,464 **** assert(last_handle_mark() == NULL, "check we have reached the end"); // It's possible we can encounter a null _ParkEvent, etc., in stillborn threads. // We NULL out the fields for good hygiene. ParkEvent::Release(_ParkEvent); _ParkEvent = NULL; - ParkEvent::Release(_SleepEvent); _SleepEvent = NULL; ParkEvent::Release(_MuxEvent); _MuxEvent = NULL; delete handle_area(); delete metadata_handles(); --- 453,462 ----
*** 1698,1708 **** _jni_active_critical = 0; _pending_jni_exception_check_fn = NULL; _do_not_unlock_if_synchronized = false; _cached_monitor_info = NULL; _parker = Parker::Allocate(this); ! // Setup safepoint state info for this thread ThreadSafepointState::create(this); debug_only(_java_call_counter = 0); --- 1696,1706 ---- _jni_active_critical = 0; _pending_jni_exception_check_fn = NULL; _do_not_unlock_if_synchronized = false; _cached_monitor_info = NULL; _parker = Parker::Allocate(this); ! _SleepEvent = ParkEvent::Allocate(this); // Setup safepoint state info for this thread ThreadSafepointState::create(this); debug_only(_java_call_counter = 0);
*** 1810,1819 **** --- 1808,1821 ---- // JSR166 -- return the parker to the free list Parker::Release(_parker); _parker = NULL; + // Return the sleep event to the free list + ParkEvent::Release(_SleepEvent); + _SleepEvent = NULL; + // Free any remaining previous UnrollBlock vframeArray* old_array = vframe_array_last(); if (old_array != NULL) { Deoptimization::UnrollBlock* old_info = old_array->unroll_block();
*** 3341,3350 **** --- 3343,3409 ---- return vfst.method()->method_holder(); } return NULL; } + // java.lang.Thread.sleep support + // Returns true if sleep time elapsed as expected, and false + // if the thread was interrupted. + bool JavaThread::sleep(jlong millis) { + assert(this == Thread::current(), "thread consistency check"); + + ParkEvent * const slp = this->_SleepEvent; + // Because there can be races with thread interruption sending an unpark() + // to the event, we explicitly reset it here to avoid an immediate return. + // The actual interrupt state will be checked before we park(). + slp->reset(); + // Thread interruption establishes a happens-before ordering in the + // Java Memory Model, so we need to ensure we synchronize with the + // interrupt state. + OrderAccess::fence(); + + jlong prevtime = os::javaTimeNanos(); + + for (;;) { + // interruption has precedence over timing out + if (os::is_interrupted(this, true)) { + return false; + } + + if (millis <= 0) { + return true; + } + + { + ThreadBlockInVM tbivm(this); + OSThreadWaitState osts(this->osthread(), false /* not Object.wait() */); + + this->set_suspend_equivalent(); + // cleared by handle_special_suspend_equivalent_condition() or + // java_suspend_self() via check_and_wait_while_suspended() + + slp->park(millis); + + // were we externally suspended while we were waiting? + this->check_and_wait_while_suspended(); + } + + // Update elapsed time tracking + jlong newtime = os::javaTimeNanos(); + if (newtime - prevtime < 0) { + // time moving backwards, should only happen if no monotonic clock + // not a guarantee() because JVM should not abort on kernel/glibc bugs + assert(!os::supports_monotonic_clock(), + "unexpected time moving backwards detected in os::sleep()"); + } else { + millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC; + } + prevtime = newtime; + } + } + + static void compiler_thread_entry(JavaThread* thread, TRAPS) { assert(thread->is_Compiler_thread(), "must be compiler thread"); CompileBroker::compiler_thread_loop(); }
< prev index next >