1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,469 @@ 1.4 +/* 1.5 + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "precompiled.hpp" 1.29 +#include "classfile/systemDictionary.hpp" 1.30 +#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp" 1.31 +#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp" 1.32 +#include "memory/genCollectedHeap.hpp" 1.33 +#include "oops/instanceRefKlass.hpp" 1.34 +#include "oops/oop.inline.hpp" 1.35 +#include "runtime/init.hpp" 1.36 +#include "runtime/interfaceSupport.hpp" 1.37 +#include "runtime/java.hpp" 1.38 +#include "runtime/javaCalls.hpp" 1.39 +#include "runtime/mutexLocker.hpp" 1.40 +#include "runtime/os.hpp" 1.41 +#include "runtime/vmThread.hpp" 1.42 + 1.43 +// ======= Concurrent Mark Sweep Thread ======== 1.44 + 1.45 +// The CMS thread is created when Concurrent Mark Sweep is used in the 1.46 +// older of two generations in a generational memory system. 1.47 + 1.48 +ConcurrentMarkSweepThread* 1.49 + ConcurrentMarkSweepThread::_cmst = NULL; 1.50 +CMSCollector* ConcurrentMarkSweepThread::_collector = NULL; 1.51 +bool ConcurrentMarkSweepThread::_should_terminate = false; 1.52 +int ConcurrentMarkSweepThread::_CMS_flag = CMS_nil; 1.53 + 1.54 +volatile jint ConcurrentMarkSweepThread::_pending_yields = 0; 1.55 +volatile jint ConcurrentMarkSweepThread::_pending_decrements = 0; 1.56 + 1.57 +volatile jint ConcurrentMarkSweepThread::_icms_disabled = 0; 1.58 +volatile bool ConcurrentMarkSweepThread::_should_run = false; 1.59 +// When icms is enabled, the icms thread is stopped until explicitly 1.60 +// started. 1.61 +volatile bool ConcurrentMarkSweepThread::_should_stop = true; 1.62 + 1.63 +SurrogateLockerThread* 1.64 + ConcurrentMarkSweepThread::_slt = NULL; 1.65 +SurrogateLockerThread::SLT_msg_type 1.66 + ConcurrentMarkSweepThread::_sltBuffer = SurrogateLockerThread::empty; 1.67 +Monitor* 1.68 + ConcurrentMarkSweepThread::_sltMonitor = NULL; 1.69 + 1.70 +ConcurrentMarkSweepThread::ConcurrentMarkSweepThread(CMSCollector* collector) 1.71 + : ConcurrentGCThread() { 1.72 + assert(UseConcMarkSweepGC, "UseConcMarkSweepGC should be set"); 1.73 + assert(_cmst == NULL, "CMS thread already created"); 1.74 + _cmst = this; 1.75 + assert(_collector == NULL, "Collector already set"); 1.76 + _collector = collector; 1.77 + 1.78 + set_name("Concurrent Mark-Sweep GC Thread"); 1.79 + 1.80 + if (os::create_thread(this, os::cgc_thread)) { 1.81 + // An old comment here said: "Priority should be just less 1.82 + // than that of VMThread". Since the VMThread runs at 1.83 + // NearMaxPriority, the old comment was inaccurate, but 1.84 + // changing the default priority to NearMaxPriority-1 1.85 + // could change current behavior, so the default of 1.86 + // NearMaxPriority stays in place. 1.87 + // 1.88 + // Note that there's a possibility of the VMThread 1.89 + // starving if UseCriticalCMSThreadPriority is on. 1.90 + // That won't happen on Solaris for various reasons, 1.91 + // but may well happen on non-Solaris platforms. 1.92 + int native_prio; 1.93 + if (UseCriticalCMSThreadPriority) { 1.94 + native_prio = os::java_to_os_priority[CriticalPriority]; 1.95 + } else { 1.96 + native_prio = os::java_to_os_priority[NearMaxPriority]; 1.97 + } 1.98 + os::set_native_priority(this, native_prio); 1.99 + 1.100 + if (!DisableStartThread) { 1.101 + os::start_thread(this); 1.102 + } 1.103 + } 1.104 + _sltMonitor = SLT_lock; 1.105 + assert(!CMSIncrementalMode || icms_is_enabled(), "Error"); 1.106 +} 1.107 + 1.108 +void ConcurrentMarkSweepThread::run() { 1.109 + assert(this == cmst(), "just checking"); 1.110 + 1.111 + this->record_stack_base_and_size(); 1.112 + this->initialize_thread_local_storage(); 1.113 + this->set_active_handles(JNIHandleBlock::allocate_block()); 1.114 + // From this time Thread::current() should be working. 1.115 + assert(this == Thread::current(), "just checking"); 1.116 + if (BindCMSThreadToCPU && !os::bind_to_processor(CPUForCMSThread)) { 1.117 + warning("Couldn't bind CMS thread to processor " UINTX_FORMAT, CPUForCMSThread); 1.118 + } 1.119 + // Wait until Universe::is_fully_initialized() 1.120 + { 1.121 + CMSLoopCountWarn loopX("CMS::run", "waiting for " 1.122 + "Universe::is_fully_initialized()", 2); 1.123 + MutexLockerEx x(CGC_lock, true); 1.124 + set_CMS_flag(CMS_cms_wants_token); 1.125 + // Wait until Universe is initialized and all initialization is completed. 1.126 + while (!is_init_completed() && !Universe::is_fully_initialized() && 1.127 + !_should_terminate) { 1.128 + CGC_lock->wait(true, 200); 1.129 + loopX.tick(); 1.130 + } 1.131 + // Wait until the surrogate locker thread that will do 1.132 + // pending list locking on our behalf has been created. 1.133 + // We cannot start the SLT thread ourselves since we need 1.134 + // to be a JavaThread to do so. 1.135 + CMSLoopCountWarn loopY("CMS::run", "waiting for SLT installation", 2); 1.136 + while (_slt == NULL && !_should_terminate) { 1.137 + CGC_lock->wait(true, 200); 1.138 + loopY.tick(); 1.139 + } 1.140 + clear_CMS_flag(CMS_cms_wants_token); 1.141 + } 1.142 + 1.143 + while (!_should_terminate) { 1.144 + sleepBeforeNextCycle(); 1.145 + if (_should_terminate) break; 1.146 + GCCause::Cause cause = _collector->_full_gc_requested ? 1.147 + _collector->_full_gc_cause : GCCause::_cms_concurrent_mark; 1.148 + _collector->collect_in_background(false, cause); 1.149 + } 1.150 + assert(_should_terminate, "just checking"); 1.151 + // Check that the state of any protocol for synchronization 1.152 + // between background (CMS) and foreground collector is "clean" 1.153 + // (i.e. will not potentially block the foreground collector, 1.154 + // requiring action by us). 1.155 + verify_ok_to_terminate(); 1.156 + // Signal that it is terminated 1.157 + { 1.158 + MutexLockerEx mu(Terminator_lock, 1.159 + Mutex::_no_safepoint_check_flag); 1.160 + assert(_cmst == this, "Weird!"); 1.161 + _cmst = NULL; 1.162 + Terminator_lock->notify(); 1.163 + } 1.164 + 1.165 + // Thread destructor usually does this.. 1.166 + ThreadLocalStorage::set_thread(NULL); 1.167 +} 1.168 + 1.169 +#ifndef PRODUCT 1.170 +void ConcurrentMarkSweepThread::verify_ok_to_terminate() const { 1.171 + assert(!(CGC_lock->owned_by_self() || cms_thread_has_cms_token() || 1.172 + cms_thread_wants_cms_token()), 1.173 + "Must renounce all worldly possessions and desires for nirvana"); 1.174 + _collector->verify_ok_to_terminate(); 1.175 +} 1.176 +#endif 1.177 + 1.178 +// create and start a new ConcurrentMarkSweep Thread for given CMS generation 1.179 +ConcurrentMarkSweepThread* ConcurrentMarkSweepThread::start(CMSCollector* collector) { 1.180 + if (!_should_terminate) { 1.181 + assert(cmst() == NULL, "start() called twice?"); 1.182 + ConcurrentMarkSweepThread* th = new ConcurrentMarkSweepThread(collector); 1.183 + assert(cmst() == th, "Where did the just-created CMS thread go?"); 1.184 + return th; 1.185 + } 1.186 + return NULL; 1.187 +} 1.188 + 1.189 +void ConcurrentMarkSweepThread::stop() { 1.190 + if (CMSIncrementalMode) { 1.191 + // Disable incremental mode and wake up the thread so it notices the change. 1.192 + disable_icms(); 1.193 + start_icms(); 1.194 + } 1.195 + // it is ok to take late safepoints here, if needed 1.196 + { 1.197 + MutexLockerEx x(Terminator_lock); 1.198 + _should_terminate = true; 1.199 + } 1.200 + { // Now post a notify on CGC_lock so as to nudge 1.201 + // CMS thread(s) that might be slumbering in 1.202 + // sleepBeforeNextCycle. 1.203 + MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag); 1.204 + CGC_lock->notify_all(); 1.205 + } 1.206 + { // Now wait until (all) CMS thread(s) have exited 1.207 + MutexLockerEx x(Terminator_lock); 1.208 + while(cmst() != NULL) { 1.209 + Terminator_lock->wait(); 1.210 + } 1.211 + } 1.212 +} 1.213 + 1.214 +void ConcurrentMarkSweepThread::threads_do(ThreadClosure* tc) { 1.215 + assert(tc != NULL, "Null ThreadClosure"); 1.216 + if (_cmst != NULL) { 1.217 + tc->do_thread(_cmst); 1.218 + } 1.219 + assert(Universe::is_fully_initialized(), 1.220 + "Called too early, make sure heap is fully initialized"); 1.221 + if (_collector != NULL) { 1.222 + AbstractWorkGang* gang = _collector->conc_workers(); 1.223 + if (gang != NULL) { 1.224 + gang->threads_do(tc); 1.225 + } 1.226 + } 1.227 +} 1.228 + 1.229 +void ConcurrentMarkSweepThread::print_on(outputStream* st) const { 1.230 + st->print("\"%s\" ", name()); 1.231 + Thread::print_on(st); 1.232 + st->cr(); 1.233 +} 1.234 + 1.235 +void ConcurrentMarkSweepThread::print_all_on(outputStream* st) { 1.236 + if (_cmst != NULL) { 1.237 + _cmst->print_on(st); 1.238 + st->cr(); 1.239 + } 1.240 + if (_collector != NULL) { 1.241 + AbstractWorkGang* gang = _collector->conc_workers(); 1.242 + if (gang != NULL) { 1.243 + gang->print_worker_threads_on(st); 1.244 + } 1.245 + } 1.246 +} 1.247 + 1.248 +void ConcurrentMarkSweepThread::synchronize(bool is_cms_thread) { 1.249 + assert(UseConcMarkSweepGC, "just checking"); 1.250 + 1.251 + MutexLockerEx x(CGC_lock, 1.252 + Mutex::_no_safepoint_check_flag); 1.253 + if (!is_cms_thread) { 1.254 + assert(Thread::current()->is_VM_thread(), "Not a VM thread"); 1.255 + CMSSynchronousYieldRequest yr; 1.256 + while (CMS_flag_is_set(CMS_cms_has_token)) { 1.257 + // indicate that we want to get the token 1.258 + set_CMS_flag(CMS_vm_wants_token); 1.259 + CGC_lock->wait(true); 1.260 + } 1.261 + // claim the token and proceed 1.262 + clear_CMS_flag(CMS_vm_wants_token); 1.263 + set_CMS_flag(CMS_vm_has_token); 1.264 + } else { 1.265 + assert(Thread::current()->is_ConcurrentGC_thread(), 1.266 + "Not a CMS thread"); 1.267 + // The following barrier assumes there's only one CMS thread. 1.268 + // This will need to be modified is there are more CMS threads than one. 1.269 + while (CMS_flag_is_set(CMS_vm_has_token | CMS_vm_wants_token)) { 1.270 + set_CMS_flag(CMS_cms_wants_token); 1.271 + CGC_lock->wait(true); 1.272 + } 1.273 + // claim the token 1.274 + clear_CMS_flag(CMS_cms_wants_token); 1.275 + set_CMS_flag(CMS_cms_has_token); 1.276 + } 1.277 +} 1.278 + 1.279 +void ConcurrentMarkSweepThread::desynchronize(bool is_cms_thread) { 1.280 + assert(UseConcMarkSweepGC, "just checking"); 1.281 + 1.282 + MutexLockerEx x(CGC_lock, 1.283 + Mutex::_no_safepoint_check_flag); 1.284 + if (!is_cms_thread) { 1.285 + assert(Thread::current()->is_VM_thread(), "Not a VM thread"); 1.286 + assert(CMS_flag_is_set(CMS_vm_has_token), "just checking"); 1.287 + clear_CMS_flag(CMS_vm_has_token); 1.288 + if (CMS_flag_is_set(CMS_cms_wants_token)) { 1.289 + // wake-up a waiting CMS thread 1.290 + CGC_lock->notify(); 1.291 + } 1.292 + assert(!CMS_flag_is_set(CMS_vm_has_token | CMS_vm_wants_token), 1.293 + "Should have been cleared"); 1.294 + } else { 1.295 + assert(Thread::current()->is_ConcurrentGC_thread(), 1.296 + "Not a CMS thread"); 1.297 + assert(CMS_flag_is_set(CMS_cms_has_token), "just checking"); 1.298 + clear_CMS_flag(CMS_cms_has_token); 1.299 + if (CMS_flag_is_set(CMS_vm_wants_token)) { 1.300 + // wake-up a waiting VM thread 1.301 + CGC_lock->notify(); 1.302 + } 1.303 + assert(!CMS_flag_is_set(CMS_cms_has_token | CMS_cms_wants_token), 1.304 + "Should have been cleared"); 1.305 + } 1.306 +} 1.307 + 1.308 +// Wait until any cms_lock event 1.309 +void ConcurrentMarkSweepThread::wait_on_cms_lock(long t_millis) { 1.310 + MutexLockerEx x(CGC_lock, 1.311 + Mutex::_no_safepoint_check_flag); 1.312 + if (_should_terminate || _collector->_full_gc_requested) { 1.313 + return; 1.314 + } 1.315 + set_CMS_flag(CMS_cms_wants_token); // to provoke notifies 1.316 + CGC_lock->wait(Mutex::_no_safepoint_check_flag, t_millis); 1.317 + clear_CMS_flag(CMS_cms_wants_token); 1.318 + assert(!CMS_flag_is_set(CMS_cms_has_token | CMS_cms_wants_token), 1.319 + "Should not be set"); 1.320 +} 1.321 + 1.322 +// Wait until the next synchronous GC, a concurrent full gc request, 1.323 +// or a timeout, whichever is earlier. 1.324 +void ConcurrentMarkSweepThread::wait_on_cms_lock_for_scavenge(long t_millis) { 1.325 + // Wait time in millis or 0 value representing infinite wait for a scavenge 1.326 + assert(t_millis >= 0, "Wait time for scavenge should be 0 or positive"); 1.327 + 1.328 + GenCollectedHeap* gch = GenCollectedHeap::heap(); 1.329 + double start_time_secs = os::elapsedTime(); 1.330 + double end_time_secs = start_time_secs + (t_millis / ((double) MILLIUNITS)); 1.331 + 1.332 + // Total collections count before waiting loop 1.333 + unsigned int before_count; 1.334 + { 1.335 + MutexLockerEx hl(Heap_lock, Mutex::_no_safepoint_check_flag); 1.336 + before_count = gch->total_collections(); 1.337 + } 1.338 + 1.339 + unsigned int loop_count = 0; 1.340 + 1.341 + while(!_should_terminate) { 1.342 + double now_time = os::elapsedTime(); 1.343 + long wait_time_millis; 1.344 + 1.345 + if(t_millis != 0) { 1.346 + // New wait limit 1.347 + wait_time_millis = (long) ((end_time_secs - now_time) * MILLIUNITS); 1.348 + if(wait_time_millis <= 0) { 1.349 + // Wait time is over 1.350 + break; 1.351 + } 1.352 + } else { 1.353 + // No wait limit, wait if necessary forever 1.354 + wait_time_millis = 0; 1.355 + } 1.356 + 1.357 + // Wait until the next event or the remaining timeout 1.358 + { 1.359 + MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag); 1.360 + 1.361 + if (_should_terminate || _collector->_full_gc_requested) { 1.362 + return; 1.363 + } 1.364 + set_CMS_flag(CMS_cms_wants_token); // to provoke notifies 1.365 + assert(t_millis == 0 || wait_time_millis > 0, "Sanity"); 1.366 + CGC_lock->wait(Mutex::_no_safepoint_check_flag, wait_time_millis); 1.367 + clear_CMS_flag(CMS_cms_wants_token); 1.368 + assert(!CMS_flag_is_set(CMS_cms_has_token | CMS_cms_wants_token), 1.369 + "Should not be set"); 1.370 + } 1.371 + 1.372 + // Extra wait time check before entering the heap lock to get the collection count 1.373 + if(t_millis != 0 && os::elapsedTime() >= end_time_secs) { 1.374 + // Wait time is over 1.375 + break; 1.376 + } 1.377 + 1.378 + // Total collections count after the event 1.379 + unsigned int after_count; 1.380 + { 1.381 + MutexLockerEx hl(Heap_lock, Mutex::_no_safepoint_check_flag); 1.382 + after_count = gch->total_collections(); 1.383 + } 1.384 + 1.385 + if(before_count != after_count) { 1.386 + // There was a collection - success 1.387 + break; 1.388 + } 1.389 + 1.390 + // Too many loops warning 1.391 + if(++loop_count == 0) { 1.392 + warning("wait_on_cms_lock_for_scavenge() has looped %u times", loop_count - 1); 1.393 + } 1.394 + } 1.395 +} 1.396 + 1.397 +void ConcurrentMarkSweepThread::sleepBeforeNextCycle() { 1.398 + while (!_should_terminate) { 1.399 + if (CMSIncrementalMode) { 1.400 + icms_wait(); 1.401 + if(CMSWaitDuration >= 0) { 1.402 + // Wait until the next synchronous GC, a concurrent full gc 1.403 + // request or a timeout, whichever is earlier. 1.404 + wait_on_cms_lock_for_scavenge(CMSWaitDuration); 1.405 + } 1.406 + return; 1.407 + } else { 1.408 + if(CMSWaitDuration >= 0) { 1.409 + // Wait until the next synchronous GC, a concurrent full gc 1.410 + // request or a timeout, whichever is earlier. 1.411 + wait_on_cms_lock_for_scavenge(CMSWaitDuration); 1.412 + } else { 1.413 + // Wait until any cms_lock event or check interval not to call shouldConcurrentCollect permanently 1.414 + wait_on_cms_lock(CMSCheckInterval); 1.415 + } 1.416 + } 1.417 + // Check if we should start a CMS collection cycle 1.418 + if (_collector->shouldConcurrentCollect()) { 1.419 + return; 1.420 + } 1.421 + // .. collection criterion not yet met, let's go back 1.422 + // and wait some more 1.423 + } 1.424 +} 1.425 + 1.426 +// Incremental CMS 1.427 +void ConcurrentMarkSweepThread::start_icms() { 1.428 + assert(UseConcMarkSweepGC && CMSIncrementalMode, "just checking"); 1.429 + MutexLockerEx x(iCMS_lock, Mutex::_no_safepoint_check_flag); 1.430 + trace_state("start_icms"); 1.431 + _should_run = true; 1.432 + iCMS_lock->notify_all(); 1.433 +} 1.434 + 1.435 +void ConcurrentMarkSweepThread::stop_icms() { 1.436 + assert(UseConcMarkSweepGC && CMSIncrementalMode, "just checking"); 1.437 + MutexLockerEx x(iCMS_lock, Mutex::_no_safepoint_check_flag); 1.438 + if (!_should_stop) { 1.439 + trace_state("stop_icms"); 1.440 + _should_stop = true; 1.441 + _should_run = false; 1.442 + asynchronous_yield_request(); 1.443 + iCMS_lock->notify_all(); 1.444 + } 1.445 +} 1.446 + 1.447 +void ConcurrentMarkSweepThread::icms_wait() { 1.448 + assert(UseConcMarkSweepGC && CMSIncrementalMode, "just checking"); 1.449 + if (_should_stop && icms_is_enabled()) { 1.450 + MutexLockerEx x(iCMS_lock, Mutex::_no_safepoint_check_flag); 1.451 + trace_state("pause_icms"); 1.452 + _collector->stats().stop_cms_timer(); 1.453 + while(!_should_run && icms_is_enabled()) { 1.454 + iCMS_lock->wait(Mutex::_no_safepoint_check_flag); 1.455 + } 1.456 + _collector->stats().start_cms_timer(); 1.457 + _should_stop = false; 1.458 + trace_state("pause_icms end"); 1.459 + } 1.460 +} 1.461 + 1.462 +// Note: this method, although exported by the ConcurrentMarkSweepThread, 1.463 +// which is a non-JavaThread, can only be called by a JavaThread. 1.464 +// Currently this is done at vm creation time (post-vm-init) by the 1.465 +// main/Primordial (Java)Thread. 1.466 +// XXX Consider changing this in the future to allow the CMS thread 1.467 +// itself to create this thread? 1.468 +void ConcurrentMarkSweepThread::makeSurrogateLockerThread(TRAPS) { 1.469 + assert(UseConcMarkSweepGC, "SLT thread needed only for CMS GC"); 1.470 + assert(_slt == NULL, "SLT already created"); 1.471 + _slt = SurrogateLockerThread::make(THREAD); 1.472 +}