< prev index next >

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

Print this page
rev 53582 : imported patch rename
   1 /*
   2  * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "gc/g1/g1BarrierSet.hpp"
  27 #include "gc/g1/g1ConcurrentRefine.hpp"
  28 #include "gc/g1/g1ConcurrentRefineThread.hpp"

  29 #include "logging/log.hpp"
  30 #include "memory/allocation.inline.hpp"
  31 #include "runtime/java.hpp"
  32 #include "runtime/thread.hpp"
  33 #include "utilities/debug.hpp"
  34 #include "utilities/globalDefinitions.hpp"
  35 #include "utilities/pair.hpp"
  36 #include <math.h>
  37 
  38 G1ConcurrentRefineThread* G1ConcurrentRefineThreadControl::create_refinement_thread(uint worker_id, bool initializing) {
  39   G1ConcurrentRefineThread* result = NULL;
  40   if (initializing || !InjectGCWorkerCreationFailure) {
  41     result = new G1ConcurrentRefineThread(_cr, worker_id);
  42   }
  43   if (result == NULL || result->osthread() == NULL) {
  44     log_warning(gc)("Failed to create refinement thread %u, no more %s",
  45                     worker_id,
  46                     result == NULL ? "memory" : "OS threads");
  47   }
  48   return result;


 361                          goal_ms);
 362 
 363   _green_zone = calc_new_green_zone(_green_zone,
 364                                     update_rs_time,
 365                                     update_rs_processed_buffers,
 366                                     goal_ms);
 367   _yellow_zone = calc_new_yellow_zone(_green_zone, _min_yellow_zone_size);
 368   _red_zone = calc_new_red_zone(_green_zone, _yellow_zone);
 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 }
   1 /*
   2  * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "gc/g1/g1BarrierSet.hpp"
  27 #include "gc/g1/g1ConcurrentRefine.hpp"
  28 #include "gc/g1/g1ConcurrentRefineThread.hpp"
  29 #include "gc/g1/g1DirtyCardQueue.hpp"
  30 #include "logging/log.hpp"
  31 #include "memory/allocation.inline.hpp"
  32 #include "runtime/java.hpp"
  33 #include "runtime/thread.hpp"
  34 #include "utilities/debug.hpp"
  35 #include "utilities/globalDefinitions.hpp"
  36 #include "utilities/pair.hpp"
  37 #include <math.h>
  38 
  39 G1ConcurrentRefineThread* G1ConcurrentRefineThreadControl::create_refinement_thread(uint worker_id, bool initializing) {
  40   G1ConcurrentRefineThread* result = NULL;
  41   if (initializing || !InjectGCWorkerCreationFailure) {
  42     result = new G1ConcurrentRefineThread(_cr, worker_id);
  43   }
  44   if (result == NULL || result->osthread() == NULL) {
  45     log_warning(gc)("Failed to create refinement thread %u, no more %s",
  46                     worker_id,
  47                     result == NULL ? "memory" : "OS threads");
  48   }
  49   return result;


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