src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp

Tue, 08 Aug 2017 15:57:29 +0800

author
aoqi
date
Tue, 08 Aug 2017 15:57:29 +0800
changeset 6876
710a3c8b516e
parent 6680
78bbf4d43a14
parent 0
f90c822e73f8
permissions
-rw-r--r--

merge

     1 /*
     2  * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 #include "precompiled.hpp"
    26 #include "classfile/systemDictionary.hpp"
    27 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp"
    28 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
    29 #include "memory/genCollectedHeap.hpp"
    30 #include "oops/instanceRefKlass.hpp"
    31 #include "oops/oop.inline.hpp"
    32 #include "runtime/init.hpp"
    33 #include "runtime/interfaceSupport.hpp"
    34 #include "runtime/java.hpp"
    35 #include "runtime/javaCalls.hpp"
    36 #include "runtime/mutexLocker.hpp"
    37 #include "runtime/os.hpp"
    38 #include "runtime/vmThread.hpp"
    40 // ======= Concurrent Mark Sweep Thread ========
    42 // The CMS thread is created when Concurrent Mark Sweep is used in the
    43 // older of two generations in a generational memory system.
    45 ConcurrentMarkSweepThread*
    46      ConcurrentMarkSweepThread::_cmst     = NULL;
    47 CMSCollector* ConcurrentMarkSweepThread::_collector = NULL;
    48 bool ConcurrentMarkSweepThread::_should_terminate = false;
    49 int  ConcurrentMarkSweepThread::_CMS_flag         = CMS_nil;
    51 volatile jint ConcurrentMarkSweepThread::_pending_yields      = 0;
    52 volatile jint ConcurrentMarkSweepThread::_pending_decrements  = 0;
    54 volatile jint ConcurrentMarkSweepThread::_icms_disabled   = 0;
    55 volatile bool ConcurrentMarkSweepThread::_should_run     = false;
    56 // When icms is enabled, the icms thread is stopped until explicitly
    57 // started.
    58 volatile bool ConcurrentMarkSweepThread::_should_stop    = true;
    60 SurrogateLockerThread*
    61      ConcurrentMarkSweepThread::_slt = NULL;
    62 SurrogateLockerThread::SLT_msg_type
    63      ConcurrentMarkSweepThread::_sltBuffer = SurrogateLockerThread::empty;
    64 Monitor*
    65      ConcurrentMarkSweepThread::_sltMonitor = NULL;
    67 ConcurrentMarkSweepThread::ConcurrentMarkSweepThread(CMSCollector* collector)
    68   : ConcurrentGCThread() {
    69   assert(UseConcMarkSweepGC,  "UseConcMarkSweepGC should be set");
    70   assert(_cmst == NULL, "CMS thread already created");
    71   _cmst = this;
    72   assert(_collector == NULL, "Collector already set");
    73   _collector = collector;
    75   set_name("Concurrent Mark-Sweep GC Thread");
    77   if (os::create_thread(this, os::cgc_thread)) {
    78     // An old comment here said: "Priority should be just less
    79     // than that of VMThread".  Since the VMThread runs at
    80     // NearMaxPriority, the old comment was inaccurate, but
    81     // changing the default priority to NearMaxPriority-1
    82     // could change current behavior, so the default of
    83     // NearMaxPriority stays in place.
    84     //
    85     // Note that there's a possibility of the VMThread
    86     // starving if UseCriticalCMSThreadPriority is on.
    87     // That won't happen on Solaris for various reasons,
    88     // but may well happen on non-Solaris platforms.
    89     int native_prio;
    90     if (UseCriticalCMSThreadPriority) {
    91       native_prio = os::java_to_os_priority[CriticalPriority];
    92     } else {
    93       native_prio = os::java_to_os_priority[NearMaxPriority];
    94     }
    95     os::set_native_priority(this, native_prio);
    97     if (!DisableStartThread) {
    98       os::start_thread(this);
    99     }
   100   }
   101   _sltMonitor = SLT_lock;
   102   assert(!CMSIncrementalMode || icms_is_enabled(), "Error");
   103 }
   105 void ConcurrentMarkSweepThread::run() {
   106   assert(this == cmst(), "just checking");
   108   this->record_stack_base_and_size();
   109   this->initialize_thread_local_storage();
   110   this->set_active_handles(JNIHandleBlock::allocate_block());
   111   // From this time Thread::current() should be working.
   112   assert(this == Thread::current(), "just checking");
   113   if (BindCMSThreadToCPU && !os::bind_to_processor(CPUForCMSThread)) {
   114     warning("Couldn't bind CMS thread to processor " UINTX_FORMAT, CPUForCMSThread);
   115   }
   116   // Wait until Universe::is_fully_initialized()
   117   {
   118     CMSLoopCountWarn loopX("CMS::run", "waiting for "
   119                            "Universe::is_fully_initialized()", 2);
   120     MutexLockerEx x(CGC_lock, true);
   121     set_CMS_flag(CMS_cms_wants_token);
   122     // Wait until Universe is initialized and all initialization is completed.
   123     while (!is_init_completed() && !Universe::is_fully_initialized() &&
   124            !_should_terminate) {
   125       CGC_lock->wait(true, 200);
   126       loopX.tick();
   127     }
   128     // Wait until the surrogate locker thread that will do
   129     // pending list locking on our behalf has been created.
   130     // We cannot start the SLT thread ourselves since we need
   131     // to be a JavaThread to do so.
   132     CMSLoopCountWarn loopY("CMS::run", "waiting for SLT installation", 2);
   133     while (_slt == NULL && !_should_terminate) {
   134       CGC_lock->wait(true, 200);
   135       loopY.tick();
   136     }
   137     clear_CMS_flag(CMS_cms_wants_token);
   138   }
   140   while (!_should_terminate) {
   141     sleepBeforeNextCycle();
   142     if (_should_terminate) break;
   143     GCCause::Cause cause = _collector->_full_gc_requested ?
   144       _collector->_full_gc_cause : GCCause::_cms_concurrent_mark;
   145     _collector->collect_in_background(false, cause);
   146   }
   147   assert(_should_terminate, "just checking");
   148   // Check that the state of any protocol for synchronization
   149   // between background (CMS) and foreground collector is "clean"
   150   // (i.e. will not potentially block the foreground collector,
   151   // requiring action by us).
   152   verify_ok_to_terminate();
   153   // Signal that it is terminated
   154   {
   155     MutexLockerEx mu(Terminator_lock,
   156                      Mutex::_no_safepoint_check_flag);
   157     assert(_cmst == this, "Weird!");
   158     _cmst = NULL;
   159     Terminator_lock->notify();
   160   }
   162   // Thread destructor usually does this..
   163   ThreadLocalStorage::set_thread(NULL);
   164 }
   166 #ifndef PRODUCT
   167 void ConcurrentMarkSweepThread::verify_ok_to_terminate() const {
   168   assert(!(CGC_lock->owned_by_self() || cms_thread_has_cms_token() ||
   169            cms_thread_wants_cms_token()),
   170          "Must renounce all worldly possessions and desires for nirvana");
   171   _collector->verify_ok_to_terminate();
   172 }
   173 #endif
   175 // create and start a new ConcurrentMarkSweep Thread for given CMS generation
   176 ConcurrentMarkSweepThread* ConcurrentMarkSweepThread::start(CMSCollector* collector) {
   177   if (!_should_terminate) {
   178     assert(cmst() == NULL, "start() called twice?");
   179     ConcurrentMarkSweepThread* th = new ConcurrentMarkSweepThread(collector);
   180     assert(cmst() == th, "Where did the just-created CMS thread go?");
   181     return th;
   182   }
   183   return NULL;
   184 }
   186 void ConcurrentMarkSweepThread::stop() {
   187   if (CMSIncrementalMode) {
   188     // Disable incremental mode and wake up the thread so it notices the change.
   189     disable_icms();
   190     start_icms();
   191   }
   192   // it is ok to take late safepoints here, if needed
   193   {
   194     MutexLockerEx x(Terminator_lock);
   195     _should_terminate = true;
   196   }
   197   { // Now post a notify on CGC_lock so as to nudge
   198     // CMS thread(s) that might be slumbering in
   199     // sleepBeforeNextCycle.
   200     MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
   201     CGC_lock->notify_all();
   202   }
   203   { // Now wait until (all) CMS thread(s) have exited
   204     MutexLockerEx x(Terminator_lock);
   205     while(cmst() != NULL) {
   206       Terminator_lock->wait();
   207     }
   208   }
   209 }
   211 void ConcurrentMarkSweepThread::threads_do(ThreadClosure* tc) {
   212   assert(tc != NULL, "Null ThreadClosure");
   213   if (_cmst != NULL) {
   214     tc->do_thread(_cmst);
   215   }
   216   assert(Universe::is_fully_initialized(),
   217          "Called too early, make sure heap is fully initialized");
   218   if (_collector != NULL) {
   219     AbstractWorkGang* gang = _collector->conc_workers();
   220     if (gang != NULL) {
   221       gang->threads_do(tc);
   222     }
   223   }
   224 }
   226 void ConcurrentMarkSweepThread::print_on(outputStream* st) const {
   227   st->print("\"%s\" ", name());
   228   Thread::print_on(st);
   229   st->cr();
   230 }
   232 void ConcurrentMarkSweepThread::print_all_on(outputStream* st) {
   233   if (_cmst != NULL) {
   234     _cmst->print_on(st);
   235     st->cr();
   236   }
   237   if (_collector != NULL) {
   238     AbstractWorkGang* gang = _collector->conc_workers();
   239     if (gang != NULL) {
   240       gang->print_worker_threads_on(st);
   241     }
   242   }
   243 }
   245 void ConcurrentMarkSweepThread::synchronize(bool is_cms_thread) {
   246   assert(UseConcMarkSweepGC, "just checking");
   248   MutexLockerEx x(CGC_lock,
   249                   Mutex::_no_safepoint_check_flag);
   250   if (!is_cms_thread) {
   251     assert(Thread::current()->is_VM_thread(), "Not a VM thread");
   252     CMSSynchronousYieldRequest yr;
   253     while (CMS_flag_is_set(CMS_cms_has_token)) {
   254       // indicate that we want to get the token
   255       set_CMS_flag(CMS_vm_wants_token);
   256       CGC_lock->wait(true);
   257     }
   258     // claim the token and proceed
   259     clear_CMS_flag(CMS_vm_wants_token);
   260     set_CMS_flag(CMS_vm_has_token);
   261   } else {
   262     assert(Thread::current()->is_ConcurrentGC_thread(),
   263            "Not a CMS thread");
   264     // The following barrier assumes there's only one CMS thread.
   265     // This will need to be modified is there are more CMS threads than one.
   266     while (CMS_flag_is_set(CMS_vm_has_token | CMS_vm_wants_token)) {
   267       set_CMS_flag(CMS_cms_wants_token);
   268       CGC_lock->wait(true);
   269     }
   270     // claim the token
   271     clear_CMS_flag(CMS_cms_wants_token);
   272     set_CMS_flag(CMS_cms_has_token);
   273   }
   274 }
   276 void ConcurrentMarkSweepThread::desynchronize(bool is_cms_thread) {
   277   assert(UseConcMarkSweepGC, "just checking");
   279   MutexLockerEx x(CGC_lock,
   280                   Mutex::_no_safepoint_check_flag);
   281   if (!is_cms_thread) {
   282     assert(Thread::current()->is_VM_thread(), "Not a VM thread");
   283     assert(CMS_flag_is_set(CMS_vm_has_token), "just checking");
   284     clear_CMS_flag(CMS_vm_has_token);
   285     if (CMS_flag_is_set(CMS_cms_wants_token)) {
   286       // wake-up a waiting CMS thread
   287       CGC_lock->notify();
   288     }
   289     assert(!CMS_flag_is_set(CMS_vm_has_token | CMS_vm_wants_token),
   290            "Should have been cleared");
   291   } else {
   292     assert(Thread::current()->is_ConcurrentGC_thread(),
   293            "Not a CMS thread");
   294     assert(CMS_flag_is_set(CMS_cms_has_token), "just checking");
   295     clear_CMS_flag(CMS_cms_has_token);
   296     if (CMS_flag_is_set(CMS_vm_wants_token)) {
   297       // wake-up a waiting VM thread
   298       CGC_lock->notify();
   299     }
   300     assert(!CMS_flag_is_set(CMS_cms_has_token | CMS_cms_wants_token),
   301            "Should have been cleared");
   302   }
   303 }
   305 // Wait until any cms_lock event
   306 void ConcurrentMarkSweepThread::wait_on_cms_lock(long t_millis) {
   307   MutexLockerEx x(CGC_lock,
   308                   Mutex::_no_safepoint_check_flag);
   309   if (_should_terminate || _collector->_full_gc_requested) {
   310     return;
   311   }
   312   set_CMS_flag(CMS_cms_wants_token);   // to provoke notifies
   313   CGC_lock->wait(Mutex::_no_safepoint_check_flag, t_millis);
   314   clear_CMS_flag(CMS_cms_wants_token);
   315   assert(!CMS_flag_is_set(CMS_cms_has_token | CMS_cms_wants_token),
   316          "Should not be set");
   317 }
   319 // Wait until the next synchronous GC, a concurrent full gc request,
   320 // or a timeout, whichever is earlier.
   321 void ConcurrentMarkSweepThread::wait_on_cms_lock_for_scavenge(long t_millis) {
   322   // Wait time in millis or 0 value representing infinite wait for a scavenge
   323   assert(t_millis >= 0, "Wait time for scavenge should be 0 or positive");
   325   GenCollectedHeap* gch = GenCollectedHeap::heap();
   326   double start_time_secs = os::elapsedTime();
   327   double end_time_secs = start_time_secs + (t_millis / ((double) MILLIUNITS));
   329   // Total collections count before waiting loop
   330   unsigned int before_count;
   331   {
   332     MutexLockerEx hl(Heap_lock, Mutex::_no_safepoint_check_flag);
   333     before_count = gch->total_collections();
   334   }
   336   unsigned int loop_count = 0;
   338   while(!_should_terminate) {
   339     double now_time = os::elapsedTime();
   340     long wait_time_millis;
   342     if(t_millis != 0) {
   343       // New wait limit
   344       wait_time_millis = (long) ((end_time_secs - now_time) * MILLIUNITS);
   345       if(wait_time_millis <= 0) {
   346         // Wait time is over
   347         break;
   348       }
   349     } else {
   350       // No wait limit, wait if necessary forever
   351       wait_time_millis = 0;
   352     }
   354     // Wait until the next event or the remaining timeout
   355     {
   356       MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
   358       if (_should_terminate || _collector->_full_gc_requested) {
   359         return;
   360       }
   361       set_CMS_flag(CMS_cms_wants_token);   // to provoke notifies
   362       assert(t_millis == 0 || wait_time_millis > 0, "Sanity");
   363       CGC_lock->wait(Mutex::_no_safepoint_check_flag, wait_time_millis);
   364       clear_CMS_flag(CMS_cms_wants_token);
   365       assert(!CMS_flag_is_set(CMS_cms_has_token | CMS_cms_wants_token),
   366              "Should not be set");
   367     }
   369     // Extra wait time check before entering the heap lock to get the collection count
   370     if(t_millis != 0 && os::elapsedTime() >= end_time_secs) {
   371       // Wait time is over
   372       break;
   373     }
   375     // Total collections count after the event
   376     unsigned int after_count;
   377     {
   378       MutexLockerEx hl(Heap_lock, Mutex::_no_safepoint_check_flag);
   379       after_count = gch->total_collections();
   380     }
   382     if(before_count != after_count) {
   383       // There was a collection - success
   384       break;
   385     }
   387     // Too many loops warning
   388     if(++loop_count == 0) {
   389       warning("wait_on_cms_lock_for_scavenge() has looped %u times", loop_count - 1);
   390     }
   391   }
   392 }
   394 void ConcurrentMarkSweepThread::sleepBeforeNextCycle() {
   395   while (!_should_terminate) {
   396     if (CMSIncrementalMode) {
   397       icms_wait();
   398       if(CMSWaitDuration >= 0) {
   399         // Wait until the next synchronous GC, a concurrent full gc
   400         // request or a timeout, whichever is earlier.
   401         wait_on_cms_lock_for_scavenge(CMSWaitDuration);
   402       }
   403       return;
   404     } else {
   405       if(CMSWaitDuration >= 0) {
   406         // Wait until the next synchronous GC, a concurrent full gc
   407         // request or a timeout, whichever is earlier.
   408         wait_on_cms_lock_for_scavenge(CMSWaitDuration);
   409       } else {
   410         // Wait until any cms_lock event or check interval not to call shouldConcurrentCollect permanently
   411         wait_on_cms_lock(CMSCheckInterval);
   412       }
   413     }
   414     // Check if we should start a CMS collection cycle
   415     if (_collector->shouldConcurrentCollect()) {
   416       return;
   417     }
   418     // .. collection criterion not yet met, let's go back
   419     // and wait some more
   420   }
   421 }
   423 // Incremental CMS
   424 void ConcurrentMarkSweepThread::start_icms() {
   425   assert(UseConcMarkSweepGC && CMSIncrementalMode, "just checking");
   426   MutexLockerEx x(iCMS_lock, Mutex::_no_safepoint_check_flag);
   427   trace_state("start_icms");
   428   _should_run = true;
   429   iCMS_lock->notify_all();
   430 }
   432 void ConcurrentMarkSweepThread::stop_icms() {
   433   assert(UseConcMarkSweepGC && CMSIncrementalMode, "just checking");
   434   MutexLockerEx x(iCMS_lock, Mutex::_no_safepoint_check_flag);
   435   if (!_should_stop) {
   436     trace_state("stop_icms");
   437     _should_stop = true;
   438     _should_run = false;
   439     asynchronous_yield_request();
   440     iCMS_lock->notify_all();
   441   }
   442 }
   444 void ConcurrentMarkSweepThread::icms_wait() {
   445   assert(UseConcMarkSweepGC && CMSIncrementalMode, "just checking");
   446   if (_should_stop && icms_is_enabled()) {
   447     MutexLockerEx x(iCMS_lock, Mutex::_no_safepoint_check_flag);
   448     trace_state("pause_icms");
   449     _collector->stats().stop_cms_timer();
   450     while(!_should_run && icms_is_enabled()) {
   451       iCMS_lock->wait(Mutex::_no_safepoint_check_flag);
   452     }
   453     _collector->stats().start_cms_timer();
   454     _should_stop = false;
   455     trace_state("pause_icms end");
   456   }
   457 }
   459 // Note: this method, although exported by the ConcurrentMarkSweepThread,
   460 // which is a non-JavaThread, can only be called by a JavaThread.
   461 // Currently this is done at vm creation time (post-vm-init) by the
   462 // main/Primordial (Java)Thread.
   463 // XXX Consider changing this in the future to allow the CMS thread
   464 // itself to create this thread?
   465 void ConcurrentMarkSweepThread::makeSurrogateLockerThread(TRAPS) {
   466   assert(UseConcMarkSweepGC, "SLT thread needed only for CMS GC");
   467   assert(_slt == NULL, "SLT already created");
   468   _slt = SurrogateLockerThread::make(THREAD);
   469 }

mercurial