--- old/src/hotspot/share/gc/shared/concurrentGCThread.cpp 2019-03-25 10:50:16.704623214 +0100 +++ new/src/hotspot/share/gc/shared/concurrentGCThread.cpp 2019-03-25 10:50:16.487616222 +0100 @@ -23,72 +23,59 @@ */ #include "precompiled.hpp" -#include "classfile/systemDictionary.hpp" #include "gc/shared/concurrentGCThread.hpp" -#include "oops/instanceRefKlass.hpp" -#include "oops/oop.inline.hpp" #include "runtime/init.hpp" -#include "runtime/java.hpp" -#include "runtime/javaCalls.hpp" +#include "runtime/mutexLocker.hpp" +#include "runtime/orderAccess.hpp" #include "runtime/os.hpp" ConcurrentGCThread::ConcurrentGCThread() : - _should_terminate(false), _has_terminated(false) { -}; + _monitor(Monitor::leaf, "ConcurrentGCThread"), + _should_terminate(false), + _has_terminated(false) {} void ConcurrentGCThread::create_and_start(ThreadPriority prio) { if (os::create_thread(this, os::cgc_thread)) { - // XXX: need to set this to low priority - // unless "aggressive mode" set; priority - // should be just less than that of VMThread. os::set_priority(this, prio); - if (!_should_terminate) { - os::start_thread(this); - } - } -} - -void ConcurrentGCThread::initialize_in_thread() { - this->set_active_handles(JNIHandleBlock::allocate_block()); - // From this time Thread::current() should be working. - assert(this == Thread::current(), "just checking"); -} - -void ConcurrentGCThread::terminate() { - assert(_should_terminate, "Should only be called on terminate request."); - // Signal that it is terminated - { - MutexLockerEx mu(Terminator_lock, - Mutex::_no_safepoint_check_flag); - _has_terminated = true; - Terminator_lock->notify(); + os::start_thread(this); } } void ConcurrentGCThread::run() { - initialize_in_thread(); + // Setup handle area + set_active_handles(JNIHandleBlock::allocate_block()); + + // Wait for initialization to complete wait_init_completed(); run_service(); - terminate(); + // Signal thread has terminated + MonitorLockerEx ml(&_monitor); + OrderAccess::release_store(&_has_terminated, true); + ml.notify_all(); } void ConcurrentGCThread::stop() { - // it is ok to take late safepoints here, if needed - { - MutexLockerEx mu(Terminator_lock); - assert(!_has_terminated, "stop should only be called once"); - assert(!_should_terminate, "stop should only be called once"); - _should_terminate = true; - } + assert(!should_terminate(), "Invalid state"); + assert(!has_terminated(), "Invalid state"); + + // Signal thread to terminate + OrderAccess::release_store(&_should_terminate, true); stop_service(); - { - MutexLockerEx mu(Terminator_lock); - while (!_has_terminated) { - Terminator_lock->wait(); - } + // Wait for thread to terminate + MonitorLockerEx ml(&_monitor); + while (!_has_terminated) { + ml.wait(); } } + +bool ConcurrentGCThread::should_terminate() { + return OrderAccess::load_acquire(&_should_terminate); +} + +bool ConcurrentGCThread::has_terminated() { + return OrderAccess::load_acquire(&_has_terminated); +}