8230422: Convert uninterruptible os::sleep calls to os::naked_short_sleep
Reviewed-by: kbarrett, dcubed, shade
--- a/src/hotspot/cpu/x86/rdtsc_x86.cpp Sat Sep 07 10:05:47 2019 -0700
+++ b/src/hotspot/cpu/x86/rdtsc_x86.cpp Sat Sep 07 18:48:57 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -62,7 +62,7 @@
fstart = os::rdtsc();
// use sleep to prevent compiler from optimizing
- os::sleep(Thread::current(), FT_SLEEP_MILLISECS, true);
+ os::sleep(JavaThread::current(), FT_SLEEP_MILLISECS);
end = os::elapsed_counter();
OrderAccess::fence();
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp Sat Sep 07 10:05:47 2019 -0700
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp Sat Sep 07 18:48:57 2019 -0400
@@ -2645,7 +2645,7 @@
MutexLocker x(freelistLock(), Mutex::_no_safepoint_check_flag);
expand_for_gc_cause(word_size*HeapWordSize, MinHeapDeltaBytes, CMSExpansionCause::_satisfy_allocation);
if (GCExpandToAllocateDelayMillis > 0) {
- os::sleep(Thread::current(), GCExpandToAllocateDelayMillis, false);
+ os::naked_sleep(GCExpandToAllocateDelayMillis);
}
return have_lock_and_allocate(word_size, tlab);
}
@@ -2684,7 +2684,7 @@
// A competing par_promote might beat us to the expansion space,
// so we may go around the loop again if promotion fails again.
if (GCExpandToAllocateDelayMillis > 0) {
- os::sleep(Thread::current(), GCExpandToAllocateDelayMillis, false);
+ os::naked_sleep(GCExpandToAllocateDelayMillis);
}
}
}
@@ -2711,7 +2711,7 @@
// A competing allocation might beat us to the expansion space,
// so we may go around the loop again if allocation fails again.
if (GCExpandToAllocateDelayMillis > 0) {
- os::sleep(Thread::current(), GCExpandToAllocateDelayMillis, false);
+ os::naked_sleep(GCExpandToAllocateDelayMillis);
}
}
}
@@ -3544,7 +3544,7 @@
for (unsigned i = 0; i < CMSCoordinatorYieldSleepCount &&
ConcurrentMarkSweepThread::should_yield() &&
!CMSCollector::foregroundGCIsActive(); ++i) {
- os::sleep(Thread::current(), 1, false);
+ os::naked_short_sleep(1);
}
ConcurrentMarkSweepThread::synchronize(true);
@@ -5541,7 +5541,7 @@
for (unsigned i = 0; i < CMSYieldSleepCount &&
ConcurrentMarkSweepThread::should_yield() &&
!CMSCollector::foregroundGCIsActive(); ++i) {
- os::sleep(Thread::current(), 1, false);
+ os::naked_short_sleep(1);
}
ConcurrentMarkSweepThread::synchronize(true);
@@ -5995,7 +5995,7 @@
ConcurrentMarkSweepThread::should_yield() &&
!CMSCollector::foregroundGCIsActive();
++i) {
- os::sleep(Thread::current(), 1, false);
+ os::naked_short_sleep(1);
}
ConcurrentMarkSweepThread::synchronize(true);
@@ -6150,7 +6150,7 @@
for (unsigned i = 0; i < CMSYieldSleepCount &&
ConcurrentMarkSweepThread::should_yield() &&
!CMSCollector::foregroundGCIsActive(); ++i) {
- os::sleep(Thread::current(), 1, false);
+ os::naked_short_sleep(1);
}
ConcurrentMarkSweepThread::synchronize(true);
@@ -6217,7 +6217,7 @@
for (unsigned i = 0; i < CMSYieldSleepCount &&
ConcurrentMarkSweepThread::should_yield() &&
!CMSCollector::foregroundGCIsActive(); ++i) {
- os::sleep(Thread::current(), 1, false);
+ os::naked_short_sleep(1);
}
ConcurrentMarkSweepThread::synchronize(true);
@@ -6368,7 +6368,7 @@
for (unsigned i = 0; i < CMSYieldSleepCount &&
ConcurrentMarkSweepThread::should_yield() &&
!CMSCollector::foregroundGCIsActive(); ++i) {
- os::sleep(Thread::current(), 1, false);
+ os::naked_short_sleep(1);
}
ConcurrentMarkSweepThread::synchronize(true);
@@ -6982,7 +6982,7 @@
for (unsigned i = 0; i < CMSYieldSleepCount &&
ConcurrentMarkSweepThread::should_yield() &&
!CMSCollector::foregroundGCIsActive(); ++i) {
- os::sleep(Thread::current(), 1, false);
+ os::naked_short_sleep(1);
}
ConcurrentMarkSweepThread::synchronize(true);
@@ -7547,7 +7547,7 @@
for (unsigned i = 0; i < CMSYieldSleepCount &&
ConcurrentMarkSweepThread::should_yield() &&
!CMSCollector::foregroundGCIsActive(); ++i) {
- os::sleep(Thread::current(), 1, false);
+ os::naked_short_sleep(1);
}
ConcurrentMarkSweepThread::synchronize(true);
@@ -7845,7 +7845,6 @@
}
// Grab the entire list; we'll put back a suffix
oop prefix = cast_to_oop(Atomic::xchg((oopDesc*)BUSY, &_overflow_list));
- Thread* tid = Thread::current();
// Before "no_of_gc_threads" was introduced CMSOverflowSpinCount was
// set to ParallelGCThreads.
size_t CMSOverflowSpinCount = (size_t) no_of_gc_threads; // was ParallelGCThreads;
@@ -7853,7 +7852,7 @@
// If the list is busy, we spin for a short while,
// sleeping between attempts to get the list.
for (size_t spin = 0; prefix == BUSY && spin < CMSOverflowSpinCount; spin++) {
- os::sleep(tid, sleep_time_millis, false);
+ os::naked_sleep(sleep_time_millis);
if (_overflow_list == NULL) {
// Nothing left to take
return false;
--- a/src/hotspot/share/gc/cms/parNewGeneration.cpp Sat Sep 07 10:05:47 2019 -0700
+++ b/src/hotspot/share/gc/cms/parNewGeneration.cpp Sat Sep 07 18:48:57 2019 -0400
@@ -1304,13 +1304,12 @@
// Otherwise, there was something there; try claiming the list.
oop prefix = cast_to_oop(Atomic::xchg((oopDesc*)BUSY, &_overflow_list));
// Trim off a prefix of at most objsFromOverflow items
- Thread* tid = Thread::current();
size_t spin_count = ParallelGCThreads;
size_t sleep_time_millis = MAX2((size_t)1, objsFromOverflow/100);
for (size_t spin = 0; prefix == BUSY && spin < spin_count; spin++) {
// someone grabbed it before we did ...
- // ... we spin for a short while...
- os::sleep(tid, sleep_time_millis, false);
+ // ... we spin/block for a short while...
+ os::naked_sleep(sleep_time_millis);
if (_overflow_list == NULL) {
// nothing left to take
return false;
--- a/src/hotspot/share/gc/parallel/psCardTable.cpp Sat Sep 07 10:05:47 2019 -0700
+++ b/src/hotspot/share/gc/parallel/psCardTable.cpp Sat Sep 07 18:48:57 2019 -0400
@@ -200,7 +200,7 @@
// Delay 1 worker so that it proceeds after all the work
// has been completed.
if (stripe_number < 2) {
- os::sleep(Thread::current(), GCWorkerDelayMillis, false);
+ os::naked_sleep(GCWorkerDelayMillis);
}
}
#endif
--- a/src/hotspot/share/gc/parallel/psOldGen.cpp Sat Sep 07 10:05:47 2019 -0700
+++ b/src/hotspot/share/gc/parallel/psOldGen.cpp Sat Sep 07 18:48:57 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -225,7 +225,7 @@
HeapWord* PSOldGen::expand_and_allocate(size_t word_size) {
expand(word_size*HeapWordSize);
if (GCExpandToAllocateDelayMillis > 0) {
- os::sleep(Thread::current(), GCExpandToAllocateDelayMillis, false);
+ os::naked_sleep(GCExpandToAllocateDelayMillis);
}
return allocate_noexpand(word_size);
}
@@ -233,7 +233,7 @@
HeapWord* PSOldGen::expand_and_cas_allocate(size_t word_size) {
expand(word_size*HeapWordSize);
if (GCExpandToAllocateDelayMillis > 0) {
- os::sleep(Thread::current(), GCExpandToAllocateDelayMillis, false);
+ os::naked_sleep(GCExpandToAllocateDelayMillis);
}
return cas_allocate_noexpand(word_size);
}
--- a/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp Sat Sep 07 10:05:47 2019 -0700
+++ b/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp Sat Sep 07 18:48:57 2019 -0400
@@ -224,7 +224,7 @@
// Delay the initialization of the promotion lab (plab).
// This exposes uninitialized plabs to card table processing.
if (GCWorkerDelayMillis > 0) {
- os::sleep(Thread::current(), GCWorkerDelayMillis, false);
+ os::naked_sleep(GCWorkerDelayMillis);
}
#endif
_old_lab.initialize(MemRegion(lab_base, OldPLABSize));
--- a/src/hotspot/share/gc/serial/tenuredGeneration.cpp Sat Sep 07 10:05:47 2019 -0700
+++ b/src/hotspot/share/gc/serial/tenuredGeneration.cpp Sat Sep 07 18:48:57 2019 -0400
@@ -202,7 +202,7 @@
while (true) {
expand(byte_size, _min_heap_delta_bytes);
if (GCExpandToAllocateDelayMillis > 0) {
- os::sleep(Thread::current(), GCExpandToAllocateDelayMillis, false);
+ os::naked_sleep(GCExpandToAllocateDelayMillis);
}
result = _the_space->par_allocate(word_size);
if ( result != NULL) {
--- a/src/hotspot/share/gc/shared/taskqueue.cpp Sat Sep 07 10:05:47 2019 -0700
+++ b/src/hotspot/share/gc/shared/taskqueue.cpp Sat Sep 07 18:48:57 2019 -0400
@@ -134,7 +134,7 @@
void ParallelTaskTerminator::sleep(uint millis) {
assert(_offered_termination <= _n_threads, "Invariant");
- os::sleep(Thread::current(), millis, false);
+ os::naked_sleep(millis);
}
bool
@@ -280,4 +280,3 @@
delete _terminator;
}
}
-
--- a/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp Sat Sep 07 10:05:47 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp Sat Sep 07 18:48:57 2019 -0400
@@ -242,7 +242,7 @@
}
cur = MAX2<size_t>(1, cur);
- os::sleep(Thread::current(), cur, true);
+ os::sleep(JavaThread::current(), cur);
double end = os::elapsedTime();
total = (size_t)((end - start) * 1000);
--- a/src/hotspot/share/jvmci/jvmciCompiler.cpp Sat Sep 07 10:05:47 2019 -0700
+++ b/src/hotspot/share/jvmci/jvmciCompiler.cpp Sat Sep 07 18:48:57 2019 -0400
@@ -50,6 +50,7 @@
}
void JVMCICompiler::bootstrap(TRAPS) {
+ assert(THREAD->is_Java_thread(), "must be");
if (Arguments::mode() == Arguments::_int) {
// Nothing to do in -Xint mode
return;
@@ -80,7 +81,7 @@
do {
// Loop until there is something in the queue.
do {
- os::sleep(THREAD, 100, true);
+ os::sleep((JavaThread*)THREAD, 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 Sat Sep 07 10:05:47 2019 -0700
+++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp Sat Sep 07 18:48:57 2019 -0400
@@ -941,10 +941,8 @@
describe_pending_hotspot_exception(THREAD, true);
}
} else {
- // Allow error reporting thread to print the stack trace. Windows
- // doesn't allow uninterruptible wait for JavaThreads
- const bool interruptible = true;
- os::sleep(THREAD, 200, interruptible);
+ // Allow error reporting thread to print the stack trace.
+ os::sleep(THREAD, 200);
}
before_exit(THREAD);
--- a/src/hotspot/share/prims/jvm.cpp Sat Sep 07 10:05:47 2019 -0700
+++ b/src/hotspot/share/prims/jvm.cpp Sat Sep 07 18:48:57 2019 -0400
@@ -2978,7 +2978,7 @@
} else {
ThreadState old_state = thread->osthread()->get_state();
thread->osthread()->set_state(SLEEPING);
- if (os::sleep(thread, millis, true) == OS_INTRPT) {
+ if (os::sleep(thread, millis) == OS_INTRPT) {
// 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 Sat Sep 07 10:05:47 2019 -0700
+++ b/src/hotspot/share/runtime/os.cpp Sat Sep 07 18:48:57 2019 -0400
@@ -1837,7 +1837,19 @@
}
#endif
-int os::sleep(Thread* thread, jlong millis, bool interruptible) {
+// Convenience wrapper around naked_short_sleep to allow for longer sleep
+// times. Only for use by non-JavaThreads.
+void os::naked_sleep(jlong millis) {
+ assert(!Thread::current()->is_Java_thread(), "not for use by JavaThreads");
+ const jlong limit = 999;
+ while (millis > limit) {
+ naked_short_sleep(limit);
+ millis -= limit;
+ }
+ naked_short_sleep(millis);
+}
+
+int os::sleep(JavaThread* thread, jlong millis) {
assert(thread == Thread::current(), "thread consistency check");
ParkEvent * const slp = thread->_SleepEvent;
@@ -1850,72 +1862,43 @@
// interrupt state.
OrderAccess::fence();
- if (interruptible) {
- jlong prevtime = javaTimeNanos();
-
- assert(thread->is_Java_thread(), "sanity check");
- JavaThread *jt = (JavaThread *) thread;
+ jlong prevtime = javaTimeNanos();
- for (;;) {
- // interruption has precedence over timing out
- if (os::is_interrupted(thread, true)) {
- return OS_INTRPT;
- }
-
- jlong newtime = javaTimeNanos();
+ for (;;) {
+ // interruption has precedence over timing out
+ if (os::is_interrupted(thread, true)) {
+ return OS_INTRPT;
+ }
- 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(interruptible)");
- } else {
- millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC;
- }
+ jlong newtime = javaTimeNanos();
- if (millis <= 0) {
- return OS_OK;
- }
-
- prevtime = newtime;
-
- {
- ThreadBlockInVM tbivm(jt);
- OSThreadWaitState osts(jt->osthread(), false /* not Object.wait() */);
+ 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;
+ }
- jt->set_suspend_equivalent();
- // cleared by handle_special_suspend_equivalent_condition() or
- // java_suspend_self() via check_and_wait_while_suspended()
-
- slp->park(millis);
+ if (millis <= 0) {
+ return OS_OK;
+ }
- // were we externally suspended while we were waiting?
- jt->check_and_wait_while_suspended();
- }
- }
- } else {
- OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
- jlong prevtime = javaTimeNanos();
+ prevtime = newtime;
+
+ {
+ ThreadBlockInVM tbivm(thread);
+ OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
- for (;;) {
- // It'd be nice to avoid the back-to-back javaTimeNanos() calls on
- // the 1st iteration ...
- jlong newtime = javaTimeNanos();
+ thread->set_suspend_equivalent();
+ // cleared by handle_special_suspend_equivalent_condition() or
+ // java_suspend_self() via check_and_wait_while_suspended()
- 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 on os::sleep(!interruptible)");
- } else {
- millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC;
- }
+ slp->park(millis);
- if (millis <= 0) break ;
-
- prevtime = newtime;
- slp->park(millis);
+ // were we externally suspended while we were waiting?
+ thread->check_and_wait_while_suspended();
}
- return OS_OK ;
}
}
--- a/src/hotspot/share/runtime/os.hpp Sat Sep 07 10:05:47 2019 -0700
+++ b/src/hotspot/share/runtime/os.hpp Sat Sep 07 18:48:57 2019 -0400
@@ -467,13 +467,19 @@
// thread id on Linux/64bit is 64bit, on Windows and Solaris, it's 32bit
static intx current_thread_id();
static int current_process_id();
- static int sleep(Thread* thread, jlong ms, bool interruptable);
- // Short standalone OS sleep suitable for slow path spin loop.
- // Ignores Thread.interrupt() (so keep it short).
- // ms = 0, will sleep for the least amount of time allowed by the OS.
+ // 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.
+ // Maximum sleep time is just under 1 second.
static void naked_short_sleep(jlong ms);
static void naked_short_nanosleep(jlong ns);
- static void infinite_sleep(); // never returns, use with CAUTION
+ // Longer standalone OS sleep routine - a convenience wrapper around
+ // multiple calls to naked_short_sleep. Only for use by non-JavaThreads.
+ static void naked_sleep(jlong millis);
+ // Never returns, use with CAUTION
+ static void infinite_sleep();
static void naked_yield () ;
static OSReturn set_priority(Thread* thread, ThreadPriority priority);
static OSReturn get_priority(const Thread* const thread, ThreadPriority& priority);
--- a/src/hotspot/share/runtime/safepoint.cpp Sat Sep 07 10:05:47 2019 -0700
+++ b/src/hotspot/share/runtime/safepoint.cpp Sat Sep 07 18:48:57 2019 -0400
@@ -939,7 +939,7 @@
break; // Could not send signal. Report fatal error.
}
// Give cur_thread a chance to report the error and terminate the VM.
- os::sleep(Thread::current(), 3000, false);
+ os::naked_sleep(3000);
}
}
fatal("Safepoint sync time longer than " INTX_FORMAT "ms detected when executing %s.",
--- a/test/hotspot/gtest/gc/g1/test_g1FreeIdSet.cpp Sat Sep 07 10:05:47 2019 -0700
+++ b/test/hotspot/gtest/gc/g1/test_g1FreeIdSet.cpp Sat Sep 07 18:48:57 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, true);
+ os::sleep(this_thread, 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 Sat Sep 07 10:05:47 2019 -0700
+++ b/test/hotspot/gtest/gc/shared/test_ptrQueueBufferAllocator.cpp Sat Sep 07 18:48:57 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, true);
+ os::sleep(this_thread, milliseconds_to_run);
}
OrderAccess::release_store(&allocator_running, false);
for (uint i = 0; i < nthreads; ++i) {
--- a/test/hotspot/gtest/utilities/test_singleWriterSynchronizer.cpp Sat Sep 07 10:05:47 2019 -0700
+++ b/test/hotspot/gtest/utilities/test_singleWriterSynchronizer.cpp Sat Sep 07 18:48:57 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -133,9 +133,10 @@
writer->doit();
tty->print_cr("Stressing synchronizer for %u ms", milliseconds_to_run);
+ JavaThread* cur = JavaThread::current();
{
- ThreadInVMfromNative invm(JavaThread::current());
- os::sleep(Thread::current(), milliseconds_to_run, true);
+ ThreadInVMfromNative invm(cur);
+ os::sleep(cur, milliseconds_to_run);
}
continue_running = 0;
for (uint i = 0; i < nreaders + 1; ++i) {