< prev index next >
src/hotspot/share/gc/g1/concurrentMarkThread.cpp
Print this page
rev 47419 : imported patch webrev.0
@@ -109,21 +109,35 @@
void do_void(){
_cm->cleanup();
}
};
-// Marking pauses can be scheduled flexibly, so we might delay marking to meet MMU.
-void ConcurrentMarkThread::delay_to_keep_mmu(G1Policy* g1_policy, bool remark) {
+// There are 3 reasons to use SuspendibleThreadSetJoiner.
+// 1. To avoid concurrency problem.
+// - G1MMUTracker::add_pause(), when_sec() and its variation(when_ms() etc..) can be called
+// concurrently from ConcurrentMarkThread and VMThread.
+// 2. If there is running young gc but not yet updated MMU, its gc time will be reflected at this MMU calculation.
+// 3. ConcurrentMarkThread will not sleep if there is young gc which makes MMU more accurate.
+double ConcurrentMarkThread::mmu_sleep_time(G1Policy* g1_policy, bool remark) {
+ SuspendibleThreadSetJoiner sts_join;
+
const G1Analytics* analytics = g1_policy->analytics();
- if (g1_policy->adaptive_young_list_length()) {
double now = os::elapsedTime();
double prediction_ms = remark ? analytics->predict_remark_time_ms()
: analytics->predict_cleanup_time_ms();
G1MMUTracker *mmu_tracker = g1_policy->mmu_tracker();
- jlong sleep_time_ms = mmu_tracker->when_ms(now, prediction_ms);
+ return mmu_tracker->when_ms(now, prediction_ms);
+}
+
+// Marking pauses can be scheduled flexibly, so we might delay marking to meet MMU.
+void ConcurrentMarkThread::delay_to_keep_mmu(G1Policy* g1_policy, bool remark) {
+ if (g1_policy->adaptive_young_list_length()) {
+ jlong sleep_time_ms = mmu_sleep_time(g1_policy, remark);
+ if (!cm()->has_aborted() && sleep_time_ms > 0) {
os::sleep(this, sleep_time_ms, false);
}
+ }
}
class G1ConcPhaseTimer : public GCTraceConcTimeImpl<LogLevel::Info, LOG_TAGS(gc, marking)> {
G1ConcurrentMark* _cm;
@@ -347,13 +361,15 @@
_vtime_accum = (end_time - _vtime_start);
if (!cm()->has_aborted()) {
delay_to_keep_mmu(g1_policy, false /* cleanup */);
+ if (!cm()->has_aborted()) {
CMCleanUp cl_cl(_cm);
VM_CGC_Operation op(&cl_cl, "Pause Cleanup");
VMThread::execute(&op);
+ }
} else {
// We don't want to update the marking status if a GC pause
// is already underway.
SuspendibleThreadSetJoiner sts_join;
g1h->collector_state()->set_mark_in_progress(false);
< prev index next >