src/hotspot/share/gc/g1/g1ConcurrentRefineThread.cpp
changeset 48103 26dbe08d1c17
parent 47789 a77a7d3bc4f6
child 49751 c3a10df652c0
equal deleted inserted replaced
48102:08be4c1e540e 48103:26dbe08d1c17
    23  */
    23  */
    24 
    24 
    25 #include "precompiled.hpp"
    25 #include "precompiled.hpp"
    26 #include "gc/g1/g1ConcurrentRefine.hpp"
    26 #include "gc/g1/g1ConcurrentRefine.hpp"
    27 #include "gc/g1/g1ConcurrentRefineThread.hpp"
    27 #include "gc/g1/g1ConcurrentRefineThread.hpp"
    28 #include "gc/g1/g1CollectedHeap.inline.hpp"
       
    29 #include "gc/g1/g1RemSet.hpp"
       
    30 #include "gc/shared/suspendibleThreadSet.hpp"
    28 #include "gc/shared/suspendibleThreadSet.hpp"
    31 #include "logging/log.hpp"
    29 #include "logging/log.hpp"
    32 #include "memory/resourceArea.hpp"
    30 #include "memory/resourceArea.hpp"
    33 #include "runtime/handles.inline.hpp"
    31 #include "runtime/handles.inline.hpp"
    34 #include "runtime/mutexLocker.hpp"
    32 #include "runtime/mutexLocker.hpp"
    35 
    33 
    36 G1ConcurrentRefineThread::G1ConcurrentRefineThread(G1ConcurrentRefine* cr,
    34 G1ConcurrentRefineThread::G1ConcurrentRefineThread(G1ConcurrentRefine* cr, uint worker_id) :
    37                                                    G1ConcurrentRefineThread *next,
       
    38                                                    uint worker_id_offset,
       
    39                                                    uint worker_id,
       
    40                                                    size_t activate,
       
    41                                                    size_t deactivate) :
       
    42   ConcurrentGCThread(),
    35   ConcurrentGCThread(),
    43   _worker_id_offset(worker_id_offset),
       
    44   _worker_id(worker_id),
    36   _worker_id(worker_id),
    45   _active(false),
    37   _active(false),
    46   _next(next),
       
    47   _monitor(NULL),
    38   _monitor(NULL),
    48   _cr(cr),
    39   _cr(cr),
    49   _vtime_accum(0.0),
    40   _vtime_accum(0.0)
    50   _activation_threshold(activate),
       
    51   _deactivation_threshold(deactivate)
       
    52 {
    41 {
    53 
       
    54   // Each thread has its own monitor. The i-th thread is responsible for signaling
    42   // Each thread has its own monitor. The i-th thread is responsible for signaling
    55   // to thread i+1 if the number of buffers in the queue exceeds a threshold for this
    43   // to thread i+1 if the number of buffers in the queue exceeds a threshold for this
    56   // thread. Monitors are also used to wake up the threads during termination.
    44   // thread. Monitors are also used to wake up the threads during termination.
    57   // The 0th (primary) worker is notified by mutator threads and has a special monitor.
    45   // The 0th (primary) worker is notified by mutator threads and has a special monitor.
    58   if (!is_primary()) {
    46   if (!is_primary()) {
    63   }
    51   }
    64 
    52 
    65   // set name
    53   // set name
    66   set_name("G1 Refine#%d", worker_id);
    54   set_name("G1 Refine#%d", worker_id);
    67   create_and_start();
    55   create_and_start();
    68 }
       
    69 
       
    70 void G1ConcurrentRefineThread::update_thresholds(size_t activate,
       
    71                                                  size_t deactivate) {
       
    72   assert(deactivate < activate, "precondition");
       
    73   _activation_threshold = activate;
       
    74   _deactivation_threshold = deactivate;
       
    75 }
    56 }
    76 
    57 
    77 void G1ConcurrentRefineThread::wait_for_completed_buffers() {
    58 void G1ConcurrentRefineThread::wait_for_completed_buffers() {
    78   MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
    59   MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
    79   while (!should_terminate() && !is_active()) {
    60   while (!should_terminate() && !is_active()) {
   116     if (should_terminate()) {
    97     if (should_terminate()) {
   117       break;
    98       break;
   118     }
    99     }
   119 
   100 
   120     size_t buffers_processed = 0;
   101     size_t buffers_processed = 0;
   121     DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
   102     log_debug(gc, refine)("Activated worker %d, on threshold: " SIZE_FORMAT ", current: " SIZE_FORMAT,
   122     log_debug(gc, refine)("Activated %d, on threshold: " SIZE_FORMAT ", current: " SIZE_FORMAT,
   103                           _worker_id, _cr->activation_threshold(_worker_id),
   123                           _worker_id, _activation_threshold, dcqs.completed_buffers_num());
   104                            JavaThread::dirty_card_queue_set().completed_buffers_num());
   124 
   105 
   125     {
   106     {
   126       SuspendibleThreadSetJoiner sts_join;
   107       SuspendibleThreadSetJoiner sts_join;
   127 
   108 
   128       while (!should_terminate()) {
   109       while (!should_terminate()) {
   129         if (sts_join.should_yield()) {
   110         if (sts_join.should_yield()) {
   130           sts_join.yield();
   111           sts_join.yield();
   131           continue;             // Re-check for termination after yield delay.
   112           continue;             // Re-check for termination after yield delay.
   132         }
   113         }
   133 
   114 
   134         size_t curr_buffer_num = dcqs.completed_buffers_num();
   115         if (!_cr->do_refinement_step(_worker_id)) {
   135         // If the number of the buffers falls down into the yellow zone,
   116           break;
   136         // that means that the transition period after the evacuation pause has ended.
       
   137         if (dcqs.completed_queue_padding() > 0 && curr_buffer_num <= cr()->yellow_zone()) {
       
   138           dcqs.set_completed_queue_padding(0);
       
   139         }
       
   140 
       
   141         // Check if we need to activate the next thread.
       
   142         if ((_next != NULL) &&
       
   143             !_next->is_active() &&
       
   144             (curr_buffer_num > _next->_activation_threshold)) {
       
   145           _next->activate();
       
   146         }
       
   147 
       
   148         // Process the next buffer, if there are enough left.
       
   149         if (!dcqs.refine_completed_buffer_concurrently(_worker_id + _worker_id_offset, _deactivation_threshold)) {
       
   150           break; // Deactivate, number of buffers fell below threshold.
       
   151         }
   117         }
   152         ++buffers_processed;
   118         ++buffers_processed;
   153       }
   119       }
   154     }
   120     }
   155 
   121 
   156     deactivate();
   122     deactivate();
   157     log_debug(gc, refine)("Deactivated %d, off threshold: " SIZE_FORMAT
   123     log_debug(gc, refine)("Deactivated worker %d, off threshold: " SIZE_FORMAT
   158                           ", current: " SIZE_FORMAT ", processed: " SIZE_FORMAT,
   124                           ", current: " SIZE_FORMAT ", processed: " SIZE_FORMAT,
   159                           _worker_id, _deactivation_threshold,
   125                           _worker_id, _cr->deactivation_threshold(_worker_id),
   160                           dcqs.completed_buffers_num(),
   126                           JavaThread::dirty_card_queue_set().completed_buffers_num(),
   161                           buffers_processed);
   127                           buffers_processed);
   162 
   128 
   163     if (os::supports_vtime()) {
   129     if (os::supports_vtime()) {
   164       _vtime_accum = (os::elapsedVTime() - _vtime_start);
   130       _vtime_accum = (os::elapsedVTime() - _vtime_start);
   165     } else {
   131     } else {