< prev index next >

src/share/vm/gc/cms/concurrentMarkSweepThread.cpp

Print this page
rev 10389 : imported patch webrev.01
rev 10390 : imported patch webrev.02
rev 10391 : [mq]: webrev.03
rev 10392 : imported patch webrev.04
rev 10393 : [mq]: web.05

*** 1,7 **** /* ! * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. --- 1,7 ---- /* ! * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.
*** 40,50 **** // ======= Concurrent Mark Sweep Thread ======== ConcurrentMarkSweepThread* ConcurrentMarkSweepThread::_cmst = NULL; CMSCollector* ConcurrentMarkSweepThread::_collector = NULL; - bool ConcurrentMarkSweepThread::_should_terminate = false; int ConcurrentMarkSweepThread::_CMS_flag = CMS_nil; volatile jint ConcurrentMarkSweepThread::_pending_yields = 0; SurrogateLockerThread* ConcurrentMarkSweepThread::_slt = NULL; --- 40,49 ----
*** 60,70 **** assert(_collector == NULL, "Collector already set"); _collector = collector; set_name("CMS Main Thread"); - if (os::create_thread(this, os::cgc_thread)) { // An old comment here said: "Priority should be just less // than that of VMThread". Since the VMThread runs at // NearMaxPriority, the old comment was inaccurate, but // changing the default priority to NearMaxPriority-1 // could change current behavior, so the default of --- 59,68 ----
*** 72,151 **** // // Note that there's a possibility of the VMThread // starving if UseCriticalCMSThreadPriority is on. // That won't happen on Solaris for various reasons, // but may well happen on non-Solaris platforms. ! int native_prio; ! if (UseCriticalCMSThreadPriority) { ! native_prio = os::java_to_os_priority[CriticalPriority]; ! } else { ! native_prio = os::java_to_os_priority[NearMaxPriority]; ! } ! os::set_native_priority(this, native_prio); - if (!DisableStartThread) { - os::start_thread(this); - } - } _sltMonitor = SLT_lock; } ! void ConcurrentMarkSweepThread::run() { assert(this == cmst(), "just checking"); - initialize_in_thread(); - // 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 " UINTX_FORMAT, 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; GCIdMark gc_id_mark; GCCause::Cause cause = _collector->_full_gc_requested ? _collector->_full_gc_cause : GCCause::_cms_concurrent_mark; _collector->collect_in_background(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(); - } } #ifndef PRODUCT void ConcurrentMarkSweepThread::verify_ok_to_terminate() const { assert(!(CGC_lock->owned_by_self() || cms_thread_has_cms_token() || --- 70,122 ---- // // Note that there's a possibility of the VMThread // starving if UseCriticalCMSThreadPriority is on. // That won't happen on Solaris for various reasons, // but may well happen on non-Solaris platforms. ! create_and_start(UseCriticalCMSThreadPriority ? CriticalPriority : NearMaxPriority); _sltMonitor = SLT_lock; } ! void ConcurrentMarkSweepThread::run_service() { assert(this == cmst(), "just checking"); if (BindCMSThreadToCPU && !os::bind_to_processor(CPUForCMSThread)) { warning("Couldn't bind CMS thread to processor " UINTX_FORMAT, CPUForCMSThread); } ! { MutexLockerEx x(CGC_lock, true); set_CMS_flag(CMS_cms_wants_token); ! assert(is_init_completed() && Universe::is_fully_initialized(), "ConcurrentGCThread::run() should have waited for this."); ! // 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; GCIdMark gc_id_mark; GCCause::Cause cause = _collector->_full_gc_requested ? _collector->_full_gc_cause : GCCause::_cms_concurrent_mark; _collector->collect_in_background(cause); } ! // 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(); } #ifndef PRODUCT void ConcurrentMarkSweepThread::verify_ok_to_terminate() const { assert(!(CGC_lock->owned_by_self() || cms_thread_has_cms_token() ||
*** 155,197 **** } #endif // 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::stop() { ! // 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(); - } - } } void ConcurrentMarkSweepThread::threads_do(ThreadClosure* tc) { assert(tc != NULL, "Null ThreadClosure"); ! if (_cmst != NULL) { ! tc->do_thread(_cmst); } assert(Universe::is_fully_initialized(), "Called too early, make sure heap is fully initialized"); if (_collector != NULL) { AbstractWorkGang* gang = _collector->conc_workers(); --- 126,153 ---- } #endif // create and start a new ConcurrentMarkSweep Thread for given CMS generation ConcurrentMarkSweepThread* ConcurrentMarkSweepThread::start(CMSCollector* collector) { ! guarantee(_cmst == NULL, "start() called twice!"); ConcurrentMarkSweepThread* th = new ConcurrentMarkSweepThread(collector); ! assert(_cmst == th, "Where did the just-created CMS thread go?"); return th; } ! void ConcurrentMarkSweepThread::stop_service() { ! // 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(); } void ConcurrentMarkSweepThread::threads_do(ThreadClosure* tc) { assert(tc != NULL, "Null ThreadClosure"); ! if (cmst() != NULL && !cmst()->has_terminated()) { ! tc->do_thread(cmst()); } assert(Universe::is_fully_initialized(), "Called too early, make sure heap is fully initialized"); if (_collector != NULL) { AbstractWorkGang* gang = _collector->conc_workers();
*** 200,211 **** } } } void ConcurrentMarkSweepThread::print_all_on(outputStream* st) { ! if (_cmst != NULL) { ! _cmst->print_on(st); st->cr(); } if (_collector != NULL) { AbstractWorkGang* gang = _collector->conc_workers(); if (gang != NULL) { --- 156,167 ---- } } } void ConcurrentMarkSweepThread::print_all_on(outputStream* st) { ! if (cmst() != NULL && !cmst()->has_terminated()) { ! cmst()->print_on(st); st->cr(); } if (_collector != NULL) { AbstractWorkGang* gang = _collector->conc_workers(); if (gang != NULL) {
*** 276,286 **** // Wait until any cms_lock event void ConcurrentMarkSweepThread::wait_on_cms_lock(long t_millis) { MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag); ! if (_should_terminate || _collector->_full_gc_requested) { return; } set_CMS_flag(CMS_cms_wants_token); // to provoke notifies CGC_lock->wait(Mutex::_no_safepoint_check_flag, t_millis); clear_CMS_flag(CMS_cms_wants_token); --- 232,242 ---- // Wait until any cms_lock event void ConcurrentMarkSweepThread::wait_on_cms_lock(long t_millis) { MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag); ! if (should_terminate() || _collector->_full_gc_requested) { return; } set_CMS_flag(CMS_cms_wants_token); // to provoke notifies CGC_lock->wait(Mutex::_no_safepoint_check_flag, t_millis); clear_CMS_flag(CMS_cms_wants_token);
*** 305,315 **** before_count = gch->total_collections(); } unsigned int loop_count = 0; ! while(!_should_terminate) { double now_time = os::elapsedTime(); long wait_time_millis; if(t_millis != 0) { // New wait limit --- 261,271 ---- before_count = gch->total_collections(); } unsigned int loop_count = 0; ! while(!should_terminate()) { double now_time = os::elapsedTime(); long wait_time_millis; if(t_millis != 0) { // New wait limit
*** 325,335 **** // Wait until the next event or the remaining timeout { MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag); ! if (_should_terminate || _collector->_full_gc_requested) { return; } set_CMS_flag(CMS_cms_wants_token); // to provoke notifies assert(t_millis == 0 || wait_time_millis > 0, "Sanity"); CGC_lock->wait(Mutex::_no_safepoint_check_flag, wait_time_millis); --- 281,291 ---- // Wait until the next event or the remaining timeout { MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag); ! if (should_terminate() || _collector->_full_gc_requested) { return; } set_CMS_flag(CMS_cms_wants_token); // to provoke notifies assert(t_millis == 0 || wait_time_millis > 0, "Sanity"); CGC_lock->wait(Mutex::_no_safepoint_check_flag, wait_time_millis);
*** 362,372 **** } } } void ConcurrentMarkSweepThread::sleepBeforeNextCycle() { ! while (!_should_terminate) { if(CMSWaitDuration >= 0) { // Wait until the next synchronous GC, a concurrent full gc // request or a timeout, whichever is earlier. wait_on_cms_lock_for_scavenge(CMSWaitDuration); } else { --- 318,328 ---- } } } void ConcurrentMarkSweepThread::sleepBeforeNextCycle() { ! while (!should_terminate()) { if(CMSWaitDuration >= 0) { // Wait until the next synchronous GC, a concurrent full gc // request or a timeout, whichever is earlier. wait_on_cms_lock_for_scavenge(CMSWaitDuration); } else {
< prev index next >