< 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 >