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