--- a/src/hotspot/cpu/x86/rdtsc_x86.cpp Thu Sep 12 03:21:11 2019 +0200
+++ b/src/hotspot/cpu/x86/rdtsc_x86.cpp Wed Sep 11 22:09:05 2019 -0400
@@ -62,7 +62,7 @@
fstart = os::rdtsc();
// use sleep to prevent compiler from optimizing
- os::sleep(JavaThread::current(), FT_SLEEP_MILLISECS);
+ JavaThread::current()->sleep(FT_SLEEP_MILLISECS);
end = os::elapsed_counter();
OrderAccess::fence();
--- a/src/hotspot/os/posix/os_posix.cpp Thu Sep 12 03:21:11 2019 +0200
+++ b/src/hotspot/os/posix/os_posix.cpp Wed Sep 11 22:09:05 2019 -0400
@@ -645,7 +645,8 @@
void os::interrupt(Thread* thread) {
debug_only(Thread::check_for_dangling_thread_pointer(thread);)
-
+ assert(thread->is_Java_thread(), "invariant");
+ JavaThread* jt = (JavaThread*) thread;
OSThread* osthread = thread->osthread();
if (!osthread->interrupted()) {
@@ -654,13 +655,12 @@
// resulting in multiple notifications. We do, however, want the store
// to interrupted() to be visible to other threads before we execute unpark().
OrderAccess::fence();
- ParkEvent * const slp = thread->_SleepEvent ;
+ ParkEvent * const slp = jt->_SleepEvent ;
if (slp != NULL) slp->unpark() ;
}
// For JSR166. Unpark even if interrupt status already was set
- if (thread->is_Java_thread())
- ((JavaThread*)thread)->parker()->unpark();
+ jt->parker()->unpark();
ParkEvent * ev = thread->_ParkEvent ;
if (ev != NULL) ev->unpark() ;
@@ -682,7 +682,7 @@
// is allowed and not harmful, and the possibility is so rare that
// it is not worth the added complexity to add yet another lock.
// For the sleep event an explicit reset is performed on entry
- // to os::sleep, so there is no early return. It has also been
+ // to JavaThread::sleep, so there is no early return. It has also been
// recommended not to put the interrupted flag into the "event"
// structure because it hides the issue.
if (interrupted && clear_interrupted) {
@@ -2049,7 +2049,7 @@
// shake out uses of park() and unpark() without checking state conditions
// properly. This spurious return doesn't manifest itself in any user code
// but only in the correctly written condition checking loops of ObjectMonitor,
- // Mutex/Monitor, Thread::muxAcquire and os::sleep
+ // Mutex/Monitor, Thread::muxAcquire and JavaThread::sleep
if (Atomic::xchg(1, &_event) >= 0) return;
--- a/src/hotspot/os/windows/os_windows.cpp Thu Sep 12 03:21:11 2019 +0200
+++ b/src/hotspot/os/windows/os_windows.cpp Wed Sep 11 22:09:05 2019 -0400
@@ -3595,7 +3595,8 @@
void os::interrupt(Thread* thread) {
debug_only(Thread::check_for_dangling_thread_pointer(thread);)
-
+ assert(thread->is_Java_thread(), "invariant");
+ JavaThread* jt = (JavaThread*) thread;
OSThread* osthread = thread->osthread();
osthread->set_interrupted(true);
// More than one thread can get here with the same value of osthread,
@@ -3605,14 +3606,12 @@
OrderAccess::release();
SetEvent(osthread->interrupt_event());
// For JSR166: unpark after setting status
- if (thread->is_Java_thread()) {
- ((JavaThread*)thread)->parker()->unpark();
- }
+ jt->parker()->unpark();
ParkEvent * ev = thread->_ParkEvent;
if (ev != NULL) ev->unpark();
- ev = thread->_SleepEvent;
+ ev = jt->_SleepEvent;
if (ev != NULL) ev->unpark();
}
--- a/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp Thu Sep 12 03:21:11 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp Wed Sep 11 22:09:05 2019 -0400
@@ -242,7 +242,7 @@
}
cur = MAX2<size_t>(1, cur);
- os::sleep(JavaThread::current(), cur);
+ JavaThread::current()->sleep(cur);
double end = os::elapsedTime();
total = (size_t)((end - start) * 1000);
--- a/src/hotspot/share/jvmci/jvmciCompiler.cpp Thu Sep 12 03:21:11 2019 +0200
+++ b/src/hotspot/share/jvmci/jvmciCompiler.cpp Wed Sep 11 22:09:05 2019 -0400
@@ -81,7 +81,7 @@
do {
// Loop until there is something in the queue.
do {
- os::sleep((JavaThread*)THREAD, 100);
+ ((JavaThread*)THREAD)->sleep(100);
qsize = CompileBroker::queue_size(CompLevel_full_optimization);
} while (!_bootstrap_compilation_request_handled && first_round && qsize == 0);
first_round = false;
--- a/src/hotspot/share/jvmci/jvmciRuntime.cpp Thu Sep 12 03:21:11 2019 +0200
+++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp Wed Sep 11 22:09:05 2019 -0400
@@ -942,7 +942,7 @@
}
} else {
// Allow error reporting thread to print the stack trace.
- os::sleep(THREAD, 200);
+ THREAD->sleep(200);
}
before_exit(THREAD);
--- a/src/hotspot/share/prims/jvm.cpp Thu Sep 12 03:21:11 2019 +0200
+++ b/src/hotspot/share/prims/jvm.cpp Wed Sep 11 22:09:05 2019 -0400
@@ -2990,7 +2990,7 @@
} else {
ThreadState old_state = thread->osthread()->get_state();
thread->osthread()->set_state(SLEEPING);
- if (os::sleep(thread, millis) == OS_INTRPT) {
+ if (!thread->sleep(millis)) { // interrupted
// An asynchronous exception (e.g., ThreadDeathException) could have been thrown on
// us while we were sleeping. We do not overwrite those.
if (!HAS_PENDING_EXCEPTION) {
--- a/src/hotspot/share/runtime/os.cpp Thu Sep 12 03:21:11 2019 +0200
+++ b/src/hotspot/share/runtime/os.cpp Wed Sep 11 22:09:05 2019 -0400
@@ -1844,57 +1844,3 @@
}
naked_short_sleep(millis);
}
-
-int os::sleep(JavaThread* thread, jlong millis) {
- assert(thread == Thread::current(), "thread consistency check");
-
- ParkEvent * const slp = thread->_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 = javaTimeNanos();
-
- for (;;) {
- // interruption has precedence over timing out
- if (os::is_interrupted(thread, true)) {
- return OS_INTRPT;
- }
-
- jlong newtime = 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;
- }
-
- if (millis <= 0) {
- return OS_OK;
- }
-
- prevtime = newtime;
-
- {
- ThreadBlockInVM tbivm(thread);
- OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
-
- thread->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?
- thread->check_and_wait_while_suspended();
- }
- }
-}
--- a/src/hotspot/share/runtime/os.hpp Thu Sep 12 03:21:11 2019 +0200
+++ b/src/hotspot/share/runtime/os.hpp Wed Sep 11 22:09:05 2019 -0400
@@ -464,8 +464,7 @@
// thread id on Linux/64bit is 64bit, on Windows and Solaris, it's 32bit
static intx current_thread_id();
static int current_process_id();
- // Implementation of java.lang.Thread.sleep for JavaThreads
- static int sleep(JavaThread* thread, jlong ms);
+
// Short standalone OS sleep routines suitable for slow path spin loop.
// Ignores safepoints/suspension/Thread.interrupt() (so keep it short).
// ms/ns = 0, will sleep for the least amount of time allowed by the OS.
--- a/src/hotspot/share/runtime/thread.cpp Thu Sep 12 03:21:11 2019 +0200
+++ b/src/hotspot/share/runtime/thread.cpp Wed Sep 11 22:09:05 2019 -0400
@@ -291,7 +291,6 @@
// 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 @@
// 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 @@
_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 @@
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 @@
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();
--- a/src/hotspot/share/runtime/thread.hpp Thu Sep 12 03:21:11 2019 +0200
+++ b/src/hotspot/share/runtime/thread.hpp Wed Sep 11 22:09:05 2019 -0400
@@ -789,7 +789,6 @@
volatile intptr_t _Stalled;
volatile int _TypeTag;
ParkEvent * _ParkEvent; // for synchronized()
- ParkEvent * _SleepEvent; // for Thread.sleep
ParkEvent * _MuxEvent; // for low-level muxAcquire-muxRelease
int NativeSyncRecursion; // diagnostic
@@ -2055,6 +2054,10 @@
private:
InstanceKlass* _class_to_be_initialized;
+ // java.lang.Thread.sleep support
+public:
+ ParkEvent * _SleepEvent;
+ bool sleep(jlong millis);
};
// Inline implementation of JavaThread::current
--- a/test/hotspot/gtest/gc/g1/test_g1FreeIdSet.cpp Thu Sep 12 03:21:11 2019 +0200
+++ b/test/hotspot/gtest/gc/g1/test_g1FreeIdSet.cpp Wed Sep 11 22:09:05 2019 -0400
@@ -145,7 +145,7 @@
tty->print_cr("Stressing G1FreeIdSet for %u ms", milliseconds_to_run);
{
ThreadInVMfromNative invm(this_thread);
- os::sleep(this_thread, milliseconds_to_run);
+ this_thread->sleep(milliseconds_to_run);
}
OrderAccess::release_store(&continue_running, false);
for (uint i = 0; i < nthreads; ++i) {
--- a/test/hotspot/gtest/gc/shared/test_ptrQueueBufferAllocator.cpp Thu Sep 12 03:21:11 2019 +0200
+++ b/test/hotspot/gtest/gc/shared/test_ptrQueueBufferAllocator.cpp Wed Sep 11 22:09:05 2019 -0400
@@ -224,7 +224,7 @@
tty->print_cr("Stressing allocator for %u ms", milliseconds_to_run);
{
ThreadInVMfromNative invm(this_thread);
- os::sleep(this_thread, milliseconds_to_run);
+ this_thread->sleep(milliseconds_to_run);
}
OrderAccess::release_store(&allocator_running, false);
for (uint i = 0; i < nthreads; ++i) {
--- a/test/hotspot/gtest/utilities/test_singleWriterSynchronizer.cpp Thu Sep 12 03:21:11 2019 +0200
+++ b/test/hotspot/gtest/utilities/test_singleWriterSynchronizer.cpp Wed Sep 11 22:09:05 2019 -0400
@@ -136,7 +136,7 @@
JavaThread* cur = JavaThread::current();
{
ThreadInVMfromNative invm(cur);
- os::sleep(cur, milliseconds_to_run);
+ cur->sleep(milliseconds_to_run);
}
continue_running = 0;
for (uint i = 0; i < nreaders + 1; ++i) {