Skip to content

Commit a34e8be

Browse files
author
Kim Barrett
committed
8230126: delay_to_keep_mmu can delay shutdown
Wait on CGC_lock instead of sleeping to provide the delay. Reviewed-by: sangheki, sjohanss
1 parent be0cd99 commit a34e8be

File tree

2 files changed

+19
-7
lines changed

2 files changed

+19
-7
lines changed

src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ class CMCleanup : public VoidClosure {
107107
}
108108
};
109109

110-
double G1ConcurrentMarkThread::mmu_sleep_time(G1Policy* g1_policy, bool remark) {
110+
double G1ConcurrentMarkThread::mmu_delay_end(G1Policy* g1_policy, bool remark) {
111111
// There are 3 reasons to use SuspendibleThreadSetJoiner.
112112
// 1. To avoid concurrency problem.
113113
// - G1MMUTracker::add_pause(), when_sec() and its variation(when_ms() etc..) can be called
@@ -119,18 +119,30 @@ double G1ConcurrentMarkThread::mmu_sleep_time(G1Policy* g1_policy, bool remark)
119119
SuspendibleThreadSetJoiner sts_join;
120120

121121
const G1Analytics* analytics = g1_policy->analytics();
122-
double now = os::elapsedTime();
123122
double prediction_ms = remark ? analytics->predict_remark_time_ms()
124123
: analytics->predict_cleanup_time_ms();
124+
double prediction = prediction_ms / MILLIUNITS;
125125
G1MMUTracker *mmu_tracker = g1_policy->mmu_tracker();
126-
return mmu_tracker->when_ms(now, prediction_ms);
126+
double now = os::elapsedTime();
127+
return now + mmu_tracker->when_sec(now, prediction);
127128
}
128129

129130
void G1ConcurrentMarkThread::delay_to_keep_mmu(G1Policy* g1_policy, bool remark) {
130131
if (g1_policy->use_adaptive_young_list_length()) {
131-
jlong sleep_time_ms = mmu_sleep_time(g1_policy, remark);
132-
if (!_cm->has_aborted() && sleep_time_ms > 0) {
133-
os::sleep(this, sleep_time_ms, false);
132+
double delay_end_sec = mmu_delay_end(g1_policy, remark);
133+
// Wait for timeout or thread termination request.
134+
MonitorLocker ml(CGC_lock, Monitor::_no_safepoint_check_flag);
135+
while (!_cm->has_aborted()) {
136+
double sleep_time_sec = (delay_end_sec - os::elapsedTime());
137+
jlong sleep_time_ms = ceil(sleep_time_sec * MILLIUNITS);
138+
if (sleep_time_ms <= 0) {
139+
break; // Passed end time.
140+
} else if (ml.wait(sleep_time_ms, Monitor::_no_safepoint_check_flag)) {
141+
break; // Timeout => reached end time.
142+
} else if (should_terminate()) {
143+
break; // Wakeup for pending termination request.
144+
}
145+
// Other (possibly spurious) wakeup. Retry with updated sleep time.
134146
}
135147
}
136148
}

src/hotspot/share/gc/g1/g1ConcurrentMarkThread.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class G1ConcurrentMarkThread: public ConcurrentGCThread {
5656
void sleep_before_next_cycle();
5757
// Delay marking to meet MMU.
5858
void delay_to_keep_mmu(G1Policy* g1_policy, bool remark);
59-
double mmu_sleep_time(G1Policy* g1_policy, bool remark);
59+
double mmu_delay_end(G1Policy* g1_policy, bool remark);
6060

6161
void run_service();
6262
void stop_service();

0 commit comments

Comments
 (0)