--- 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() {