@@ -107,7 +107,7 @@ class CMCleanup : public VoidClosure {
107
107
}
108
108
};
109
109
110
- double G1ConcurrentMarkThread::mmu_sleep_time (G1Policy* g1_policy, bool remark) {
110
+ double G1ConcurrentMarkThread::mmu_delay_end (G1Policy* g1_policy, bool remark) {
111
111
// There are 3 reasons to use SuspendibleThreadSetJoiner.
112
112
// 1. To avoid concurrency problem.
113
113
// - 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)
119
119
SuspendibleThreadSetJoiner sts_join;
120
120
121
121
const G1Analytics* analytics = g1_policy->analytics ();
122
- double now = os::elapsedTime ();
123
122
double prediction_ms = remark ? analytics->predict_remark_time_ms ()
124
123
: analytics->predict_cleanup_time_ms ();
124
+ double prediction = prediction_ms / MILLIUNITS;
125
125
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);
127
128
}
128
129
129
130
void G1ConcurrentMarkThread::delay_to_keep_mmu (G1Policy* g1_policy, bool remark) {
130
131
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.
134
146
}
135
147
}
136
148
}
0 commit comments