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