8230423: Move os::sleep to JavaThread::sleep

Reviewed-by: rehn, dcubed
This commit is contained in:
David Holmes 2019-09-11 22:09:05 -04:00
parent 091cf3608b
commit 99252bd9d6
14 changed files with 84 additions and 79 deletions

View file

@ -291,7 +291,6 @@ Thread::Thread() {
// 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
@ -456,7 +455,6 @@ Thread::~Thread() {
// 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();
@ -1696,7 +1694,7 @@ void JavaThread::initialize() {
_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);
@ -1808,6 +1806,10 @@ JavaThread::~JavaThread() {
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();
@ -3339,6 +3341,62 @@ Klass* JavaThread::security_get_caller_class(int depth) {
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();