// create and start a new ConcurrentMarkSweep Thread for given CMS generation ConcurrentMarkSweepThread* ConcurrentMarkSweepThread::start(CMSCollector* collector) { if (!_should_terminate) { assert(cmst() == NULL, "start() called twice?"); ConcurrentMarkSweepThread* th = new ConcurrentMarkSweepThread(collector); assert(cmst() == th, "Where did the just-created CMS thread go?"); return th; } return NULL; }
void ConcurrentMarkSweepThread::run() { assert(this == cmst(), "just checking"); this->record_stack_base_and_size(); this->initialize_thread_local_storage(); this->set_active_handles(JNIHandleBlock::allocate_block()); // From this time Thread::current() should be working. assert(this == Thread::current(), "just checking"); if (BindCMSThreadToCPU && !os::bind_to_processor(CPUForCMSThread)) { warning("Couldn't bind CMS thread to processor %u", CPUForCMSThread); } // Wait until Universe::is_fully_initialized() { CMSLoopCountWarn loopX("CMS::run", "waiting for " "Universe::is_fully_initialized()", 2); MutexLockerEx x(CGC_lock, true); set_CMS_flag(CMS_cms_wants_token); // Wait until Universe is initialized and all initialization is completed. while (!is_init_completed() && !Universe::is_fully_initialized() && !_should_terminate) { CGC_lock->wait(true, 200); loopX.tick(); } // Wait until the surrogate locker thread that will do // pending list locking on our behalf has been created. // We cannot start the SLT thread ourselves since we need // to be a JavaThread to do so. CMSLoopCountWarn loopY("CMS::run", "waiting for SLT installation", 2); while (_slt == NULL && !_should_terminate) { CGC_lock->wait(true, 200); loopY.tick(); } clear_CMS_flag(CMS_cms_wants_token); } while (!_should_terminate) { sleepBeforeNextCycle(); if (_should_terminate) break; GCCause::Cause cause = _collector->_full_gc_requested ? _collector->_full_gc_cause : GCCause::_cms_concurrent_mark; _collector->collect_in_background(false, cause); } assert(_should_terminate, "just checking"); // Check that the state of any protocol for synchronization // between background (CMS) and foreground collector is "clean" // (i.e. will not potentially block the foreground collector, // requiring action by us). verify_ok_to_terminate(); // Signal that it is terminated { MutexLockerEx mu(Terminator_lock, Mutex::_no_safepoint_check_flag); assert(_cmst == this, "Weird!"); _cmst = NULL; Terminator_lock->notify(); } // Thread destructor usually does this.. ThreadLocalStorage::set_thread(NULL); }
void ConcurrentMarkSweepThread::stop() { if (CMSIncrementalMode) { // Disable incremental mode and wake up the thread so it notices the change. disable_icms(); start_icms(); } // it is ok to take late safepoints here, if needed { MutexLockerEx x(Terminator_lock); _should_terminate = true; } { // Now post a notify on CGC_lock so as to nudge // CMS thread(s) that might be slumbering in // sleepBeforeNextCycle. MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag); CGC_lock->notify_all(); } { // Now wait until (all) CMS thread(s) have exited MutexLockerEx x(Terminator_lock); while(cmst() != NULL) { Terminator_lock->wait(); } } }