1 /*
   2  * Copyright (c) 2002, 2010, 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  */
  24 
  25 #include "precompiled.hpp"
  26 #include "gc_implementation/parallelScavenge/gcTaskManager.hpp"
  27 #include "gc_implementation/parallelScavenge/gcTaskThread.hpp"
  28 #include "memory/allocation.hpp"
  29 #include "memory/allocation.inline.hpp"
  30 #include "runtime/mutex.hpp"
  31 #include "runtime/mutexLocker.hpp"
  32 
  33 //
  34 // GCTask
  35 //
  36 
  37 const char* GCTask::Kind::to_string(kind value) {
  38   const char* result = "unknown GCTask kind";
  39   switch (value) {
  40   default:
  41     result = "unknown GCTask kind";
  42     break;
  43   case unknown_task:
  44     result = "unknown task";
  45     break;
  46   case ordinary_task:
  47     result = "ordinary task";
  48     break;
  49   case barrier_task:
  50     result = "barrier task";
  51     break;
  52   case noop_task:
  53     result = "noop task";
  54     break;
  55   }
  56   return result;
  57 };
  58 
  59 GCTask::GCTask() :
  60   _kind(Kind::ordinary_task),
  61   _affinity(GCTaskManager::sentinel_worker()){
  62   initialize();
  63 }
  64 
  65 GCTask::GCTask(Kind::kind kind) :
  66   _kind(kind),
  67   _affinity(GCTaskManager::sentinel_worker()) {
  68   initialize();
  69 }
  70 
  71 GCTask::GCTask(uint affinity) :
  72   _kind(Kind::ordinary_task),
  73   _affinity(affinity) {
  74   initialize();
  75 }
  76 
  77 GCTask::GCTask(Kind::kind kind, uint affinity) :
  78   _kind(kind),
  79   _affinity(affinity) {
  80   initialize();
  81 }
  82 
  83 void GCTask::initialize() {
  84   _older = NULL;
  85   _newer = NULL;
  86 }
  87 
  88 void GCTask::destruct() {
  89   assert(older() == NULL, "shouldn't have an older task");
  90   assert(newer() == NULL, "shouldn't have a newer task");
  91   // Nothing to do.
  92 }
  93 
  94 NOT_PRODUCT(
  95 void GCTask::print(const char* message) const {
  96   tty->print(INTPTR_FORMAT " <- " INTPTR_FORMAT "(%u) -> " INTPTR_FORMAT,
  97              newer(), this, affinity(), older());
  98 }
  99 )
 100 
 101 //
 102 // GCTaskQueue
 103 //
 104 
 105 GCTaskQueue* GCTaskQueue::create() {
 106   GCTaskQueue* result = new GCTaskQueue(false);
 107   if (TraceGCTaskQueue) {
 108     tty->print_cr("GCTaskQueue::create()"
 109                   " returns " INTPTR_FORMAT, result);
 110   }
 111   return result;
 112 }
 113 
 114 GCTaskQueue* GCTaskQueue::create_on_c_heap() {
 115   GCTaskQueue* result = new(ResourceObj::C_HEAP) GCTaskQueue(true);
 116   if (TraceGCTaskQueue) {
 117     tty->print_cr("GCTaskQueue::create_on_c_heap()"
 118                   " returns " INTPTR_FORMAT,
 119                   result);
 120   }
 121   return result;
 122 }
 123 
 124 GCTaskQueue::GCTaskQueue(bool on_c_heap) :
 125   _is_c_heap_obj(on_c_heap) {
 126   initialize();
 127   if (TraceGCTaskQueue) {
 128     tty->print_cr("[" INTPTR_FORMAT "]"
 129                   " GCTaskQueue::GCTaskQueue() constructor",
 130                   this);
 131   }
 132 }
 133 
 134 void GCTaskQueue::destruct() {
 135   // Nothing to do.
 136 }
 137 
 138 void GCTaskQueue::destroy(GCTaskQueue* that) {
 139   if (TraceGCTaskQueue) {
 140     tty->print_cr("[" INTPTR_FORMAT "]"
 141                   " GCTaskQueue::destroy()"
 142                   "  is_c_heap_obj:  %s",
 143                   that,
 144                   that->is_c_heap_obj() ? "true" : "false");
 145   }
 146   // That instance may have been allocated as a CHeapObj,
 147   // in which case we have to free it explicitly.
 148   if (that != NULL) {
 149     that->destruct();
 150     assert(that->is_empty(), "should be empty");
 151     if (that->is_c_heap_obj()) {
 152       FreeHeap(that);
 153     }
 154   }
 155 }
 156 
 157 void GCTaskQueue::initialize() {
 158   set_insert_end(NULL);
 159   set_remove_end(NULL);
 160   set_length(0);
 161 }
 162 
 163 // Enqueue one task.
 164 void GCTaskQueue::enqueue(GCTask* task) {
 165   if (TraceGCTaskQueue) {
 166     tty->print_cr("[" INTPTR_FORMAT "]"
 167                   " GCTaskQueue::enqueue(task: "
 168                   INTPTR_FORMAT ")",
 169                   this, task);
 170     print("before:");
 171   }
 172   assert(task != NULL, "shouldn't have null task");
 173   assert(task->older() == NULL, "shouldn't be on queue");
 174   assert(task->newer() == NULL, "shouldn't be on queue");
 175   task->set_newer(NULL);
 176   task->set_older(insert_end());
 177   if (is_empty()) {
 178     set_remove_end(task);
 179   } else {
 180     insert_end()->set_newer(task);
 181   }
 182   set_insert_end(task);
 183   increment_length();
 184   if (TraceGCTaskQueue) {
 185     print("after:");
 186   }
 187 }
 188 
 189 // Enqueue a whole list of tasks.  Empties the argument list.
 190 void GCTaskQueue::enqueue(GCTaskQueue* list) {
 191   if (TraceGCTaskQueue) {
 192     tty->print_cr("[" INTPTR_FORMAT "]"
 193                   " GCTaskQueue::enqueue(list: "
 194                   INTPTR_FORMAT ")",
 195                   this);
 196     print("before:");
 197     list->print("list:");
 198   }
 199   if (list->is_empty()) {
 200     // Enqueuing the empty list: nothing to do.
 201     return;
 202   }
 203   uint list_length = list->length();
 204   if (is_empty()) {
 205     // Enqueuing to empty list: just acquire elements.
 206     set_insert_end(list->insert_end());
 207     set_remove_end(list->remove_end());
 208     set_length(list_length);
 209   } else {
 210     // Prepend argument list to our queue.
 211     list->remove_end()->set_older(insert_end());
 212     insert_end()->set_newer(list->remove_end());
 213     set_insert_end(list->insert_end());
 214     // empty the argument list.
 215   }
 216   set_length(length() + list_length);
 217   list->initialize();
 218   if (TraceGCTaskQueue) {
 219     print("after:");
 220     list->print("list:");
 221   }
 222 }
 223 
 224 // Dequeue one task.
 225 GCTask* GCTaskQueue::dequeue() {
 226   if (TraceGCTaskQueue) {
 227     tty->print_cr("[" INTPTR_FORMAT "]"
 228                   " GCTaskQueue::dequeue()", this);
 229     print("before:");
 230   }
 231   assert(!is_empty(), "shouldn't dequeue from empty list");
 232   GCTask* result = remove();
 233   assert(result != NULL, "shouldn't have NULL task");
 234   if (TraceGCTaskQueue) {
 235     tty->print_cr("    return: " INTPTR_FORMAT, result);
 236     print("after:");
 237   }
 238   return result;
 239 }
 240 
 241 // Dequeue one task, preferring one with affinity.
 242 GCTask* GCTaskQueue::dequeue(uint affinity) {
 243   if (TraceGCTaskQueue) {
 244     tty->print_cr("[" INTPTR_FORMAT "]"
 245                   " GCTaskQueue::dequeue(%u)", this, affinity);
 246     print("before:");
 247   }
 248   assert(!is_empty(), "shouldn't dequeue from empty list");
 249   // Look down to the next barrier for a task with this affinity.
 250   GCTask* result = NULL;
 251   for (GCTask* element = remove_end();
 252        element != NULL;
 253        element = element->newer()) {
 254     if (element->is_barrier_task()) {
 255       // Don't consider barrier tasks, nor past them.
 256       result = NULL;
 257       break;
 258     }
 259     if (element->affinity() == affinity) {
 260       result = remove(element);
 261       break;
 262     }
 263   }
 264   // If we didn't find anything with affinity, just take the next task.
 265   if (result == NULL) {
 266     result = remove();
 267   }
 268   if (TraceGCTaskQueue) {
 269     tty->print_cr("    return: " INTPTR_FORMAT, result);
 270     print("after:");
 271   }
 272   return result;
 273 }
 274 
 275 GCTask* GCTaskQueue::remove() {
 276   // Dequeue from remove end.
 277   GCTask* result = remove_end();
 278   assert(result != NULL, "shouldn't have null task");
 279   assert(result->older() == NULL, "not the remove_end");
 280   set_remove_end(result->newer());
 281   if (remove_end() == NULL) {
 282     assert(insert_end() == result, "not a singleton");
 283     set_insert_end(NULL);
 284   } else {
 285     remove_end()->set_older(NULL);
 286   }
 287   result->set_newer(NULL);
 288   decrement_length();
 289   assert(result->newer() == NULL, "shouldn't be on queue");
 290   assert(result->older() == NULL, "shouldn't be on queue");
 291   return result;
 292 }
 293 
 294 GCTask* GCTaskQueue::remove(GCTask* task) {
 295   // This is slightly more work, and has slightly fewer asserts
 296   // than removing from the remove end.
 297   assert(task != NULL, "shouldn't have null task");
 298   GCTask* result = task;
 299   if (result->newer() != NULL) {
 300     result->newer()->set_older(result->older());
 301   } else {
 302     assert(insert_end() == result, "not youngest");
 303     set_insert_end(result->older());
 304   }
 305   if (result->older() != NULL) {
 306     result->older()->set_newer(result->newer());
 307   } else {
 308     assert(remove_end() == result, "not oldest");
 309     set_remove_end(result->newer());
 310   }
 311   result->set_newer(NULL);
 312   result->set_older(NULL);
 313   decrement_length();
 314   return result;
 315 }
 316 
 317 NOT_PRODUCT(
 318 void GCTaskQueue::print(const char* message) const {
 319   tty->print_cr("[" INTPTR_FORMAT "] GCTaskQueue:"
 320                 "  insert_end: " INTPTR_FORMAT
 321                 "  remove_end: " INTPTR_FORMAT
 322                 "  %s",
 323                 this, insert_end(), remove_end(), message);
 324   for (GCTask* element = insert_end();
 325        element != NULL;
 326        element = element->older()) {
 327     element->print("    ");
 328     tty->cr();
 329   }
 330 }
 331 )
 332 
 333 //
 334 // SynchronizedGCTaskQueue
 335 //
 336 
 337 SynchronizedGCTaskQueue::SynchronizedGCTaskQueue(GCTaskQueue* queue_arg,
 338                                                  Monitor *       lock_arg) :
 339   _unsynchronized_queue(queue_arg),
 340   _lock(lock_arg) {
 341   assert(unsynchronized_queue() != NULL, "null queue");
 342   assert(lock() != NULL, "null lock");
 343 }
 344 
 345 SynchronizedGCTaskQueue::~SynchronizedGCTaskQueue() {
 346   // Nothing to do.
 347 }
 348 
 349 //
 350 // GCTaskManager
 351 //
 352 GCTaskManager::GCTaskManager(uint workers) :
 353   _workers(workers),
 354   _ndc(NULL) {
 355   initialize();
 356 }
 357 
 358 GCTaskManager::GCTaskManager(uint workers, NotifyDoneClosure* ndc) :
 359   _workers(workers),
 360   _ndc(ndc) {
 361   initialize();
 362 }
 363 
 364 void GCTaskManager::initialize() {
 365   if (TraceGCTaskManager) {
 366     tty->print_cr("GCTaskManager::initialize: workers: %u", workers());
 367   }
 368   assert(workers() != 0, "no workers");
 369   _monitor = new Monitor(Mutex::barrier,                // rank
 370                          "GCTaskManager monitor",       // name
 371                          Mutex::_allow_vm_block_flag);  // allow_vm_block
 372   // The queue for the GCTaskManager must be a CHeapObj.
 373   GCTaskQueue* unsynchronized_queue = GCTaskQueue::create_on_c_heap();
 374   _queue = SynchronizedGCTaskQueue::create(unsynchronized_queue, lock());
 375   _noop_task = NoopGCTask::create_on_c_heap();
 376   _resource_flag = NEW_C_HEAP_ARRAY(bool, workers());
 377   {
 378     // Set up worker threads.
 379     //     Distribute the workers among the available processors,
 380     //     unless we were told not to, or if the os doesn't want to.
 381     uint* processor_assignment = NEW_C_HEAP_ARRAY(uint, workers());
 382     if (!BindGCTaskThreadsToCPUs ||
 383         !os::distribute_processes(workers(), processor_assignment)) {
 384       for (uint a = 0; a < workers(); a += 1) {
 385         processor_assignment[a] = sentinel_worker();
 386       }
 387     }
 388     _thread = NEW_C_HEAP_ARRAY(GCTaskThread*, workers());
 389     for (uint t = 0; t < workers(); t += 1) {
 390       set_thread(t, GCTaskThread::create(this, t, processor_assignment[t]));
 391     }
 392     if (TraceGCTaskThread) {
 393       tty->print("GCTaskManager::initialize: distribution:");
 394       for (uint t = 0; t < workers(); t += 1) {
 395         tty->print("  %u", processor_assignment[t]);
 396       }
 397       tty->cr();
 398     }
 399     FREE_C_HEAP_ARRAY(uint, processor_assignment);
 400   }
 401   reset_busy_workers();
 402   set_unblocked();
 403   for (uint w = 0; w < workers(); w += 1) {
 404     set_resource_flag(w, false);
 405   }
 406   reset_delivered_tasks();
 407   reset_completed_tasks();
 408   reset_noop_tasks();
 409   reset_barriers();
 410   reset_emptied_queue();
 411   for (uint s = 0; s < workers(); s += 1) {
 412     thread(s)->start();
 413   }
 414 }
 415 
 416 GCTaskManager::~GCTaskManager() {
 417   assert(busy_workers() == 0, "still have busy workers");
 418   assert(queue()->is_empty(), "still have queued work");
 419   NoopGCTask::destroy(_noop_task);
 420   _noop_task = NULL;
 421   if (_thread != NULL) {
 422     for (uint i = 0; i < workers(); i += 1) {
 423       GCTaskThread::destroy(thread(i));
 424       set_thread(i, NULL);
 425     }
 426     FREE_C_HEAP_ARRAY(GCTaskThread*, _thread);
 427     _thread = NULL;
 428   }
 429   if (_resource_flag != NULL) {
 430     FREE_C_HEAP_ARRAY(bool, _resource_flag);
 431     _resource_flag = NULL;
 432   }
 433   if (queue() != NULL) {
 434     GCTaskQueue* unsynchronized_queue = queue()->unsynchronized_queue();
 435     GCTaskQueue::destroy(unsynchronized_queue);
 436     SynchronizedGCTaskQueue::destroy(queue());
 437     _queue = NULL;
 438   }
 439   if (monitor() != NULL) {
 440     delete monitor();
 441     _monitor = NULL;
 442   }
 443 }
 444 
 445 void GCTaskManager::print_task_time_stamps() {
 446   for(uint i=0; i<ParallelGCThreads; i++) {
 447     GCTaskThread* t = thread(i);
 448     t->print_task_time_stamps();
 449   }
 450 }
 451 
 452 void GCTaskManager::print_threads_on(outputStream* st) {
 453   uint num_thr = workers();
 454   for (uint i = 0; i < num_thr; i++) {
 455     thread(i)->print_on(st);
 456     st->cr();
 457   }
 458 }
 459 
 460 void GCTaskManager::threads_do(ThreadClosure* tc) {
 461   assert(tc != NULL, "Null ThreadClosure");
 462   uint num_thr = workers();
 463   for (uint i = 0; i < num_thr; i++) {
 464     tc->do_thread(thread(i));
 465   }
 466 }
 467 
 468 GCTaskThread* GCTaskManager::thread(uint which) {
 469   assert(which < workers(), "index out of bounds");
 470   assert(_thread[which] != NULL, "shouldn't have null thread");
 471   return _thread[which];
 472 }
 473 
 474 void GCTaskManager::set_thread(uint which, GCTaskThread* value) {
 475   assert(which < workers(), "index out of bounds");
 476   assert(value != NULL, "shouldn't have null thread");
 477   _thread[which] = value;
 478 }
 479 
 480 void GCTaskManager::add_task(GCTask* task) {
 481   assert(task != NULL, "shouldn't have null task");
 482   MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
 483   if (TraceGCTaskManager) {
 484     tty->print_cr("GCTaskManager::add_task(" INTPTR_FORMAT " [%s])",
 485                   task, GCTask::Kind::to_string(task->kind()));
 486   }
 487   queue()->enqueue(task);
 488   // Notify with the lock held to avoid missed notifies.
 489   if (TraceGCTaskManager) {
 490     tty->print_cr("    GCTaskManager::add_task (%s)->notify_all",
 491                   monitor()->name());
 492   }
 493   (void) monitor()->notify_all();
 494   // Release monitor().
 495 }
 496 
 497 void GCTaskManager::add_list(GCTaskQueue* list) {
 498   assert(list != NULL, "shouldn't have null task");
 499   MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
 500   if (TraceGCTaskManager) {
 501     tty->print_cr("GCTaskManager::add_list(%u)", list->length());
 502   }
 503   queue()->enqueue(list);
 504   // Notify with the lock held to avoid missed notifies.
 505   if (TraceGCTaskManager) {
 506     tty->print_cr("    GCTaskManager::add_list (%s)->notify_all",
 507                   monitor()->name());
 508   }
 509   (void) monitor()->notify_all();
 510   // Release monitor().
 511 }
 512 
 513 GCTask* GCTaskManager::get_task(uint which) {
 514   GCTask* result = NULL;
 515   // Grab the queue lock.
 516   MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
 517   // Wait while the queue is block or
 518   // there is nothing to do, except maybe release resources.
 519   while (is_blocked() ||
 520          (queue()->is_empty() && !should_release_resources(which))) {
 521     if (TraceGCTaskManager) {
 522       tty->print_cr("GCTaskManager::get_task(%u)"
 523                     "  blocked: %s"
 524                     "  empty: %s"
 525                     "  release: %s",
 526                     which,
 527                     is_blocked() ? "true" : "false",
 528                     queue()->is_empty() ? "true" : "false",
 529                     should_release_resources(which) ? "true" : "false");
 530       tty->print_cr("    => (%s)->wait()",
 531                     monitor()->name());
 532     }
 533     monitor()->wait(Mutex::_no_safepoint_check_flag, 0);
 534   }
 535   // We've reacquired the queue lock here.
 536   // Figure out which condition caused us to exit the loop above.
 537   if (!queue()->is_empty()) {
 538     if (UseGCTaskAffinity) {
 539       result = queue()->dequeue(which);
 540     } else {
 541       result = queue()->dequeue();
 542     }
 543     if (result->is_barrier_task()) {
 544       assert(which != sentinel_worker(),
 545              "blocker shouldn't be bogus");
 546       set_blocking_worker(which);
 547     }
 548   } else {
 549     // The queue is empty, but we were woken up.
 550     // Just hand back a Noop task,
 551     // in case someone wanted us to release resources, or whatever.
 552     result = noop_task();
 553     increment_noop_tasks();
 554   }
 555   assert(result != NULL, "shouldn't have null task");
 556   if (TraceGCTaskManager) {
 557     tty->print_cr("GCTaskManager::get_task(%u) => " INTPTR_FORMAT " [%s]",
 558                   which, result, GCTask::Kind::to_string(result->kind()));
 559     tty->print_cr("     %s", result->name());
 560   }
 561   increment_busy_workers();
 562   increment_delivered_tasks();
 563   return result;
 564   // Release monitor().
 565 }
 566 
 567 void GCTaskManager::note_completion(uint which) {
 568   MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
 569   if (TraceGCTaskManager) {
 570     tty->print_cr("GCTaskManager::note_completion(%u)", which);
 571   }
 572   // If we are blocked, check if the completing thread is the blocker.
 573   if (blocking_worker() == which) {
 574     assert(blocking_worker() != sentinel_worker(),
 575            "blocker shouldn't be bogus");
 576     increment_barriers();
 577     set_unblocked();
 578   }
 579   increment_completed_tasks();
 580   uint active = decrement_busy_workers();
 581   if ((active == 0) && (queue()->is_empty())) {
 582     increment_emptied_queue();
 583     if (TraceGCTaskManager) {
 584       tty->print_cr("    GCTaskManager::note_completion(%u) done", which);
 585     }
 586     // Notify client that we are done.
 587     NotifyDoneClosure* ndc = notify_done_closure();
 588     if (ndc != NULL) {
 589       ndc->notify(this);
 590     }
 591   }
 592   if (TraceGCTaskManager) {
 593     tty->print_cr("    GCTaskManager::note_completion(%u) (%s)->notify_all",
 594                   which, monitor()->name());
 595     tty->print_cr("  "
 596                   "  blocked: %s"
 597                   "  empty: %s"
 598                   "  release: %s",
 599                   is_blocked() ? "true" : "false",
 600                   queue()->is_empty() ? "true" : "false",
 601                   should_release_resources(which) ? "true" : "false");
 602     tty->print_cr("  "
 603                   "  delivered: %u"
 604                   "  completed: %u"
 605                   "  barriers: %u"
 606                   "  emptied: %u",
 607                   delivered_tasks(),
 608                   completed_tasks(),
 609                   barriers(),
 610                   emptied_queue());
 611   }
 612   // Tell everyone that a task has completed.
 613   (void) monitor()->notify_all();
 614   // Release monitor().
 615 }
 616 
 617 uint GCTaskManager::increment_busy_workers() {
 618   assert(queue()->own_lock(), "don't own the lock");
 619   _busy_workers += 1;
 620   return _busy_workers;
 621 }
 622 
 623 uint GCTaskManager::decrement_busy_workers() {
 624   assert(queue()->own_lock(), "don't own the lock");
 625   _busy_workers -= 1;
 626   return _busy_workers;
 627 }
 628 
 629 void GCTaskManager::release_all_resources() {
 630   // If you want this to be done atomically, do it in a BarrierGCTask.
 631   for (uint i = 0; i < workers(); i += 1) {
 632     set_resource_flag(i, true);
 633   }
 634 }
 635 
 636 bool GCTaskManager::should_release_resources(uint which) {
 637   // This can be done without a lock because each thread reads one element.
 638   return resource_flag(which);
 639 }
 640 
 641 void GCTaskManager::note_release(uint which) {
 642   // This can be done without a lock because each thread writes one element.
 643   set_resource_flag(which, false);
 644 }
 645 
 646 void GCTaskManager::execute_and_wait(GCTaskQueue* list) {
 647   WaitForBarrierGCTask* fin = WaitForBarrierGCTask::create();
 648   list->enqueue(fin);
 649   add_list(list);
 650   fin->wait_for();
 651   // We have to release the barrier tasks!
 652   WaitForBarrierGCTask::destroy(fin);
 653 }
 654 
 655 bool GCTaskManager::resource_flag(uint which) {
 656   assert(which < workers(), "index out of bounds");
 657   return _resource_flag[which];
 658 }
 659 
 660 void GCTaskManager::set_resource_flag(uint which, bool value) {
 661   assert(which < workers(), "index out of bounds");
 662   _resource_flag[which] = value;
 663 }
 664 
 665 //
 666 // NoopGCTask
 667 //
 668 
 669 NoopGCTask* NoopGCTask::create() {
 670   NoopGCTask* result = new NoopGCTask(false);
 671   return result;
 672 }
 673 
 674 NoopGCTask* NoopGCTask::create_on_c_heap() {
 675   NoopGCTask* result = new(ResourceObj::C_HEAP) NoopGCTask(true);
 676   return result;
 677 }
 678 
 679 void NoopGCTask::destroy(NoopGCTask* that) {
 680   if (that != NULL) {
 681     that->destruct();
 682     if (that->is_c_heap_obj()) {
 683       FreeHeap(that);
 684     }
 685   }
 686 }
 687 
 688 void NoopGCTask::destruct() {
 689   // This has to know it's superclass structure, just like the constructor.
 690   this->GCTask::destruct();
 691   // Nothing else to do.
 692 }
 693 
 694 //
 695 // BarrierGCTask
 696 //
 697 
 698 void BarrierGCTask::do_it(GCTaskManager* manager, uint which) {
 699   // Wait for this to be the only busy worker.
 700   // ??? I thought of having a StackObj class
 701   //     whose constructor would grab the lock and come to the barrier,
 702   //     and whose destructor would release the lock,
 703   //     but that seems like too much mechanism for two lines of code.
 704   MutexLockerEx ml(manager->lock(), Mutex::_no_safepoint_check_flag);
 705   do_it_internal(manager, which);
 706   // Release manager->lock().
 707 }
 708 
 709 void BarrierGCTask::do_it_internal(GCTaskManager* manager, uint which) {
 710   // Wait for this to be the only busy worker.
 711   assert(manager->monitor()->owned_by_self(), "don't own the lock");
 712   assert(manager->is_blocked(), "manager isn't blocked");
 713   while (manager->busy_workers() > 1) {
 714     if (TraceGCTaskManager) {
 715       tty->print_cr("BarrierGCTask::do_it(%u) waiting on %u workers",
 716                     which, manager->busy_workers());
 717     }
 718     manager->monitor()->wait(Mutex::_no_safepoint_check_flag, 0);
 719   }
 720 }
 721 
 722 void BarrierGCTask::destruct() {
 723   this->GCTask::destruct();
 724   // Nothing else to do.
 725 }
 726 
 727 //
 728 // ReleasingBarrierGCTask
 729 //
 730 
 731 void ReleasingBarrierGCTask::do_it(GCTaskManager* manager, uint which) {
 732   MutexLockerEx ml(manager->lock(), Mutex::_no_safepoint_check_flag);
 733   do_it_internal(manager, which);
 734   manager->release_all_resources();
 735   // Release manager->lock().
 736 }
 737 
 738 void ReleasingBarrierGCTask::destruct() {
 739   this->BarrierGCTask::destruct();
 740   // Nothing else to do.
 741 }
 742 
 743 //
 744 // NotifyingBarrierGCTask
 745 //
 746 
 747 void NotifyingBarrierGCTask::do_it(GCTaskManager* manager, uint which) {
 748   MutexLockerEx ml(manager->lock(), Mutex::_no_safepoint_check_flag);
 749   do_it_internal(manager, which);
 750   NotifyDoneClosure* ndc = notify_done_closure();
 751   if (ndc != NULL) {
 752     ndc->notify(manager);
 753   }
 754   // Release manager->lock().
 755 }
 756 
 757 void NotifyingBarrierGCTask::destruct() {
 758   this->BarrierGCTask::destruct();
 759   // Nothing else to do.
 760 }
 761 
 762 //
 763 // WaitForBarrierGCTask
 764 //
 765 WaitForBarrierGCTask* WaitForBarrierGCTask::create() {
 766   WaitForBarrierGCTask* result = new WaitForBarrierGCTask(false);
 767   return result;
 768 }
 769 
 770 WaitForBarrierGCTask* WaitForBarrierGCTask::create_on_c_heap() {
 771   WaitForBarrierGCTask* result = new WaitForBarrierGCTask(true);
 772   return result;
 773 }
 774 
 775 WaitForBarrierGCTask::WaitForBarrierGCTask(bool on_c_heap) :
 776   _is_c_heap_obj(on_c_heap) {
 777   _monitor = MonitorSupply::reserve();
 778   set_should_wait(true);
 779   if (TraceGCTaskManager) {
 780     tty->print_cr("[" INTPTR_FORMAT "]"
 781                   " WaitForBarrierGCTask::WaitForBarrierGCTask()"
 782                   "  monitor: " INTPTR_FORMAT,
 783                   this, monitor());
 784   }
 785 }
 786 
 787 void WaitForBarrierGCTask::destroy(WaitForBarrierGCTask* that) {
 788   if (that != NULL) {
 789     if (TraceGCTaskManager) {
 790       tty->print_cr("[" INTPTR_FORMAT "]"
 791                     " WaitForBarrierGCTask::destroy()"
 792                     "  is_c_heap_obj: %s"
 793                     "  monitor: " INTPTR_FORMAT,
 794                     that,
 795                     that->is_c_heap_obj() ? "true" : "false",
 796                     that->monitor());
 797     }
 798     that->destruct();
 799     if (that->is_c_heap_obj()) {
 800       FreeHeap(that);
 801     }
 802   }
 803 }
 804 
 805 void WaitForBarrierGCTask::destruct() {
 806   assert(monitor() != NULL, "monitor should not be NULL");
 807   if (TraceGCTaskManager) {
 808     tty->print_cr("[" INTPTR_FORMAT "]"
 809                   " WaitForBarrierGCTask::destruct()"
 810                   "  monitor: " INTPTR_FORMAT,
 811                   this, monitor());
 812   }
 813   this->BarrierGCTask::destruct();
 814   // Clean up that should be in the destructor,
 815   // except that ResourceMarks don't call destructors.
 816    if (monitor() != NULL) {
 817      MonitorSupply::release(monitor());
 818   }
 819   _monitor = (Monitor*) 0xDEAD000F;
 820 }
 821 
 822 void WaitForBarrierGCTask::do_it(GCTaskManager* manager, uint which) {
 823   if (TraceGCTaskManager) {
 824     tty->print_cr("[" INTPTR_FORMAT "]"
 825                   " WaitForBarrierGCTask::do_it() waiting for idle"
 826                   "  monitor: " INTPTR_FORMAT,
 827                   this, monitor());
 828   }
 829   {
 830     // First, wait for the barrier to arrive.
 831     MutexLockerEx ml(manager->lock(), Mutex::_no_safepoint_check_flag);
 832     do_it_internal(manager, which);
 833     // Release manager->lock().
 834   }
 835   {
 836     // Then notify the waiter.
 837     MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
 838     set_should_wait(false);
 839     // Waiter doesn't miss the notify in the wait_for method
 840     // since it checks the flag after grabbing the monitor.
 841     if (TraceGCTaskManager) {
 842       tty->print_cr("[" INTPTR_FORMAT "]"
 843                     " WaitForBarrierGCTask::do_it()"
 844                     "  [" INTPTR_FORMAT "] (%s)->notify_all()",
 845                     this, monitor(), monitor()->name());
 846     }
 847     monitor()->notify_all();
 848     // Release monitor().
 849   }
 850 }
 851 
 852 void WaitForBarrierGCTask::wait_for() {
 853   if (TraceGCTaskManager) {
 854     tty->print_cr("[" INTPTR_FORMAT "]"
 855                   " WaitForBarrierGCTask::wait_for()"
 856       "  should_wait: %s",
 857       this, should_wait() ? "true" : "false");
 858   }
 859   {
 860     // Grab the lock and check again.
 861     MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
 862     while (should_wait()) {
 863       if (TraceGCTaskManager) {
 864         tty->print_cr("[" INTPTR_FORMAT "]"
 865                       " WaitForBarrierGCTask::wait_for()"
 866           "  [" INTPTR_FORMAT "] (%s)->wait()",
 867           this, monitor(), monitor()->name());
 868       }
 869       monitor()->wait(Mutex::_no_safepoint_check_flag, 0);
 870     }
 871     // Reset the flag in case someone reuses this task.
 872     set_should_wait(true);
 873     if (TraceGCTaskManager) {
 874       tty->print_cr("[" INTPTR_FORMAT "]"
 875                     " WaitForBarrierGCTask::wait_for() returns"
 876         "  should_wait: %s",
 877         this, should_wait() ? "true" : "false");
 878     }
 879     // Release monitor().
 880   }
 881 }
 882 
 883 Mutex*                   MonitorSupply::_lock     = NULL;
 884 GrowableArray<Monitor*>* MonitorSupply::_freelist = NULL;
 885 
 886 Monitor* MonitorSupply::reserve() {
 887   Monitor* result = NULL;
 888   // Lazy initialization: possible race.
 889   if (lock() == NULL) {
 890     _lock = new Mutex(Mutex::barrier,                  // rank
 891                       "MonitorSupply mutex",           // name
 892                       Mutex::_allow_vm_block_flag);    // allow_vm_block
 893   }
 894   {
 895     MutexLockerEx ml(lock());
 896     // Lazy initialization.
 897     if (freelist() == NULL) {
 898       _freelist =
 899         new(ResourceObj::C_HEAP) GrowableArray<Monitor*>(ParallelGCThreads,
 900                                                          true);
 901     }
 902     if (! freelist()->is_empty()) {
 903       result = freelist()->pop();
 904     } else {
 905       result = new Monitor(Mutex::barrier,                  // rank
 906                            "MonitorSupply monitor",         // name
 907                            Mutex::_allow_vm_block_flag);    // allow_vm_block
 908     }
 909     guarantee(result != NULL, "shouldn't return NULL");
 910     assert(!result->is_locked(), "shouldn't be locked");
 911     // release lock().
 912   }
 913   return result;
 914 }
 915 
 916 void MonitorSupply::release(Monitor* instance) {
 917   assert(instance != NULL, "shouldn't release NULL");
 918   assert(!instance->is_locked(), "shouldn't be locked");
 919   {
 920     MutexLockerEx ml(lock());
 921     freelist()->push(instance);
 922     // release lock().
 923   }
 924 }