1 /*
  2  * Copyright (c) 2017, 2019, Red Hat, Inc. 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 
 27 #include "gc/shared/gc_globals.hpp"
 28 #include "gc/shared/workerPolicy.hpp"
 29 #include "gc/shenandoah/shenandoahWorkerPolicy.hpp"
 30 #include "runtime/javaThread.hpp"
 31 #include "runtime/threads.hpp"
 32 
 33 uint ShenandoahWorkerPolicy::_prev_par_marking     = 0;
 34 uint ShenandoahWorkerPolicy::_prev_conc_marking    = 0;
 35 uint ShenandoahWorkerPolicy::_prev_conc_evac       = 0;
 36 uint ShenandoahWorkerPolicy::_prev_conc_root_proc  = 0;
 37 uint ShenandoahWorkerPolicy::_prev_conc_refs_proc  = 0;
 38 uint ShenandoahWorkerPolicy::_prev_fullgc          = 0;
 39 uint ShenandoahWorkerPolicy::_prev_degengc         = 0;
 40 uint ShenandoahWorkerPolicy::_prev_conc_update_ref = 0;
 41 uint ShenandoahWorkerPolicy::_prev_par_update_ref  = 0;
 42 uint ShenandoahWorkerPolicy::_prev_conc_cleanup    = 0;
 43 uint ShenandoahWorkerPolicy::_prev_conc_reset      = 0;
 44 
 45 uint ShenandoahWorkerPolicy::calc_workers_for_init_marking() {
 46   uint active_workers = (_prev_par_marking == 0) ? ParallelGCThreads : _prev_par_marking;
 47 
 48   _prev_par_marking =
 49     WorkerPolicy::calc_active_workers(ParallelGCThreads,
 50                                       active_workers,
 51                                       Threads::number_of_non_daemon_threads());
 52   return _prev_par_marking;
 53 }
 54 
 55 uint ShenandoahWorkerPolicy::calc_workers_for_conc_marking() {
 56   uint active_workers = (_prev_conc_marking == 0) ?  ConcGCThreads : _prev_conc_marking;
 57   _prev_conc_marking =
 58     WorkerPolicy::calc_active_conc_workers(ConcGCThreads,
 59                                            active_workers,
 60                                            Threads::number_of_non_daemon_threads());
 61   return _prev_conc_marking;
 62 }
 63 
 64 // Reuse the calculation result from init marking
 65 uint ShenandoahWorkerPolicy::calc_workers_for_final_marking() {
 66   return _prev_par_marking;
 67 }
 68 
 69 // Calculate workers for concurrent refs processing
 70 uint ShenandoahWorkerPolicy::calc_workers_for_conc_refs_processing() {
 71   uint active_workers = (_prev_conc_refs_proc == 0) ? ConcGCThreads : _prev_conc_refs_proc;
 72   _prev_conc_refs_proc =
 73     WorkerPolicy::calc_active_conc_workers(ConcGCThreads,
 74                                            active_workers,
 75                                            Threads::number_of_non_daemon_threads());
 76   return _prev_conc_refs_proc;
 77 }
 78 
 79 // Calculate workers for concurrent root processing
 80 uint ShenandoahWorkerPolicy::calc_workers_for_conc_root_processing() {
 81   uint active_workers = (_prev_conc_root_proc == 0) ? ConcGCThreads : _prev_conc_root_proc;
 82   _prev_conc_root_proc =
 83           WorkerPolicy::calc_active_conc_workers(ConcGCThreads,
 84                                                  active_workers,
 85                                                  Threads::number_of_non_daemon_threads());
 86   return _prev_conc_root_proc;
 87 }
 88 
 89 // Calculate workers for concurrent evacuation (concurrent GC)
 90 uint ShenandoahWorkerPolicy::calc_workers_for_conc_evac() {
 91   uint active_workers = (_prev_conc_evac == 0) ? ConcGCThreads : _prev_conc_evac;
 92   _prev_conc_evac =
 93     WorkerPolicy::calc_active_conc_workers(ConcGCThreads,
 94                                            active_workers,
 95                                            Threads::number_of_non_daemon_threads());
 96   return _prev_conc_evac;
 97 }
 98 
 99 // Calculate workers for parallel fullgc
100 uint ShenandoahWorkerPolicy::calc_workers_for_fullgc() {
101   uint active_workers = (_prev_fullgc == 0) ?  ParallelGCThreads : _prev_fullgc;
102   _prev_fullgc =
103     WorkerPolicy::calc_active_workers(ParallelGCThreads,
104                                       active_workers,
105                                       Threads::number_of_non_daemon_threads());
106   return _prev_fullgc;
107 }
108 
109 // Calculate workers for parallel degenerated gc
110 uint ShenandoahWorkerPolicy::calc_workers_for_stw_degenerated() {
111   uint active_workers = (_prev_degengc == 0) ?  ParallelGCThreads : _prev_degengc;
112   _prev_degengc =
113     WorkerPolicy::calc_active_workers(ParallelGCThreads,
114                                       active_workers,
115                                       Threads::number_of_non_daemon_threads());
116   return _prev_degengc;
117 }
118 
119 // Calculate workers for concurrent reference update
120 uint ShenandoahWorkerPolicy::calc_workers_for_conc_update_ref() {
121   uint active_workers = (_prev_conc_update_ref == 0) ? ConcGCThreads : _prev_conc_update_ref;
122   _prev_conc_update_ref =
123     WorkerPolicy::calc_active_conc_workers(ConcGCThreads,
124                                            active_workers,
125                                            Threads::number_of_non_daemon_threads());
126   return _prev_conc_update_ref;
127 }
128 
129 // Calculate workers for parallel reference update
130 uint ShenandoahWorkerPolicy::calc_workers_for_final_update_ref() {
131   uint active_workers = (_prev_par_update_ref == 0) ? ParallelGCThreads : _prev_par_update_ref;
132   _prev_par_update_ref =
133     WorkerPolicy::calc_active_workers(ParallelGCThreads,
134                                       active_workers,
135                                       Threads::number_of_non_daemon_threads());
136   return _prev_par_update_ref;
137 }
138 
139 uint ShenandoahWorkerPolicy::calc_workers_for_conc_cleanup() {
140   uint active_workers = (_prev_conc_cleanup == 0) ? ConcGCThreads : _prev_conc_cleanup;
141   _prev_conc_cleanup =
142           WorkerPolicy::calc_active_conc_workers(ConcGCThreads,
143                                                  active_workers,
144                                                  Threads::number_of_non_daemon_threads());
145   return _prev_conc_cleanup;
146 }
147 
148 uint ShenandoahWorkerPolicy::calc_workers_for_conc_reset() {
149   uint active_workers = (_prev_conc_reset == 0) ? ConcGCThreads : _prev_conc_reset;
150   _prev_conc_reset =
151           WorkerPolicy::calc_active_conc_workers(ConcGCThreads,
152                                                  active_workers,
153                                                  Threads::number_of_non_daemon_threads());
154   return _prev_conc_reset;
155 }