< prev index next >
src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp
Print this page
rev 56085 : [mq]: use_monitor
*** 105,115 ****
void do_void(){
_cm->cleanup();
}
};
! double G1ConcurrentMarkThread::mmu_sleep_time(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 currently a gc is running, but it has not yet updated the MMU,
--- 105,115 ----
void do_void(){
_cm->cleanup();
}
};
! double G1ConcurrentMarkThread::mmu_delay_end(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 currently a gc is running, but it has not yet updated the MMU,
*** 117,138 ****
// 3. If currently a gc is running, ConcurrentMarkThread will wait it to be finished.
// And then sleep for predicted amount of time by delay_to_keep_mmu().
SuspendibleThreadSetJoiner sts_join;
const G1Analytics* analytics = g1_policy->analytics();
- 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();
! return mmu_tracker->when_ms(now, prediction_ms);
}
void G1ConcurrentMarkThread::delay_to_keep_mmu(G1Policy* g1_policy, bool remark) {
if (g1_policy->use_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)> {
--- 117,150 ----
// 3. If currently a gc is running, ConcurrentMarkThread will wait it to be finished.
// And then sleep for predicted amount of time by delay_to_keep_mmu().
SuspendibleThreadSetJoiner sts_join;
const G1Analytics* analytics = g1_policy->analytics();
double prediction_ms = remark ? analytics->predict_remark_time_ms()
: analytics->predict_cleanup_time_ms();
+ double prediction = prediction_ms / MILLIUNITS;
G1MMUTracker *mmu_tracker = g1_policy->mmu_tracker();
! double now = os::elapsedTime();
! return now + mmu_tracker->when_sec(now, prediction);
}
void G1ConcurrentMarkThread::delay_to_keep_mmu(G1Policy* g1_policy, bool remark) {
if (g1_policy->use_adaptive_young_list_length()) {
! double delay_end_sec = mmu_delay_end(g1_policy, remark);
! // Wait for timeout or thread termination request.
! MonitorLocker ml(CGC_lock, Monitor::_no_safepoint_check_flag);
! while (!_cm->has_aborted()) {
! double sleep_time_sec = (delay_end_sec - os::elapsedTime());
! jlong sleep_time_ms = ceil(sleep_time_sec * MILLIUNITS);
! if (sleep_time_ms <= 0) {
! break; // Passed end time.
! } else if (ml.wait(sleep_time_ms, Monitor::_no_safepoint_check_flag)) {
! break; // Timeout => reached end time.
! } else if (should_terminate()) {
! break; // Wakeup for pending termination request.
! }
! // Other (possibly spurious) wakeup. Retry with updated sleep time.
}
}
}
class G1ConcPhaseTimer : public GCTraceConcTimeImpl<LogLevel::Info, LOG_TAGS(gc, marking)> {
< prev index next >