Thu, 22 May 2014 15:52:41 -0400
8037816: Fix for 8036122 breaks build with Xcode5/clang
8043029: Change 8037816 breaks HS build with older GCC versions which don't support diagnostic pragmas
8043164: Format warning in traceStream.hpp
Summary: Backport of main fix + two corrections, enables clang compilation, turns on format attributes, corrects/mutes warnings
Reviewed-by: kvn, coleenp, iveresov, twisti
1 /*
2 * Copyright (c) 2002, 2014, 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 */
25 #include "precompiled.hpp"
26 #include "gc_implementation/parallelScavenge/gcTaskManager.hpp"
27 #include "gc_implementation/parallelScavenge/gcTaskThread.hpp"
28 #include "gc_implementation/shared/adaptiveSizePolicy.hpp"
29 #include "memory/allocation.hpp"
30 #include "memory/allocation.inline.hpp"
31 #include "runtime/mutex.hpp"
32 #include "runtime/mutexLocker.hpp"
34 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
36 //
37 // GCTask
38 //
40 const char* GCTask::Kind::to_string(kind value) {
41 const char* result = "unknown GCTask kind";
42 switch (value) {
43 default:
44 result = "unknown GCTask kind";
45 break;
46 case unknown_task:
47 result = "unknown task";
48 break;
49 case ordinary_task:
50 result = "ordinary task";
51 break;
52 case barrier_task:
53 result = "barrier task";
54 break;
55 case noop_task:
56 result = "noop task";
57 break;
58 case idle_task:
59 result = "idle task";
60 break;
61 }
62 return result;
63 };
65 GCTask::GCTask() :
66 _kind(Kind::ordinary_task),
67 _affinity(GCTaskManager::sentinel_worker()){
68 initialize();
69 }
71 GCTask::GCTask(Kind::kind kind) :
72 _kind(kind),
73 _affinity(GCTaskManager::sentinel_worker()) {
74 initialize();
75 }
77 GCTask::GCTask(uint affinity) :
78 _kind(Kind::ordinary_task),
79 _affinity(affinity) {
80 initialize();
81 }
83 GCTask::GCTask(Kind::kind kind, uint affinity) :
84 _kind(kind),
85 _affinity(affinity) {
86 initialize();
87 }
89 void GCTask::initialize() {
90 _older = NULL;
91 _newer = NULL;
92 }
94 void GCTask::destruct() {
95 assert(older() == NULL, "shouldn't have an older task");
96 assert(newer() == NULL, "shouldn't have a newer task");
97 // Nothing to do.
98 }
100 NOT_PRODUCT(
101 void GCTask::print(const char* message) const {
102 tty->print(INTPTR_FORMAT " <- " INTPTR_FORMAT "(%u) -> " INTPTR_FORMAT,
103 newer(), this, affinity(), older());
104 }
105 )
107 //
108 // GCTaskQueue
109 //
111 GCTaskQueue* GCTaskQueue::create() {
112 GCTaskQueue* result = new GCTaskQueue(false);
113 if (TraceGCTaskQueue) {
114 tty->print_cr("GCTaskQueue::create()"
115 " returns " INTPTR_FORMAT, result);
116 }
117 return result;
118 }
120 GCTaskQueue* GCTaskQueue::create_on_c_heap() {
121 GCTaskQueue* result = new(ResourceObj::C_HEAP, mtGC) GCTaskQueue(true);
122 if (TraceGCTaskQueue) {
123 tty->print_cr("GCTaskQueue::create_on_c_heap()"
124 " returns " INTPTR_FORMAT,
125 result);
126 }
127 return result;
128 }
130 GCTaskQueue::GCTaskQueue(bool on_c_heap) :
131 _is_c_heap_obj(on_c_heap) {
132 initialize();
133 if (TraceGCTaskQueue) {
134 tty->print_cr("[" INTPTR_FORMAT "]"
135 " GCTaskQueue::GCTaskQueue() constructor",
136 this);
137 }
138 }
140 void GCTaskQueue::destruct() {
141 // Nothing to do.
142 }
144 void GCTaskQueue::destroy(GCTaskQueue* that) {
145 if (TraceGCTaskQueue) {
146 tty->print_cr("[" INTPTR_FORMAT "]"
147 " GCTaskQueue::destroy()"
148 " is_c_heap_obj: %s",
149 that,
150 that->is_c_heap_obj() ? "true" : "false");
151 }
152 // That instance may have been allocated as a CHeapObj,
153 // in which case we have to free it explicitly.
154 if (that != NULL) {
155 that->destruct();
156 assert(that->is_empty(), "should be empty");
157 if (that->is_c_heap_obj()) {
158 FreeHeap(that);
159 }
160 }
161 }
163 void GCTaskQueue::initialize() {
164 set_insert_end(NULL);
165 set_remove_end(NULL);
166 set_length(0);
167 }
169 // Enqueue one task.
170 void GCTaskQueue::enqueue(GCTask* task) {
171 if (TraceGCTaskQueue) {
172 tty->print_cr("[" INTPTR_FORMAT "]"
173 " GCTaskQueue::enqueue(task: "
174 INTPTR_FORMAT ")",
175 this, task);
176 print("before:");
177 }
178 assert(task != NULL, "shouldn't have null task");
179 assert(task->older() == NULL, "shouldn't be on queue");
180 assert(task->newer() == NULL, "shouldn't be on queue");
181 task->set_newer(NULL);
182 task->set_older(insert_end());
183 if (is_empty()) {
184 set_remove_end(task);
185 } else {
186 insert_end()->set_newer(task);
187 }
188 set_insert_end(task);
189 increment_length();
190 verify_length();
191 if (TraceGCTaskQueue) {
192 print("after:");
193 }
194 }
196 // Enqueue a whole list of tasks. Empties the argument list.
197 void GCTaskQueue::enqueue(GCTaskQueue* list) {
198 if (TraceGCTaskQueue) {
199 tty->print_cr("[" INTPTR_FORMAT "]"
200 " GCTaskQueue::enqueue(list: "
201 INTPTR_FORMAT ")",
202 this, list);
203 print("before:");
204 list->print("list:");
205 }
206 if (list->is_empty()) {
207 // Enqueuing the empty list: nothing to do.
208 return;
209 }
210 uint list_length = list->length();
211 if (is_empty()) {
212 // Enqueuing to empty list: just acquire elements.
213 set_insert_end(list->insert_end());
214 set_remove_end(list->remove_end());
215 set_length(list_length);
216 } else {
217 // Prepend argument list to our queue.
218 list->remove_end()->set_older(insert_end());
219 insert_end()->set_newer(list->remove_end());
220 set_insert_end(list->insert_end());
221 set_length(length() + list_length);
222 // empty the argument list.
223 }
224 list->initialize();
225 if (TraceGCTaskQueue) {
226 print("after:");
227 list->print("list:");
228 }
229 verify_length();
230 }
232 // Dequeue one task.
233 GCTask* GCTaskQueue::dequeue() {
234 if (TraceGCTaskQueue) {
235 tty->print_cr("[" INTPTR_FORMAT "]"
236 " GCTaskQueue::dequeue()", this);
237 print("before:");
238 }
239 assert(!is_empty(), "shouldn't dequeue from empty list");
240 GCTask* result = remove();
241 assert(result != NULL, "shouldn't have NULL task");
242 if (TraceGCTaskQueue) {
243 tty->print_cr(" return: " INTPTR_FORMAT, result);
244 print("after:");
245 }
246 return result;
247 }
249 // Dequeue one task, preferring one with affinity.
250 GCTask* GCTaskQueue::dequeue(uint affinity) {
251 if (TraceGCTaskQueue) {
252 tty->print_cr("[" INTPTR_FORMAT "]"
253 " GCTaskQueue::dequeue(%u)", this, affinity);
254 print("before:");
255 }
256 assert(!is_empty(), "shouldn't dequeue from empty list");
257 // Look down to the next barrier for a task with this affinity.
258 GCTask* result = NULL;
259 for (GCTask* element = remove_end();
260 element != NULL;
261 element = element->newer()) {
262 if (element->is_barrier_task()) {
263 // Don't consider barrier tasks, nor past them.
264 result = NULL;
265 break;
266 }
267 if (element->affinity() == affinity) {
268 result = remove(element);
269 break;
270 }
271 }
272 // If we didn't find anything with affinity, just take the next task.
273 if (result == NULL) {
274 result = remove();
275 }
276 if (TraceGCTaskQueue) {
277 tty->print_cr(" return: " INTPTR_FORMAT, result);
278 print("after:");
279 }
280 return result;
281 }
283 GCTask* GCTaskQueue::remove() {
284 // Dequeue from remove end.
285 GCTask* result = remove_end();
286 assert(result != NULL, "shouldn't have null task");
287 assert(result->older() == NULL, "not the remove_end");
288 set_remove_end(result->newer());
289 if (remove_end() == NULL) {
290 assert(insert_end() == result, "not a singleton");
291 set_insert_end(NULL);
292 } else {
293 remove_end()->set_older(NULL);
294 }
295 result->set_newer(NULL);
296 decrement_length();
297 assert(result->newer() == NULL, "shouldn't be on queue");
298 assert(result->older() == NULL, "shouldn't be on queue");
299 verify_length();
300 return result;
301 }
303 GCTask* GCTaskQueue::remove(GCTask* task) {
304 // This is slightly more work, and has slightly fewer asserts
305 // than removing from the remove end.
306 assert(task != NULL, "shouldn't have null task");
307 GCTask* result = task;
308 if (result->newer() != NULL) {
309 result->newer()->set_older(result->older());
310 } else {
311 assert(insert_end() == result, "not youngest");
312 set_insert_end(result->older());
313 }
314 if (result->older() != NULL) {
315 result->older()->set_newer(result->newer());
316 } else {
317 assert(remove_end() == result, "not oldest");
318 set_remove_end(result->newer());
319 }
320 result->set_newer(NULL);
321 result->set_older(NULL);
322 decrement_length();
323 verify_length();
324 return result;
325 }
327 NOT_PRODUCT(
328 // Count the elements in the queue and verify the length against
329 // that count.
330 void GCTaskQueue::verify_length() const {
331 uint count = 0;
332 for (GCTask* element = insert_end();
333 element != NULL;
334 element = element->older()) {
336 count++;
337 }
338 assert(count == length(), "Length does not match queue");
339 }
341 void GCTaskQueue::print(const char* message) const {
342 tty->print_cr("[" INTPTR_FORMAT "] GCTaskQueue:"
343 " insert_end: " INTPTR_FORMAT
344 " remove_end: " INTPTR_FORMAT
345 " length: %d"
346 " %s",
347 this, insert_end(), remove_end(), length(), message);
348 uint count = 0;
349 for (GCTask* element = insert_end();
350 element != NULL;
351 element = element->older()) {
352 element->print(" ");
353 count++;
354 tty->cr();
355 }
356 tty->print("Total tasks: %d", count);
357 }
358 )
360 //
361 // SynchronizedGCTaskQueue
362 //
364 SynchronizedGCTaskQueue::SynchronizedGCTaskQueue(GCTaskQueue* queue_arg,
365 Monitor * lock_arg) :
366 _unsynchronized_queue(queue_arg),
367 _lock(lock_arg) {
368 assert(unsynchronized_queue() != NULL, "null queue");
369 assert(lock() != NULL, "null lock");
370 }
372 SynchronizedGCTaskQueue::~SynchronizedGCTaskQueue() {
373 // Nothing to do.
374 }
376 //
377 // GCTaskManager
378 //
379 GCTaskManager::GCTaskManager(uint workers) :
380 _workers(workers),
381 _active_workers(0),
382 _idle_workers(0),
383 _ndc(NULL) {
384 initialize();
385 }
387 GCTaskManager::GCTaskManager(uint workers, NotifyDoneClosure* ndc) :
388 _workers(workers),
389 _active_workers(0),
390 _idle_workers(0),
391 _ndc(ndc) {
392 initialize();
393 }
395 void GCTaskManager::initialize() {
396 if (TraceGCTaskManager) {
397 tty->print_cr("GCTaskManager::initialize: workers: %u", workers());
398 }
399 assert(workers() != 0, "no workers");
400 _monitor = new Monitor(Mutex::barrier, // rank
401 "GCTaskManager monitor", // name
402 Mutex::_allow_vm_block_flag); // allow_vm_block
403 // The queue for the GCTaskManager must be a CHeapObj.
404 GCTaskQueue* unsynchronized_queue = GCTaskQueue::create_on_c_heap();
405 _queue = SynchronizedGCTaskQueue::create(unsynchronized_queue, lock());
406 _noop_task = NoopGCTask::create_on_c_heap();
407 _idle_inactive_task = WaitForBarrierGCTask::create_on_c_heap();
408 _resource_flag = NEW_C_HEAP_ARRAY(bool, workers(), mtGC);
409 {
410 // Set up worker threads.
411 // Distribute the workers among the available processors,
412 // unless we were told not to, or if the os doesn't want to.
413 uint* processor_assignment = NEW_C_HEAP_ARRAY(uint, workers(), mtGC);
414 if (!BindGCTaskThreadsToCPUs ||
415 !os::distribute_processes(workers(), processor_assignment)) {
416 for (uint a = 0; a < workers(); a += 1) {
417 processor_assignment[a] = sentinel_worker();
418 }
419 }
420 _thread = NEW_C_HEAP_ARRAY(GCTaskThread*, workers(), mtGC);
421 for (uint t = 0; t < workers(); t += 1) {
422 set_thread(t, GCTaskThread::create(this, t, processor_assignment[t]));
423 }
424 if (TraceGCTaskThread) {
425 tty->print("GCTaskManager::initialize: distribution:");
426 for (uint t = 0; t < workers(); t += 1) {
427 tty->print(" %u", processor_assignment[t]);
428 }
429 tty->cr();
430 }
431 FREE_C_HEAP_ARRAY(uint, processor_assignment, mtGC);
432 }
433 reset_busy_workers();
434 set_unblocked();
435 for (uint w = 0; w < workers(); w += 1) {
436 set_resource_flag(w, false);
437 }
438 reset_delivered_tasks();
439 reset_completed_tasks();
440 reset_noop_tasks();
441 reset_barriers();
442 reset_emptied_queue();
443 for (uint s = 0; s < workers(); s += 1) {
444 thread(s)->start();
445 }
446 }
448 GCTaskManager::~GCTaskManager() {
449 assert(busy_workers() == 0, "still have busy workers");
450 assert(queue()->is_empty(), "still have queued work");
451 NoopGCTask::destroy(_noop_task);
452 _noop_task = NULL;
453 WaitForBarrierGCTask::destroy(_idle_inactive_task);
454 _idle_inactive_task = NULL;
455 if (_thread != NULL) {
456 for (uint i = 0; i < workers(); i += 1) {
457 GCTaskThread::destroy(thread(i));
458 set_thread(i, NULL);
459 }
460 FREE_C_HEAP_ARRAY(GCTaskThread*, _thread, mtGC);
461 _thread = NULL;
462 }
463 if (_resource_flag != NULL) {
464 FREE_C_HEAP_ARRAY(bool, _resource_flag, mtGC);
465 _resource_flag = NULL;
466 }
467 if (queue() != NULL) {
468 GCTaskQueue* unsynchronized_queue = queue()->unsynchronized_queue();
469 GCTaskQueue::destroy(unsynchronized_queue);
470 SynchronizedGCTaskQueue::destroy(queue());
471 _queue = NULL;
472 }
473 if (monitor() != NULL) {
474 delete monitor();
475 _monitor = NULL;
476 }
477 }
479 void GCTaskManager::set_active_gang() {
480 _active_workers =
481 AdaptiveSizePolicy::calc_active_workers(workers(),
482 active_workers(),
483 Threads::number_of_non_daemon_threads());
485 assert(!all_workers_active() || active_workers() == ParallelGCThreads,
486 err_msg("all_workers_active() is incorrect: "
487 "active %d ParallelGCThreads %d", active_workers(),
488 ParallelGCThreads));
489 if (TraceDynamicGCThreads) {
490 gclog_or_tty->print_cr("GCTaskManager::set_active_gang(): "
491 "all_workers_active() %d workers %d "
492 "active %d ParallelGCThreads %d ",
493 all_workers_active(), workers(), active_workers(),
494 ParallelGCThreads);
495 }
496 }
498 // Create IdleGCTasks for inactive workers.
499 // Creates tasks in a ResourceArea and assumes
500 // an appropriate ResourceMark.
501 void GCTaskManager::task_idle_workers() {
502 {
503 int more_inactive_workers = 0;
504 {
505 // Stop any idle tasks from exiting their IdleGCTask's
506 // and get the count for additional IdleGCTask's under
507 // the GCTaskManager's monitor so that the "more_inactive_workers"
508 // count is correct.
509 MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
510 _idle_inactive_task->set_should_wait(true);
511 // active_workers are a number being requested. idle_workers
512 // are the number currently idle. If all the workers are being
513 // requested to be active but some are already idle, reduce
514 // the number of active_workers to be consistent with the
515 // number of idle_workers. The idle_workers are stuck in
516 // idle tasks and will no longer be release (since a new GC
517 // is starting). Try later to release enough idle_workers
518 // to allow the desired number of active_workers.
519 more_inactive_workers =
520 workers() - active_workers() - idle_workers();
521 if (more_inactive_workers < 0) {
522 int reduced_active_workers = active_workers() + more_inactive_workers;
523 set_active_workers(reduced_active_workers);
524 more_inactive_workers = 0;
525 }
526 if (TraceDynamicGCThreads) {
527 gclog_or_tty->print_cr("JT: %d workers %d active %d "
528 "idle %d more %d",
529 Threads::number_of_non_daemon_threads(),
530 workers(),
531 active_workers(),
532 idle_workers(),
533 more_inactive_workers);
534 }
535 }
536 GCTaskQueue* q = GCTaskQueue::create();
537 for(uint i = 0; i < (uint) more_inactive_workers; i++) {
538 q->enqueue(IdleGCTask::create_on_c_heap());
539 increment_idle_workers();
540 }
541 assert(workers() == active_workers() + idle_workers(),
542 "total workers should equal active + inactive");
543 add_list(q);
544 // GCTaskQueue* q was created in a ResourceArea so a
545 // destroy() call is not needed.
546 }
547 }
549 void GCTaskManager::release_idle_workers() {
550 {
551 MutexLockerEx ml(monitor(),
552 Mutex::_no_safepoint_check_flag);
553 _idle_inactive_task->set_should_wait(false);
554 monitor()->notify_all();
555 // Release monitor
556 }
557 }
559 void GCTaskManager::print_task_time_stamps() {
560 for(uint i=0; i<ParallelGCThreads; i++) {
561 GCTaskThread* t = thread(i);
562 t->print_task_time_stamps();
563 }
564 }
566 void GCTaskManager::print_threads_on(outputStream* st) {
567 uint num_thr = workers();
568 for (uint i = 0; i < num_thr; i++) {
569 thread(i)->print_on(st);
570 st->cr();
571 }
572 }
574 void GCTaskManager::threads_do(ThreadClosure* tc) {
575 assert(tc != NULL, "Null ThreadClosure");
576 uint num_thr = workers();
577 for (uint i = 0; i < num_thr; i++) {
578 tc->do_thread(thread(i));
579 }
580 }
582 GCTaskThread* GCTaskManager::thread(uint which) {
583 assert(which < workers(), "index out of bounds");
584 assert(_thread[which] != NULL, "shouldn't have null thread");
585 return _thread[which];
586 }
588 void GCTaskManager::set_thread(uint which, GCTaskThread* value) {
589 assert(which < workers(), "index out of bounds");
590 assert(value != NULL, "shouldn't have null thread");
591 _thread[which] = value;
592 }
594 void GCTaskManager::add_task(GCTask* task) {
595 assert(task != NULL, "shouldn't have null task");
596 MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
597 if (TraceGCTaskManager) {
598 tty->print_cr("GCTaskManager::add_task(" INTPTR_FORMAT " [%s])",
599 task, GCTask::Kind::to_string(task->kind()));
600 }
601 queue()->enqueue(task);
602 // Notify with the lock held to avoid missed notifies.
603 if (TraceGCTaskManager) {
604 tty->print_cr(" GCTaskManager::add_task (%s)->notify_all",
605 monitor()->name());
606 }
607 (void) monitor()->notify_all();
608 // Release monitor().
609 }
611 void GCTaskManager::add_list(GCTaskQueue* list) {
612 assert(list != NULL, "shouldn't have null task");
613 MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
614 if (TraceGCTaskManager) {
615 tty->print_cr("GCTaskManager::add_list(%u)", list->length());
616 }
617 queue()->enqueue(list);
618 // Notify with the lock held to avoid missed notifies.
619 if (TraceGCTaskManager) {
620 tty->print_cr(" GCTaskManager::add_list (%s)->notify_all",
621 monitor()->name());
622 }
623 (void) monitor()->notify_all();
624 // Release monitor().
625 }
627 // GC workers wait in get_task() for new work to be added
628 // to the GCTaskManager's queue. When new work is added,
629 // a notify is sent to the waiting GC workers which then
630 // compete to get tasks. If a GC worker wakes up and there
631 // is no work on the queue, it is given a noop_task to execute
632 // and then loops to find more work.
634 GCTask* GCTaskManager::get_task(uint which) {
635 GCTask* result = NULL;
636 // Grab the queue lock.
637 MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
638 // Wait while the queue is block or
639 // there is nothing to do, except maybe release resources.
640 while (is_blocked() ||
641 (queue()->is_empty() && !should_release_resources(which))) {
642 if (TraceGCTaskManager) {
643 tty->print_cr("GCTaskManager::get_task(%u)"
644 " blocked: %s"
645 " empty: %s"
646 " release: %s",
647 which,
648 is_blocked() ? "true" : "false",
649 queue()->is_empty() ? "true" : "false",
650 should_release_resources(which) ? "true" : "false");
651 tty->print_cr(" => (%s)->wait()",
652 monitor()->name());
653 }
654 monitor()->wait(Mutex::_no_safepoint_check_flag, 0);
655 }
656 // We've reacquired the queue lock here.
657 // Figure out which condition caused us to exit the loop above.
658 if (!queue()->is_empty()) {
659 if (UseGCTaskAffinity) {
660 result = queue()->dequeue(which);
661 } else {
662 result = queue()->dequeue();
663 }
664 if (result->is_barrier_task()) {
665 assert(which != sentinel_worker(),
666 "blocker shouldn't be bogus");
667 set_blocking_worker(which);
668 }
669 } else {
670 // The queue is empty, but we were woken up.
671 // Just hand back a Noop task,
672 // in case someone wanted us to release resources, or whatever.
673 result = noop_task();
674 increment_noop_tasks();
675 }
676 assert(result != NULL, "shouldn't have null task");
677 if (TraceGCTaskManager) {
678 tty->print_cr("GCTaskManager::get_task(%u) => " INTPTR_FORMAT " [%s]",
679 which, result, GCTask::Kind::to_string(result->kind()));
680 tty->print_cr(" %s", result->name());
681 }
682 if (!result->is_idle_task()) {
683 increment_busy_workers();
684 increment_delivered_tasks();
685 }
686 return result;
687 // Release monitor().
688 }
690 void GCTaskManager::note_completion(uint which) {
691 MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
692 if (TraceGCTaskManager) {
693 tty->print_cr("GCTaskManager::note_completion(%u)", which);
694 }
695 // If we are blocked, check if the completing thread is the blocker.
696 if (blocking_worker() == which) {
697 assert(blocking_worker() != sentinel_worker(),
698 "blocker shouldn't be bogus");
699 increment_barriers();
700 set_unblocked();
701 }
702 increment_completed_tasks();
703 uint active = decrement_busy_workers();
704 if ((active == 0) && (queue()->is_empty())) {
705 increment_emptied_queue();
706 if (TraceGCTaskManager) {
707 tty->print_cr(" GCTaskManager::note_completion(%u) done", which);
708 }
709 // Notify client that we are done.
710 NotifyDoneClosure* ndc = notify_done_closure();
711 if (ndc != NULL) {
712 ndc->notify(this);
713 }
714 }
715 if (TraceGCTaskManager) {
716 tty->print_cr(" GCTaskManager::note_completion(%u) (%s)->notify_all",
717 which, monitor()->name());
718 tty->print_cr(" "
719 " blocked: %s"
720 " empty: %s"
721 " release: %s",
722 is_blocked() ? "true" : "false",
723 queue()->is_empty() ? "true" : "false",
724 should_release_resources(which) ? "true" : "false");
725 tty->print_cr(" "
726 " delivered: %u"
727 " completed: %u"
728 " barriers: %u"
729 " emptied: %u",
730 delivered_tasks(),
731 completed_tasks(),
732 barriers(),
733 emptied_queue());
734 }
735 // Tell everyone that a task has completed.
736 (void) monitor()->notify_all();
737 // Release monitor().
738 }
740 uint GCTaskManager::increment_busy_workers() {
741 assert(queue()->own_lock(), "don't own the lock");
742 _busy_workers += 1;
743 return _busy_workers;
744 }
746 uint GCTaskManager::decrement_busy_workers() {
747 assert(queue()->own_lock(), "don't own the lock");
748 assert(_busy_workers > 0, "About to make a mistake");
749 _busy_workers -= 1;
750 return _busy_workers;
751 }
753 void GCTaskManager::release_all_resources() {
754 // If you want this to be done atomically, do it in a BarrierGCTask.
755 for (uint i = 0; i < workers(); i += 1) {
756 set_resource_flag(i, true);
757 }
758 }
760 bool GCTaskManager::should_release_resources(uint which) {
761 // This can be done without a lock because each thread reads one element.
762 return resource_flag(which);
763 }
765 void GCTaskManager::note_release(uint which) {
766 // This can be done without a lock because each thread writes one element.
767 set_resource_flag(which, false);
768 }
770 // "list" contains tasks that are ready to execute. Those
771 // tasks are added to the GCTaskManager's queue of tasks and
772 // then the GC workers are notified that there is new work to
773 // do.
774 //
775 // Typically different types of tasks can be added to the "list".
776 // For example in PSScavenge OldToYoungRootsTask, SerialOldToYoungRootsTask,
777 // ScavengeRootsTask, and StealTask tasks are all added to the list
778 // and then the GC workers are notified of new work. The tasks are
779 // handed out in the order in which they are added to the list
780 // (although execution is not necessarily in that order). As long
781 // as any tasks are running the GCTaskManager will wait for execution
782 // to complete. GC workers that execute a stealing task remain in
783 // the stealing task until all stealing tasks have completed. The load
784 // balancing afforded by the stealing tasks work best if the stealing
785 // tasks are added last to the list.
787 void GCTaskManager::execute_and_wait(GCTaskQueue* list) {
788 WaitForBarrierGCTask* fin = WaitForBarrierGCTask::create();
789 list->enqueue(fin);
790 // The barrier task will be read by one of the GC
791 // workers once it is added to the list of tasks.
792 // Be sure that is globally visible before the
793 // GC worker reads it (which is after the task is added
794 // to the list of tasks below).
795 OrderAccess::storestore();
796 add_list(list);
797 fin->wait_for(true /* reset */);
798 // We have to release the barrier tasks!
799 WaitForBarrierGCTask::destroy(fin);
800 }
802 bool GCTaskManager::resource_flag(uint which) {
803 assert(which < workers(), "index out of bounds");
804 return _resource_flag[which];
805 }
807 void GCTaskManager::set_resource_flag(uint which, bool value) {
808 assert(which < workers(), "index out of bounds");
809 _resource_flag[which] = value;
810 }
812 //
813 // NoopGCTask
814 //
816 NoopGCTask* NoopGCTask::create() {
817 NoopGCTask* result = new NoopGCTask(false);
818 return result;
819 }
821 NoopGCTask* NoopGCTask::create_on_c_heap() {
822 NoopGCTask* result = new(ResourceObj::C_HEAP, mtGC) NoopGCTask(true);
823 return result;
824 }
826 void NoopGCTask::destroy(NoopGCTask* that) {
827 if (that != NULL) {
828 that->destruct();
829 if (that->is_c_heap_obj()) {
830 FreeHeap(that);
831 }
832 }
833 }
835 void NoopGCTask::destruct() {
836 // This has to know it's superclass structure, just like the constructor.
837 this->GCTask::destruct();
838 // Nothing else to do.
839 }
841 //
842 // IdleGCTask
843 //
845 IdleGCTask* IdleGCTask::create() {
846 IdleGCTask* result = new IdleGCTask(false);
847 assert(UseDynamicNumberOfGCThreads,
848 "Should only be used with dynamic GC thread");
849 return result;
850 }
852 IdleGCTask* IdleGCTask::create_on_c_heap() {
853 IdleGCTask* result = new(ResourceObj::C_HEAP, mtGC) IdleGCTask(true);
854 assert(UseDynamicNumberOfGCThreads,
855 "Should only be used with dynamic GC thread");
856 return result;
857 }
859 void IdleGCTask::do_it(GCTaskManager* manager, uint which) {
860 WaitForBarrierGCTask* wait_for_task = manager->idle_inactive_task();
861 if (TraceGCTaskManager) {
862 tty->print_cr("[" INTPTR_FORMAT "]"
863 " IdleGCTask:::do_it()"
864 " should_wait: %s",
865 this, wait_for_task->should_wait() ? "true" : "false");
866 }
867 MutexLockerEx ml(manager->monitor(), Mutex::_no_safepoint_check_flag);
868 if (TraceDynamicGCThreads) {
869 gclog_or_tty->print_cr("--- idle %d", which);
870 }
871 // Increment has to be done when the idle tasks are created.
872 // manager->increment_idle_workers();
873 manager->monitor()->notify_all();
874 while (wait_for_task->should_wait()) {
875 if (TraceGCTaskManager) {
876 tty->print_cr("[" INTPTR_FORMAT "]"
877 " IdleGCTask::do_it()"
878 " [" INTPTR_FORMAT "] (%s)->wait()",
879 this, manager->monitor(), manager->monitor()->name());
880 }
881 manager->monitor()->wait(Mutex::_no_safepoint_check_flag, 0);
882 }
883 manager->decrement_idle_workers();
884 if (TraceDynamicGCThreads) {
885 gclog_or_tty->print_cr("--- release %d", which);
886 }
887 if (TraceGCTaskManager) {
888 tty->print_cr("[" INTPTR_FORMAT "]"
889 " IdleGCTask::do_it() returns"
890 " should_wait: %s",
891 this, wait_for_task->should_wait() ? "true" : "false");
892 }
893 // Release monitor().
894 }
896 void IdleGCTask::destroy(IdleGCTask* that) {
897 if (that != NULL) {
898 that->destruct();
899 if (that->is_c_heap_obj()) {
900 FreeHeap(that);
901 }
902 }
903 }
905 void IdleGCTask::destruct() {
906 // This has to know it's superclass structure, just like the constructor.
907 this->GCTask::destruct();
908 // Nothing else to do.
909 }
911 //
912 // BarrierGCTask
913 //
915 void BarrierGCTask::do_it(GCTaskManager* manager, uint which) {
916 // Wait for this to be the only busy worker.
917 // ??? I thought of having a StackObj class
918 // whose constructor would grab the lock and come to the barrier,
919 // and whose destructor would release the lock,
920 // but that seems like too much mechanism for two lines of code.
921 MutexLockerEx ml(manager->lock(), Mutex::_no_safepoint_check_flag);
922 do_it_internal(manager, which);
923 // Release manager->lock().
924 }
926 void BarrierGCTask::do_it_internal(GCTaskManager* manager, uint which) {
927 // Wait for this to be the only busy worker.
928 assert(manager->monitor()->owned_by_self(), "don't own the lock");
929 assert(manager->is_blocked(), "manager isn't blocked");
930 while (manager->busy_workers() > 1) {
931 if (TraceGCTaskManager) {
932 tty->print_cr("BarrierGCTask::do_it(%u) waiting on %u workers",
933 which, manager->busy_workers());
934 }
935 manager->monitor()->wait(Mutex::_no_safepoint_check_flag, 0);
936 }
937 }
939 void BarrierGCTask::destruct() {
940 this->GCTask::destruct();
941 // Nothing else to do.
942 }
944 //
945 // ReleasingBarrierGCTask
946 //
948 void ReleasingBarrierGCTask::do_it(GCTaskManager* manager, uint which) {
949 MutexLockerEx ml(manager->lock(), Mutex::_no_safepoint_check_flag);
950 do_it_internal(manager, which);
951 manager->release_all_resources();
952 // Release manager->lock().
953 }
955 void ReleasingBarrierGCTask::destruct() {
956 this->BarrierGCTask::destruct();
957 // Nothing else to do.
958 }
960 //
961 // NotifyingBarrierGCTask
962 //
964 void NotifyingBarrierGCTask::do_it(GCTaskManager* manager, uint which) {
965 MutexLockerEx ml(manager->lock(), Mutex::_no_safepoint_check_flag);
966 do_it_internal(manager, which);
967 NotifyDoneClosure* ndc = notify_done_closure();
968 if (ndc != NULL) {
969 ndc->notify(manager);
970 }
971 // Release manager->lock().
972 }
974 void NotifyingBarrierGCTask::destruct() {
975 this->BarrierGCTask::destruct();
976 // Nothing else to do.
977 }
979 //
980 // WaitForBarrierGCTask
981 //
982 WaitForBarrierGCTask* WaitForBarrierGCTask::create() {
983 WaitForBarrierGCTask* result = new WaitForBarrierGCTask(false);
984 return result;
985 }
987 WaitForBarrierGCTask* WaitForBarrierGCTask::create_on_c_heap() {
988 WaitForBarrierGCTask* result =
989 new (ResourceObj::C_HEAP, mtGC) WaitForBarrierGCTask(true);
990 return result;
991 }
993 WaitForBarrierGCTask::WaitForBarrierGCTask(bool on_c_heap) :
994 _is_c_heap_obj(on_c_heap) {
995 _monitor = MonitorSupply::reserve();
996 set_should_wait(true);
997 if (TraceGCTaskManager) {
998 tty->print_cr("[" INTPTR_FORMAT "]"
999 " WaitForBarrierGCTask::WaitForBarrierGCTask()"
1000 " monitor: " INTPTR_FORMAT,
1001 this, monitor());
1002 }
1003 }
1005 void WaitForBarrierGCTask::destroy(WaitForBarrierGCTask* that) {
1006 if (that != NULL) {
1007 if (TraceGCTaskManager) {
1008 tty->print_cr("[" INTPTR_FORMAT "]"
1009 " WaitForBarrierGCTask::destroy()"
1010 " is_c_heap_obj: %s"
1011 " monitor: " INTPTR_FORMAT,
1012 that,
1013 that->is_c_heap_obj() ? "true" : "false",
1014 that->monitor());
1015 }
1016 that->destruct();
1017 if (that->is_c_heap_obj()) {
1018 FreeHeap(that);
1019 }
1020 }
1021 }
1023 void WaitForBarrierGCTask::destruct() {
1024 assert(monitor() != NULL, "monitor should not be NULL");
1025 if (TraceGCTaskManager) {
1026 tty->print_cr("[" INTPTR_FORMAT "]"
1027 " WaitForBarrierGCTask::destruct()"
1028 " monitor: " INTPTR_FORMAT,
1029 this, monitor());
1030 }
1031 this->BarrierGCTask::destruct();
1032 // Clean up that should be in the destructor,
1033 // except that ResourceMarks don't call destructors.
1034 if (monitor() != NULL) {
1035 MonitorSupply::release(monitor());
1036 }
1037 _monitor = (Monitor*) 0xDEAD000F;
1038 }
1040 void WaitForBarrierGCTask::do_it(GCTaskManager* manager, uint which) {
1041 if (TraceGCTaskManager) {
1042 tty->print_cr("[" INTPTR_FORMAT "]"
1043 " WaitForBarrierGCTask::do_it() waiting for idle"
1044 " monitor: " INTPTR_FORMAT,
1045 this, monitor());
1046 }
1047 {
1048 // First, wait for the barrier to arrive.
1049 MutexLockerEx ml(manager->lock(), Mutex::_no_safepoint_check_flag);
1050 do_it_internal(manager, which);
1051 // Release manager->lock().
1052 }
1053 {
1054 // Then notify the waiter.
1055 MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
1056 set_should_wait(false);
1057 // Waiter doesn't miss the notify in the wait_for method
1058 // since it checks the flag after grabbing the monitor.
1059 if (TraceGCTaskManager) {
1060 tty->print_cr("[" INTPTR_FORMAT "]"
1061 " WaitForBarrierGCTask::do_it()"
1062 " [" INTPTR_FORMAT "] (%s)->notify_all()",
1063 this, monitor(), monitor()->name());
1064 }
1065 monitor()->notify_all();
1066 // Release monitor().
1067 }
1068 }
1070 void WaitForBarrierGCTask::wait_for(bool reset) {
1071 if (TraceGCTaskManager) {
1072 tty->print_cr("[" INTPTR_FORMAT "]"
1073 " WaitForBarrierGCTask::wait_for()"
1074 " should_wait: %s",
1075 this, should_wait() ? "true" : "false");
1076 }
1077 {
1078 // Grab the lock and check again.
1079 MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
1080 while (should_wait()) {
1081 if (TraceGCTaskManager) {
1082 tty->print_cr("[" INTPTR_FORMAT "]"
1083 " WaitForBarrierGCTask::wait_for()"
1084 " [" INTPTR_FORMAT "] (%s)->wait()",
1085 this, monitor(), monitor()->name());
1086 }
1087 monitor()->wait(Mutex::_no_safepoint_check_flag, 0);
1088 }
1089 // Reset the flag in case someone reuses this task.
1090 if (reset) {
1091 set_should_wait(true);
1092 }
1093 if (TraceGCTaskManager) {
1094 tty->print_cr("[" INTPTR_FORMAT "]"
1095 " WaitForBarrierGCTask::wait_for() returns"
1096 " should_wait: %s",
1097 this, should_wait() ? "true" : "false");
1098 }
1099 // Release monitor().
1100 }
1101 }
1103 Mutex* MonitorSupply::_lock = NULL;
1104 GrowableArray<Monitor*>* MonitorSupply::_freelist = NULL;
1106 Monitor* MonitorSupply::reserve() {
1107 Monitor* result = NULL;
1108 // Lazy initialization: possible race.
1109 if (lock() == NULL) {
1110 _lock = new Mutex(Mutex::barrier, // rank
1111 "MonitorSupply mutex", // name
1112 Mutex::_allow_vm_block_flag); // allow_vm_block
1113 }
1114 {
1115 MutexLockerEx ml(lock());
1116 // Lazy initialization.
1117 if (freelist() == NULL) {
1118 _freelist =
1119 new(ResourceObj::C_HEAP, mtGC) GrowableArray<Monitor*>(ParallelGCThreads,
1120 true);
1121 }
1122 if (! freelist()->is_empty()) {
1123 result = freelist()->pop();
1124 } else {
1125 result = new Monitor(Mutex::barrier, // rank
1126 "MonitorSupply monitor", // name
1127 Mutex::_allow_vm_block_flag); // allow_vm_block
1128 }
1129 guarantee(result != NULL, "shouldn't return NULL");
1130 assert(!result->is_locked(), "shouldn't be locked");
1131 // release lock().
1132 }
1133 return result;
1134 }
1136 void MonitorSupply::release(Monitor* instance) {
1137 assert(instance != NULL, "shouldn't release NULL");
1138 assert(!instance->is_locked(), "shouldn't be locked");
1139 {
1140 MutexLockerEx ml(lock());
1141 freelist()->push(instance);
1142 // release lock().
1143 }
1144 }