src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp
changeset 57913 d1a6f72e4aec
parent 55268 c5fe45d1281d
child 58002 01d31583f25c
equal deleted inserted replaced
57907:f080150a6a7e 57913:d1a6f72e4aec
   105   void do_void(){
   105   void do_void(){
   106     _cm->cleanup();
   106     _cm->cleanup();
   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   // There are 3 reasons to use SuspendibleThreadSetJoiner.
   111   // There are 3 reasons to use SuspendibleThreadSetJoiner.
   112   // 1. To avoid concurrency problem.
   112   // 1. To avoid concurrency problem.
   113   //    - G1MMUTracker::add_pause(), when_sec() and its variation(when_ms() etc..) can be called
   113   //    - G1MMUTracker::add_pause(), when_sec() and its variation(when_ms() etc..) can be called
   114   //      concurrently from ConcurrentMarkThread and VMThread.
   114   //      concurrently from ConcurrentMarkThread and VMThread.
   115   // 2. If currently a gc is running, but it has not yet updated the MMU,
   115   // 2. If currently a gc is running, but it has not yet updated the MMU,
   117   // 3. If currently a gc is running, ConcurrentMarkThread will wait it to be finished.
   117   // 3. If currently a gc is running, ConcurrentMarkThread will wait it to be finished.
   118   //    And then sleep for predicted amount of time by delay_to_keep_mmu().
   118   //    And then sleep for predicted amount of time by delay_to_keep_mmu().
   119   SuspendibleThreadSetJoiner sts_join;
   119   SuspendibleThreadSetJoiner sts_join;
   120 
   120 
   121   const G1Analytics* analytics = g1_policy->analytics();
   121   const G1Analytics* analytics = g1_policy->analytics();
   122   double now = os::elapsedTime();
       
   123   double prediction_ms = remark ? analytics->predict_remark_time_ms()
   122   double prediction_ms = remark ? analytics->predict_remark_time_ms()
   124                                 : analytics->predict_cleanup_time_ms();
   123                                 : analytics->predict_cleanup_time_ms();
       
   124   double prediction = prediction_ms / MILLIUNITS;
   125   G1MMUTracker *mmu_tracker = g1_policy->mmu_tracker();
   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 void G1ConcurrentMarkThread::delay_to_keep_mmu(G1Policy* g1_policy, bool remark) {
   130 void G1ConcurrentMarkThread::delay_to_keep_mmu(G1Policy* g1_policy, bool remark) {
   130   if (g1_policy->use_adaptive_young_list_length()) {
   131   if (g1_policy->use_adaptive_young_list_length()) {
   131     jlong sleep_time_ms = mmu_sleep_time(g1_policy, remark);
   132     double delay_end_sec = mmu_delay_end(g1_policy, remark);
   132     if (!_cm->has_aborted() && sleep_time_ms > 0) {
   133     // Wait for timeout or thread termination request.
   133       os::sleep(this, sleep_time_ms, false);
   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 }
   137 
   149 
   138 class G1ConcPhaseTimer : public GCTraceConcTimeImpl<LogLevel::Info, LOG_TAGS(gc, marking)> {
   150 class G1ConcPhaseTimer : public GCTraceConcTimeImpl<LogLevel::Info, LOG_TAGS(gc, marking)> {