src/hotspot/share/gc/z/zMetronome.cpp
changeset 54922 185ffc45593c
parent 54623 1126f0607c70
--- a/src/hotspot/share/gc/z/zMetronome.cpp	Fri May 17 11:44:44 2019 +0200
+++ b/src/hotspot/share/gc/z/zMetronome.cpp	Fri May 17 12:06:03 2019 +0200
@@ -34,10 +34,6 @@
     _nticks(0),
     _stopped(false) {}
 
-uint64_t ZMetronome::nticks() const {
-  return _nticks;
-}
-
 bool ZMetronome::wait_for_tick() {
   if (_nticks++ == 0) {
     // First tick, set start time
@@ -45,7 +41,9 @@
     _start_ms = TimeHelper::counter_to_millis(now.value());
   }
 
-  for (;;) {
+  MonitorLocker ml(&_monitor, Monitor::_no_safepoint_check_flag);
+
+  while (!_stopped) {
     // We might wake up spuriously from wait, so always recalculate
     // the timeout after a wakeup to see if we need to wait again.
     const Ticks now = Ticks::now();
@@ -53,15 +51,27 @@
     const uint64_t next_ms = _start_ms + (_interval_ms * _nticks);
     const int64_t timeout_ms = next_ms - now_ms;
 
-    MonitorLocker ml(&_monitor, Monitor::_no_safepoint_check_flag);
-    if (!_stopped && timeout_ms > 0) {
+    if (timeout_ms > 0) {
       // Wait
       ml.wait(timeout_ms);
     } else {
       // Tick
-      return !_stopped;
+      if (timeout_ms < 0) {
+        const uint64_t overslept = -timeout_ms;
+        if (overslept > _interval_ms) {
+          // Missed one or more ticks. Bump _nticks accordingly to
+          // avoid firing a string of immediate ticks to make up
+          // for the ones we missed.
+          _nticks += overslept / _interval_ms;
+        }
+      }
+
+      return true;
     }
   }
+
+  // Stopped
+  return false;
 }
 
 void ZMetronome::stop() {