< prev index next >

src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp

Print this page
rev 52688 : imported patch pqs_threshold_types
rev 52689 : [mq]: tschatzl_review


 127     }
 128   }
 129 }
 130 
 131 void G1ConcurrentRefineThreadControl::stop() {
 132   for (uint i = 0; i < _num_max_threads; i++) {
 133     if (_threads[i] != NULL) {
 134       _threads[i]->stop();
 135     }
 136   }
 137 }
 138 
 139 // Arbitrary but large limits, to simplify some of the zone calculations.
 140 // The general idea is to allow expressions like
 141 //   MIN2(x OP y, max_XXX_zone)
 142 // without needing to check for overflow in "x OP y", because the
 143 // ranges for x and y have been restricted.
 144 STATIC_ASSERT(sizeof(LP64_ONLY(jint) NOT_LP64(jshort)) <= (sizeof(size_t)/2));
 145 const size_t max_yellow_zone = LP64_ONLY(max_jint) NOT_LP64(max_jshort);
 146 const size_t max_green_zone = max_yellow_zone / 2;
 147 const size_t max_red_zone = INT_MAX; // For dcqs.set_max_completed_queue.
 148 STATIC_ASSERT(max_yellow_zone <= max_red_zone);
 149 
 150 // Range check assertions for green zone values.
 151 #define assert_zone_constraints_g(green)                        \
 152   do {                                                          \
 153     size_t azc_g_green = (green);                               \
 154     assert(azc_g_green <= max_green_zone,                       \
 155            "green exceeds max: " SIZE_FORMAT, azc_g_green);     \
 156   } while (0)
 157 
 158 // Range check assertions for green and yellow zone values.
 159 #define assert_zone_constraints_gy(green, yellow)                       \
 160   do {                                                                  \
 161     size_t azc_gy_green = (green);                                      \
 162     size_t azc_gy_yellow = (yellow);                                    \
 163     assert_zone_constraints_g(azc_gy_green);                            \
 164     assert(azc_gy_yellow <= max_yellow_zone,                            \
 165            "yellow exceeds max: " SIZE_FORMAT, azc_gy_yellow);          \
 166     assert(azc_gy_green <= azc_gy_yellow,                               \
 167            "green (" SIZE_FORMAT ") exceeds yellow (" SIZE_FORMAT ")",  \


 369 
 370   assert_zone_constraints_gyr(_green_zone, _yellow_zone, _red_zone);
 371   LOG_ZONES("Updated Refinement Zones: "
 372             "green: " SIZE_FORMAT ", "
 373             "yellow: " SIZE_FORMAT ", "
 374             "red: " SIZE_FORMAT,
 375             _green_zone, _yellow_zone, _red_zone);
 376 }
 377 
 378 void G1ConcurrentRefine::adjust(double update_rs_time,
 379                                 size_t update_rs_processed_buffers,
 380                                 double goal_ms) {
 381   DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
 382 
 383   if (G1UseAdaptiveConcRefinement) {
 384     update_zones(update_rs_time, update_rs_processed_buffers, goal_ms);
 385 
 386     // Change the barrier params
 387     if (max_num_threads() == 0) {
 388       // Disable dcqs notification when there are no threads to notify.
 389       dcqs.set_process_completed_threshold(INT_MAX);
 390     } else {
 391       // Worker 0 is the primary; wakeup is via dcqs notification.
 392       STATIC_ASSERT(max_yellow_zone <= INT_MAX);
 393       size_t activate = activation_threshold(0);
 394       dcqs.set_process_completed_threshold((int)activate);
 395     }
 396     dcqs.set_max_completed_queue((int)red_zone());
 397   }
 398 
 399   size_t curr_queue_size = dcqs.completed_buffers_num();
 400   if (curr_queue_size >= yellow_zone()) {
 401     dcqs.set_completed_queue_padding(curr_queue_size);

 402   } else {
 403     dcqs.set_completed_queue_padding(0);
 404   }
 405   dcqs.notify_if_necessary();
 406 }
 407 
 408 size_t G1ConcurrentRefine::activation_threshold(uint worker_id) const {
 409   Thresholds thresholds = calc_thresholds(_green_zone, _yellow_zone, worker_id);
 410   return activation_level(thresholds);
 411 }
 412 
 413 size_t G1ConcurrentRefine::deactivation_threshold(uint worker_id) const {
 414   Thresholds thresholds = calc_thresholds(_green_zone, _yellow_zone, worker_id);
 415   return deactivation_level(thresholds);
 416 }
 417 
 418 uint G1ConcurrentRefine::worker_id_offset() {
 419   return DirtyCardQueueSet::num_par_ids();
 420 }
 421 
 422 void G1ConcurrentRefine::maybe_activate_more_threads(uint worker_id, size_t num_cur_buffers) {
 423   if (num_cur_buffers > activation_threshold(worker_id + 1)) {
 424     _thread_control.maybe_activate_next(worker_id);
 425   }
 426 }
 427 
 428 bool G1ConcurrentRefine::do_refinement_step(uint worker_id) {
 429   DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
 430 
 431   size_t curr_buffer_num = dcqs.completed_buffers_num();
 432   // If the number of the buffers falls down into the yellow zone,
 433   // that means that the transition period after the evacuation pause has ended.
 434   // Since the value written to the DCQS is the same for all threads, there is no
 435   // need to synchronize.
 436   if (dcqs.completed_queue_padding() > 0 && curr_buffer_num <= yellow_zone()) {
 437     dcqs.set_completed_queue_padding(0);
 438   }
 439 
 440   maybe_activate_more_threads(worker_id, curr_buffer_num);
 441 
 442   // Process the next buffer, if there are enough left.
 443   return dcqs.refine_completed_buffer_concurrently(worker_id + worker_id_offset(),
 444                                                    deactivation_threshold(worker_id));
 445 }


 127     }
 128   }
 129 }
 130 
 131 void G1ConcurrentRefineThreadControl::stop() {
 132   for (uint i = 0; i < _num_max_threads; i++) {
 133     if (_threads[i] != NULL) {
 134       _threads[i]->stop();
 135     }
 136   }
 137 }
 138 
 139 // Arbitrary but large limits, to simplify some of the zone calculations.
 140 // The general idea is to allow expressions like
 141 //   MIN2(x OP y, max_XXX_zone)
 142 // without needing to check for overflow in "x OP y", because the
 143 // ranges for x and y have been restricted.
 144 STATIC_ASSERT(sizeof(LP64_ONLY(jint) NOT_LP64(jshort)) <= (sizeof(size_t)/2));
 145 const size_t max_yellow_zone = LP64_ONLY(max_jint) NOT_LP64(max_jshort);
 146 const size_t max_green_zone = max_yellow_zone / 2;
 147 const size_t max_red_zone = INT_MAX; // For dcqs.set_max_completed_buffers.
 148 STATIC_ASSERT(max_yellow_zone <= max_red_zone);
 149 
 150 // Range check assertions for green zone values.
 151 #define assert_zone_constraints_g(green)                        \
 152   do {                                                          \
 153     size_t azc_g_green = (green);                               \
 154     assert(azc_g_green <= max_green_zone,                       \
 155            "green exceeds max: " SIZE_FORMAT, azc_g_green);     \
 156   } while (0)
 157 
 158 // Range check assertions for green and yellow zone values.
 159 #define assert_zone_constraints_gy(green, yellow)                       \
 160   do {                                                                  \
 161     size_t azc_gy_green = (green);                                      \
 162     size_t azc_gy_yellow = (yellow);                                    \
 163     assert_zone_constraints_g(azc_gy_green);                            \
 164     assert(azc_gy_yellow <= max_yellow_zone,                            \
 165            "yellow exceeds max: " SIZE_FORMAT, azc_gy_yellow);          \
 166     assert(azc_gy_green <= azc_gy_yellow,                               \
 167            "green (" SIZE_FORMAT ") exceeds yellow (" SIZE_FORMAT ")",  \


 369 
 370   assert_zone_constraints_gyr(_green_zone, _yellow_zone, _red_zone);
 371   LOG_ZONES("Updated Refinement Zones: "
 372             "green: " SIZE_FORMAT ", "
 373             "yellow: " SIZE_FORMAT ", "
 374             "red: " SIZE_FORMAT,
 375             _green_zone, _yellow_zone, _red_zone);
 376 }
 377 
 378 void G1ConcurrentRefine::adjust(double update_rs_time,
 379                                 size_t update_rs_processed_buffers,
 380                                 double goal_ms) {
 381   DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
 382 
 383   if (G1UseAdaptiveConcRefinement) {
 384     update_zones(update_rs_time, update_rs_processed_buffers, goal_ms);
 385 
 386     // Change the barrier params
 387     if (max_num_threads() == 0) {
 388       // Disable dcqs notification when there are no threads to notify.
 389       dcqs.set_process_completed_buffers_threshold(DirtyCardQueueSet::ProcessCompletedBuffersThresholdNever);
 390     } else {
 391       // Worker 0 is the primary; wakeup is via dcqs notification.
 392       STATIC_ASSERT(max_yellow_zone <= INT_MAX);
 393       size_t activate = activation_threshold(0);
 394       dcqs.set_process_completed_buffers_threshold(activate);
 395     }
 396     dcqs.set_max_completed_buffers(red_zone());
 397   }
 398 
 399   size_t curr_queue_size = dcqs.completed_buffers_num();
 400   if ((dcqs.max_completed_buffers() > 0) &&
 401       (curr_queue_size >= yellow_zone())) {
 402     dcqs.set_completed_buffers_padding(curr_queue_size);
 403   } else {
 404     dcqs.set_completed_buffers_padding(0);
 405   }
 406   dcqs.notify_if_necessary();
 407 }
 408 
 409 size_t G1ConcurrentRefine::activation_threshold(uint worker_id) const {
 410   Thresholds thresholds = calc_thresholds(_green_zone, _yellow_zone, worker_id);
 411   return activation_level(thresholds);
 412 }
 413 
 414 size_t G1ConcurrentRefine::deactivation_threshold(uint worker_id) const {
 415   Thresholds thresholds = calc_thresholds(_green_zone, _yellow_zone, worker_id);
 416   return deactivation_level(thresholds);
 417 }
 418 
 419 uint G1ConcurrentRefine::worker_id_offset() {
 420   return DirtyCardQueueSet::num_par_ids();
 421 }
 422 
 423 void G1ConcurrentRefine::maybe_activate_more_threads(uint worker_id, size_t num_cur_buffers) {
 424   if (num_cur_buffers > activation_threshold(worker_id + 1)) {
 425     _thread_control.maybe_activate_next(worker_id);
 426   }
 427 }
 428 
 429 bool G1ConcurrentRefine::do_refinement_step(uint worker_id) {
 430   DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
 431 
 432   size_t curr_buffer_num = dcqs.completed_buffers_num();
 433   // If the number of the buffers falls down into the yellow zone,
 434   // that means that the transition period after the evacuation pause has ended.
 435   // Since the value written to the DCQS is the same for all threads, there is no
 436   // need to synchronize.
 437   if (dcqs.completed_buffers_padding() > 0 && curr_buffer_num <= yellow_zone()) {
 438     dcqs.set_completed_buffers_padding(0);
 439   }
 440 
 441   maybe_activate_more_threads(worker_id, curr_buffer_num);
 442 
 443   // Process the next buffer, if there are enough left.
 444   return dcqs.refine_completed_buffer_concurrently(worker_id + worker_id_offset(),
 445                                                    deactivation_threshold(worker_id));
 446 }
< prev index next >