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/g1ConcurrentRefine.hpp"
27 #include "gc/g1/g1ConcurrentRefineThread.hpp"
28 #include "logging/log.hpp"
29 #include "runtime/java.hpp"
30 #include "runtime/thread.hpp"
31 #include "utilities/debug.hpp"
32 #include "utilities/globalDefinitions.hpp"
33 #include "utilities/pair.hpp"
34 #include <math.h>
35
36 G1ConcurrentRefineThreadControl::G1ConcurrentRefineThreadControl() :
37 _cg1r(NULL),
38 _threads(NULL),
39 _num_max_threads(0)
40 {
41 }
42
43 G1ConcurrentRefineThreadControl::~G1ConcurrentRefineThreadControl() {
44 for (uint i = 0; i < _num_max_threads; i++) {
45 G1ConcurrentRefineThread* t = _threads[i];
46 if (t != NULL) {
47 delete t;
48 }
49 }
50 FREE_C_HEAP_ARRAY(G1ConcurrentRefineThread*, _threads);
51 }
52
53 void G1ConcurrentRefineThreadControl::initialize(G1ConcurrentRefine* cg1r, uint num_max_threads) {
54 assert(cg1r != NULL, "Passed g1ConcurrentRefine must not be NULL");
55 _cg1r = cg1r;
56 _num_max_threads = num_max_threads;
57 _threads = NEW_C_HEAP_ARRAY(G1ConcurrentRefineThread*, num_max_threads, mtGC);
58 for (uint i = 0; i < num_max_threads; i++) {
59 if (UseDynamicNumberOfGCThreads) {
60 _threads[i] = NULL;
61 } else {
62 _threads[i] = new G1ConcurrentRefineThread(_cg1r, i);
63 }
64 }
65 }
66
67 void G1ConcurrentRefineThreadControl::maybe_activate_next(uint cur_worker_id) {
68 assert(cur_worker_id < _num_max_threads, "Tried to activate from impossible thread %u", cur_worker_id);
69 if (cur_worker_id == (_num_max_threads - 1)) {
70 // Already the last thread, there is no more thread to activate.
71 return;
72 }
73
74 uint worker_id = cur_worker_id + 1;
75 G1ConcurrentRefineThread* thread_to_activate = _threads[worker_id];
76 if (thread_to_activate == NULL) {
77 // Still need to create the thread...
78 _threads[worker_id] = new G1ConcurrentRefineThread(_cg1r, worker_id);
79 thread_to_activate = _threads[worker_id];
80 }
81 thread_to_activate->activate();
82 }
83
84 void G1ConcurrentRefineThreadControl::print_on(outputStream* st) const {
85 for (uint i = 0; i < _num_max_threads; ++i) {
86 if (_threads[i] != NULL) {
87 _threads[i]->print_on(st);
88 st->cr();
89 }
90 }
91 }
92
93 void G1ConcurrentRefineThreadControl::worker_threads_do(ThreadClosure* tc) {
94 for (uint i = 0; i < _num_max_threads; i++) {
95 if (_threads[i] != NULL) {
96 tc->do_thread(_threads[i]);
97 }
98 }
99 }
100
101 void G1ConcurrentRefineThreadControl::stop() {
178 // than green_zone buffers to be processed by update_rs.
179 step = MIN2(step, ParallelGCThreads / 2.0);
180 }
181 size_t activate_offset = static_cast<size_t>(ceil(step * (worker_i + 1)));
182 size_t deactivate_offset = static_cast<size_t>(floor(step * worker_i));
183 return Thresholds(green_zone + activate_offset,
184 green_zone + deactivate_offset);
185 }
186
187 G1ConcurrentRefine::G1ConcurrentRefine(size_t green_zone,
188 size_t yellow_zone,
189 size_t red_zone,
190 size_t min_yellow_zone_size) :
191 _thread_control(),
192 _green_zone(green_zone),
193 _yellow_zone(yellow_zone),
194 _red_zone(red_zone),
195 _min_yellow_zone_size(min_yellow_zone_size)
196 {
197 assert_zone_constraints_gyr(green_zone, yellow_zone, red_zone);
198 _thread_control.initialize(this, max_num_threads());
199 }
200
201 static size_t calc_min_yellow_zone_size() {
202 size_t step = G1ConcRefinementThresholdStep;
203 uint n_workers = G1ConcurrentRefine::max_num_threads();
204 if ((max_yellow_zone / step) < n_workers) {
205 return max_yellow_zone;
206 } else {
207 return step * n_workers;
208 }
209 }
210
211 static size_t calc_init_green_zone() {
212 size_t green = G1ConcRefinementGreenZone;
213 if (FLAG_IS_DEFAULT(G1ConcRefinementGreenZone)) {
214 green = ParallelGCThreads;
215 }
216 return MIN2(green, max_green_zone);
217 }
218
247 size_t red_zone = calc_init_red_zone(green_zone, yellow_zone);
248
249 LOG_ZONES("Initial Refinement Zones: "
250 "green: " SIZE_FORMAT ", "
251 "yellow: " SIZE_FORMAT ", "
252 "red: " SIZE_FORMAT ", "
253 "min yellow size: " SIZE_FORMAT,
254 green_zone, yellow_zone, red_zone, min_yellow_zone_size);
255
256 G1ConcurrentRefine* cr = new G1ConcurrentRefine(green_zone,
257 yellow_zone,
258 red_zone,
259 min_yellow_zone_size);
260
261 if (cr == NULL) {
262 *ecode = JNI_ENOMEM;
263 vm_shutdown_during_initialization("Could not create G1ConcurrentRefine");
264 return NULL;
265 }
266
267 *ecode = JNI_OK;
268 return cr;
269 }
270
271 void G1ConcurrentRefine::stop() {
272 _thread_control.stop();
273 }
274
275 G1ConcurrentRefine::~G1ConcurrentRefine() {
276 }
277
278 void G1ConcurrentRefine::threads_do(ThreadClosure *tc) {
279 _thread_control.worker_threads_do(tc);
280 }
281
282 uint G1ConcurrentRefine::max_num_threads() {
283 return G1ConcRefinementThreads;
284 }
285
286 void G1ConcurrentRefine::print_threads_on(outputStream* st) const {
287 _thread_control.print_on(st);
|
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/g1ConcurrentRefine.hpp"
27 #include "gc/g1/g1ConcurrentRefineThread.hpp"
28 #include "logging/log.hpp"
29 #include "runtime/java.hpp"
30 #include "runtime/thread.hpp"
31 #include "utilities/debug.hpp"
32 #include "utilities/globalDefinitions.hpp"
33 #include "utilities/pair.hpp"
34 #include <math.h>
35
36 G1ConcurrentRefineThread* G1ConcurrentRefineThreadControl::create_refinement_thread(uint worker_id, bool initializing) {
37 G1ConcurrentRefineThread* result = NULL;
38 if (initializing || !InjectGCWorkerCreationFailure) {
39 result = new G1ConcurrentRefineThread(_cr, worker_id);
40 }
41 if (result == NULL || result->osthread() == NULL) {
42 log_warning(gc)("Failed to create refinement thread %u, no more %s",
43 worker_id,
44 result == NULL ? "memory" : "OS threads");
45 }
46 return result;
47 }
48
49 G1ConcurrentRefineThreadControl::G1ConcurrentRefineThreadControl() :
50 _cr(NULL),
51 _threads(NULL),
52 _num_max_threads(0)
53 {
54 }
55
56 G1ConcurrentRefineThreadControl::~G1ConcurrentRefineThreadControl() {
57 for (uint i = 0; i < _num_max_threads; i++) {
58 G1ConcurrentRefineThread* t = _threads[i];
59 if (t != NULL) {
60 delete t;
61 }
62 }
63 FREE_C_HEAP_ARRAY(G1ConcurrentRefineThread*, _threads);
64 }
65
66 jint G1ConcurrentRefineThreadControl::initialize(G1ConcurrentRefine* cr, uint num_max_threads) {
67 assert(cr != NULL, "G1ConcurrentRefine must not be NULL");
68 _cr = cr;
69 _num_max_threads = num_max_threads;
70
71 _threads = NEW_C_HEAP_ARRAY_RETURN_NULL(G1ConcurrentRefineThread*, num_max_threads, mtGC);
72 if (_threads == NULL) {
73 vm_shutdown_during_initialization("Could not allocate thread holder array.");
74 return JNI_ENOMEM;
75 }
76
77 for (uint i = 0; i < num_max_threads; i++) {
78 if (UseDynamicNumberOfGCThreads && i != 0 /* Always start first thread. */) {
79 _threads[i] = NULL;
80 } else {
81 _threads[i] = create_refinement_thread(i, true);
82 if (_threads[i] == NULL) {
83 vm_shutdown_during_initialization("Could not allocate refinement threads.");
84 return JNI_ENOMEM;
85 }
86 }
87 }
88 return JNI_OK;
89 }
90
91 void G1ConcurrentRefineThreadControl::maybe_activate_next(uint cur_worker_id) {
92 assert(cur_worker_id < _num_max_threads,
93 "Activating another thread from %u not allowed since there can be at most %u",
94 cur_worker_id, _num_max_threads);
95 if (cur_worker_id == (_num_max_threads - 1)) {
96 // Already the last thread, there is no more thread to activate.
97 return;
98 }
99
100 uint worker_id = cur_worker_id + 1;
101 G1ConcurrentRefineThread* thread_to_activate = _threads[worker_id];
102 if (thread_to_activate == NULL) {
103 // Still need to create the thread...
104 _threads[worker_id] = create_refinement_thread(worker_id, false);
105 thread_to_activate = _threads[worker_id];
106 }
107 if (thread_to_activate != NULL) {
108 thread_to_activate->activate();
109 }
110 }
111
112 void G1ConcurrentRefineThreadControl::print_on(outputStream* st) const {
113 for (uint i = 0; i < _num_max_threads; ++i) {
114 if (_threads[i] != NULL) {
115 _threads[i]->print_on(st);
116 st->cr();
117 }
118 }
119 }
120
121 void G1ConcurrentRefineThreadControl::worker_threads_do(ThreadClosure* tc) {
122 for (uint i = 0; i < _num_max_threads; i++) {
123 if (_threads[i] != NULL) {
124 tc->do_thread(_threads[i]);
125 }
126 }
127 }
128
129 void G1ConcurrentRefineThreadControl::stop() {
206 // than green_zone buffers to be processed by update_rs.
207 step = MIN2(step, ParallelGCThreads / 2.0);
208 }
209 size_t activate_offset = static_cast<size_t>(ceil(step * (worker_i + 1)));
210 size_t deactivate_offset = static_cast<size_t>(floor(step * worker_i));
211 return Thresholds(green_zone + activate_offset,
212 green_zone + deactivate_offset);
213 }
214
215 G1ConcurrentRefine::G1ConcurrentRefine(size_t green_zone,
216 size_t yellow_zone,
217 size_t red_zone,
218 size_t min_yellow_zone_size) :
219 _thread_control(),
220 _green_zone(green_zone),
221 _yellow_zone(yellow_zone),
222 _red_zone(red_zone),
223 _min_yellow_zone_size(min_yellow_zone_size)
224 {
225 assert_zone_constraints_gyr(green_zone, yellow_zone, red_zone);
226 }
227
228 jint G1ConcurrentRefine::initialize() {
229 return _thread_control.initialize(this, max_num_threads());
230 }
231
232 static size_t calc_min_yellow_zone_size() {
233 size_t step = G1ConcRefinementThresholdStep;
234 uint n_workers = G1ConcurrentRefine::max_num_threads();
235 if ((max_yellow_zone / step) < n_workers) {
236 return max_yellow_zone;
237 } else {
238 return step * n_workers;
239 }
240 }
241
242 static size_t calc_init_green_zone() {
243 size_t green = G1ConcRefinementGreenZone;
244 if (FLAG_IS_DEFAULT(G1ConcRefinementGreenZone)) {
245 green = ParallelGCThreads;
246 }
247 return MIN2(green, max_green_zone);
248 }
249
278 size_t red_zone = calc_init_red_zone(green_zone, yellow_zone);
279
280 LOG_ZONES("Initial Refinement Zones: "
281 "green: " SIZE_FORMAT ", "
282 "yellow: " SIZE_FORMAT ", "
283 "red: " SIZE_FORMAT ", "
284 "min yellow size: " SIZE_FORMAT,
285 green_zone, yellow_zone, red_zone, min_yellow_zone_size);
286
287 G1ConcurrentRefine* cr = new G1ConcurrentRefine(green_zone,
288 yellow_zone,
289 red_zone,
290 min_yellow_zone_size);
291
292 if (cr == NULL) {
293 *ecode = JNI_ENOMEM;
294 vm_shutdown_during_initialization("Could not create G1ConcurrentRefine");
295 return NULL;
296 }
297
298 *ecode = cr->initialize();
299 return cr;
300 }
301
302 void G1ConcurrentRefine::stop() {
303 _thread_control.stop();
304 }
305
306 G1ConcurrentRefine::~G1ConcurrentRefine() {
307 }
308
309 void G1ConcurrentRefine::threads_do(ThreadClosure *tc) {
310 _thread_control.worker_threads_do(tc);
311 }
312
313 uint G1ConcurrentRefine::max_num_threads() {
314 return G1ConcRefinementThreads;
315 }
316
317 void G1ConcurrentRefine::print_threads_on(outputStream* st) const {
318 _thread_control.print_on(st);
|