8230423: Move os::sleep to JavaThread::sleep
authordholmes
Wed, 11 Sep 2019 22:09:05 -0400
changeset 58095 adc72cd1d1f2
parent 58094 0f6c749acd15
child 58096 0d97bf7cf8a4
8230423: Move os::sleep to JavaThread::sleep Reviewed-by: rehn, dcubed
src/hotspot/cpu/x86/rdtsc_x86.cpp
src/hotspot/os/posix/os_posix.cpp
src/hotspot/os/windows/os_windows.cpp
src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp
src/hotspot/share/jvmci/jvmciCompiler.cpp
src/hotspot/share/jvmci/jvmciRuntime.cpp
src/hotspot/share/prims/jvm.cpp
src/hotspot/share/runtime/os.cpp
src/hotspot/share/runtime/os.hpp
src/hotspot/share/runtime/thread.cpp
src/hotspot/share/runtime/thread.hpp
test/hotspot/gtest/gc/g1/test_g1FreeIdSet.cpp
test/hotspot/gtest/gc/shared/test_ptrQueueBufferAllocator.cpp
test/hotspot/gtest/utilities/test_singleWriterSynchronizer.cpp
--- 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) {