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