src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp

Fri, 29 Apr 2016 00:06:10 +0800

author
aoqi
date
Fri, 29 Apr 2016 00:06:10 +0800
changeset 1
2d8a650513c2
parent 0
f90c822e73f8
child 25
873fd82b133d
permissions
-rw-r--r--

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().
  1003 void ReleasingBarrierGCTask::destruct() {
  1004   this->BarrierGCTask::destruct();
  1005   // Nothing else to do.
  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);
  1019   // Release manager->lock().
  1022 void NotifyingBarrierGCTask::destruct() {
  1023   this->BarrierGCTask::destruct();
  1024   // Nothing else to do.
  1027 //
  1028 // WaitForBarrierGCTask
  1029 //
  1030 WaitForBarrierGCTask* WaitForBarrierGCTask::create() {
  1031   WaitForBarrierGCTask* result = new WaitForBarrierGCTask(false);
  1032   return result;
  1035 WaitForBarrierGCTask* WaitForBarrierGCTask::create_on_c_heap() {
  1036   WaitForBarrierGCTask* result =
  1037     new (ResourceObj::C_HEAP, mtGC) WaitForBarrierGCTask(true);
  1038   return result;
  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());
  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());
  1064     that->destruct();
  1065     if (that->is_c_heap_obj()) {
  1066       FreeHeap(that);
  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());
  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());
  1085   _monitor = (Monitor*) 0xDEAD000F;
  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());
  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().
  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());
  1113     monitor()->notify_all();
  1114     // Release monitor().
  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");
  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());
  1135       monitor()->wait(Mutex::_no_safepoint_check_flag, 0);
  1137     // Reset the flag in case someone reuses this task.
  1138     if (reset) {
  1139       set_should_wait(true);
  1141     if (TraceGCTaskManager) {
  1142       tty->print_cr("[" INTPTR_FORMAT "]"
  1143                     " WaitForBarrierGCTask::wait_for() returns"
  1144         "  should_wait: %s",
  1145         this, should_wait() ? "true" : "false");
  1147     // Release monitor().
  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
  1163     MutexLockerEx ml(lock());
  1164     // Lazy initialization.
  1165     if (freelist() == NULL) {
  1166       _freelist =
  1167         new(ResourceObj::C_HEAP, mtGC) GrowableArray<Monitor*>(ParallelGCThreads,
  1168                                                          true);
  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
  1177     guarantee(result != NULL, "shouldn't return NULL");
  1178     assert(!result->is_locked(), "shouldn't be locked");
  1179     // release lock().
  1181   return result;
  1184 void MonitorSupply::release(Monitor* instance) {
  1185   assert(instance != NULL, "shouldn't release NULL");
  1186   assert(!instance->is_locked(), "shouldn't be locked");
  1188     MutexLockerEx ml(lock());
  1189     freelist()->push(instance);
  1190     // release lock().

mercurial