< prev index next >
src/hotspot/share/runtime/synchronizer.cpp
Print this page
rev 54996 : Checkpoint latest preliminary review patches for full OpenJDK review; merge with 8222295.patch.
rev 54997 : imported patch dcubed.monitor_deflate_conc.v2.01
rev 54998 : imported patch dcubed.monitor_deflate_conc.v2.02
rev 54999 : imported patch dcubed.monitor_deflate_conc.v2.03
rev 55000 : [mq]: dcubed.monitor_deflate_conc.v2.04
@@ -123,12 +123,13 @@
// global monitor in-use list, for moribund threads,
// monitors they inflated need to be scanned for deflation
ObjectMonitor * volatile ObjectSynchronizer::gOmInUseList = NULL;
// count of entries in gOmInUseList
int ObjectSynchronizer::gOmInUseCount = 0;
-bool ObjectSynchronizer::_gOmShouldDeflateIdleMonitors = false;
-bool volatile ObjectSynchronizer::_is_cleanup_requested = false;
+bool volatile ObjectSynchronizer::_is_async_deflation_requested = false;
+bool volatile ObjectSynchronizer::_is_special_deflation_requested = false;
+jlong ObjectSynchronizer::_last_async_deflation_time_ns = 0;
static volatile intptr_t gListLock = 0; // protects global monitor lists
static volatile int gMonitorFreeCount = 0; // # on gFreeList
static volatile int gMonitorPopulation = 0; // # Extant -- in circulation
@@ -1011,22 +1012,59 @@
static bool monitors_used_above_threshold() {
if (gMonitorPopulation == 0) {
return false;
}
+ if (MonitorUsedDeflationThreshold > 0) {
int monitors_used = gMonitorPopulation - gMonitorFreeCount;
int monitor_usage = (monitors_used * 100LL) / gMonitorPopulation;
return monitor_usage > MonitorUsedDeflationThreshold;
+ }
+ return false;
}
-bool ObjectSynchronizer::is_cleanup_needed() {
- if (MonitorUsedDeflationThreshold > 0) {
- return monitors_used_above_threshold();
+bool ObjectSynchronizer::is_async_deflation_needed() {
+ if (!AsyncDeflateIdleMonitors) {
+ return false;
+ }
+ if (is_async_deflation_requested()) {
+ // Async deflation request.
+ return true;
+ }
+ if (AsyncDeflationInterval > 0 &&
+ time_since_last_async_deflation_ms() > AsyncDeflationInterval &&
+ monitors_used_above_threshold()) {
+ // It's been longer than our specified deflate interval and there
+ // are too many monitors in use. We don't deflate more frequently
+ // than AsyncDeflationInterval (unless is_async_deflation_requested)
+ // in order to not swamp the ServiceThread.
+ _last_async_deflation_time_ns = os::javaTimeNanos();
+ return true;
}
return false;
}
+bool ObjectSynchronizer::is_safepoint_deflation_needed() {
+ if (!AsyncDeflateIdleMonitors) {
+ if (monitors_used_above_threshold()) {
+ // Too many monitors in use.
+ return true;
+ }
+ return false;
+ }
+ if (is_special_deflation_requested()) {
+ // For AsyncDeflateIdleMonitors only do a safepoint deflation
+ // if there is a special deflation request.
+ return true;
+ }
+ return false;
+}
+
+jlong ObjectSynchronizer::time_since_last_async_deflation_ms() {
+ return (os::javaTimeNanos() - _last_async_deflation_time_ns) / (NANOUNITS / MILLIUNITS);
+}
+
void ObjectSynchronizer::oops_do(OopClosure* f) {
// We only scan the global used list here (for moribund threads), and
// the thread-local monitors in Thread::oops_do().
global_used_oops_do(f);
}
@@ -1116,13 +1154,15 @@
if (AsyncDeflateIdleMonitors) {
JavaThread * jt = (JavaThread *)Self;
if (jt->omShouldDeflateIdleMonitors && jt->omInUseCount > 0 &&
cause != inflate_cause_vm_internal) {
// Deflate any per-thread idle monitors for this JavaThread if
- // this is not an internal inflation. Clean up your own mess.
- // (Gibbs Rule 45) Otherwise, skip this cleanup.
- // deflate_global_idle_monitors_using_JT() is called by the ServiceThread.
+ // this is not an internal inflation; internal inflations can
+ // occur in places where it is not safe to pause for a safepoint.
+ // Clean up your own mess. (Gibbs Rule 45) Otherwise, skip this
+ // deflation. deflate_global_idle_monitors_using_JT() is called
+ // by the ServiceThread.
debug_only(jt->check_for_valid_safepoint_state(false);)
ObjectSynchronizer::deflate_per_thread_idle_monitors_using_JT();
}
}
@@ -1701,20 +1741,20 @@
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
// The per-thread in-use lists are handled in
// ParallelSPCleanupThreadClosure::do_thread().
- if (!AsyncDeflateIdleMonitors || is_cleanup_requested()) {
- // Use the older mechanism for the global in-use list or
- // if a special cleanup has been requested.
+ if (!AsyncDeflateIdleMonitors || is_special_deflation_requested()) {
+ // Use the older mechanism for the global in-use list or if a
+ // special deflation has been requested before the safepoint.
ObjectSynchronizer::deflate_idle_monitors(_counters);
return;
}
- log_debug(monitorinflation)("requesting deflation of idle monitors.");
- // Request deflation of global idle monitors by the ServiceThread:
- _gOmShouldDeflateIdleMonitors = true;
+ log_debug(monitorinflation)("requesting async deflation of idle monitors.");
+ // Request deflation of idle monitors by the ServiceThread:
+ set_is_async_deflation_requested(true);
MonitorLocker ml(Service_lock, Mutex::_no_safepoint_check_flag);
ml.notify_all();
}
// Deflate a single monitor if not in-use
@@ -2039,12 +2079,12 @@
void ObjectSynchronizer::deflate_idle_monitors(DeflateMonitorCounters* counters) {
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
if (AsyncDeflateIdleMonitors) {
// Nothing to do when global idle ObjectMonitors are deflated using
- // a JavaThread unless a special cleanup has been requested.
- if (!is_cleanup_requested()) {
+ // a JavaThread unless a special deflation has been requested.
+ if (!is_special_deflation_requested()) {
return;
}
}
bool deflated = false;
@@ -2104,12 +2144,10 @@
void ObjectSynchronizer::deflate_global_idle_monitors_using_JT() {
assert(AsyncDeflateIdleMonitors, "sanity check");
assert(Thread::current()->is_Java_thread(), "precondition");
JavaThread * self = JavaThread::current();
- _gOmShouldDeflateIdleMonitors = false;
-
deflate_common_idle_monitors_using_JT(true /* is_global */, self);
}
// Deflate per-thread idle ObjectMonitors using a JavaThread.
//
@@ -2225,17 +2263,17 @@
// Report the cumulative time for deflating each thread's idle
// monitors. Note: if the work is split among more than one
// worker thread, then the reported time will likely be more
// than a beginning to end measurement of the phase.
// Note: AsyncDeflateIdleMonitors only deflates per-thread idle
- // monitors at a safepoint when a special cleanup has been requested.
+ // monitors at a safepoint when a special deflation has been requested.
log_info(safepoint, cleanup)("deflating per-thread idle monitors, %3.7f secs, monitors=%d", counters->perThreadTimes, counters->perThreadScavenged);
- bool needs_special_cleanup = is_cleanup_requested();
- if (!AsyncDeflateIdleMonitors || needs_special_cleanup) {
+ bool needs_special_deflation = is_special_deflation_requested();
+ if (!AsyncDeflateIdleMonitors || needs_special_deflation) {
// AsyncDeflateIdleMonitors does not use these counters unless
- // there is a special cleanup request.
+ // there is a special deflation request.
gMonitorFreeCount += counters->nScavenged;
OM_PERFDATA_OP(Deflations, inc(counters->nScavenged));
OM_PERFDATA_OP(MonExtant, set_value(counters->nInCirculation));
@@ -2254,22 +2292,22 @@
}
ForceMonitorScavenge = 0; // Reset
GVars.stwRandom = os::random();
GVars.stwCycle++;
- if (needs_special_cleanup) {
- set_is_cleanup_requested(false); // special clean up is done
+ if (needs_special_deflation) {
+ set_is_special_deflation_requested(false); // special deflation is done
}
}
void ObjectSynchronizer::deflate_thread_local_monitors(Thread* thread, DeflateMonitorCounters* counters) {
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
if (AsyncDeflateIdleMonitors) {
- if (!is_cleanup_requested()) {
- // Mark the JavaThread for idle monitor cleanup if a special
- // cleanup has NOT been requested.
+ if (!is_special_deflation_requested()) {
+ // Mark the JavaThread for idle monitor deflation if a special
+ // deflation has NOT been requested.
if (thread->omInUseCount > 0) {
// This JavaThread is using monitors so mark it.
thread->omShouldDeflateIdleMonitors = true;
}
return;
< prev index next >