# HG changeset patch # User pliden # Date 1553679529 -3600 # Node ID 2f522c487791649ce343fc6d45599dbfbe0527f0 # Parent 1b85f55c9aa22c6474e385fa397533c8cc2f13b6 8221392: Reduce ConcurrentGCThreads spinning during start up Reviewed-by: eosterlund, kbarrett diff -r 1b85f55c9aa2 -r 2f522c487791 src/hotspot/share/gc/shared/concurrentGCThread.cpp --- a/src/hotspot/share/gc/shared/concurrentGCThread.cpp Wed Mar 27 10:38:49 2019 +0100 +++ b/src/hotspot/share/gc/shared/concurrentGCThread.cpp Wed Mar 27 10:38:49 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2019, 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 @@ -54,13 +54,6 @@ assert(this == Thread::current(), "just checking"); } -void ConcurrentGCThread::wait_for_universe_init() { - MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag); - while (!is_init_completed() && !_should_terminate) { - CGC_lock->wait(Mutex::_no_safepoint_check_flag, 1); - } -} - void ConcurrentGCThread::terminate() { assert(_should_terminate, "Should only be called on terminate request."); // Signal that it is terminated @@ -74,7 +67,7 @@ void ConcurrentGCThread::run() { initialize_in_thread(); - wait_for_universe_init(); + wait_init_completed(); run_service(); diff -r 1b85f55c9aa2 -r 2f522c487791 src/hotspot/share/runtime/init.cpp --- a/src/hotspot/share/runtime/init.cpp Wed Mar 27 10:38:49 2019 +0100 +++ b/src/hotspot/share/runtime/init.cpp Wed Mar 27 10:38:49 2019 +0100 @@ -36,6 +36,7 @@ #include "runtime/handles.inline.hpp" #include "runtime/icache.hpp" #include "runtime/init.hpp" +#include "runtime/orderAccess.hpp" #include "runtime/safepoint.hpp" #include "runtime/sharedRuntime.hpp" #include "services/memTracker.hpp" @@ -186,11 +187,19 @@ static volatile bool _init_completed = false; bool is_init_completed() { - return _init_completed; + return OrderAccess::load_acquire(&_init_completed); } +void wait_init_completed() { + MonitorLockerEx ml(InitCompleted_lock, Monitor::_no_safepoint_check_flag); + while (!_init_completed) { + ml.wait(Monitor::_no_safepoint_check_flag); + } +} void set_init_completed() { assert(Universe::is_fully_initialized(), "Should have completed initialization"); - _init_completed = true; + MonitorLockerEx ml(InitCompleted_lock, Monitor::_no_safepoint_check_flag); + OrderAccess::release_store(&_init_completed, true); + ml.notify_all(); } diff -r 1b85f55c9aa2 -r 2f522c487791 src/hotspot/share/runtime/init.hpp --- a/src/hotspot/share/runtime/init.hpp Wed Mar 27 10:38:49 2019 +0100 +++ b/src/hotspot/share/runtime/init.hpp Wed Mar 27 10:38:49 2019 +0100 @@ -40,6 +40,7 @@ void exit_globals(); // call destructors before exit bool is_init_completed(); // returns true when bootstrapping has completed +void wait_init_completed(); // wait until set_init_completed() has been called void set_init_completed(); // set basic init to completed #endif // SHARE_RUNTIME_INIT_HPP diff -r 1b85f55c9aa2 -r 2f522c487791 src/hotspot/share/runtime/mutexLocker.cpp --- a/src/hotspot/share/runtime/mutexLocker.cpp Wed Mar 27 10:38:49 2019 +0100 +++ b/src/hotspot/share/runtime/mutexLocker.cpp Wed Mar 27 10:38:49 2019 +0100 @@ -97,6 +97,7 @@ Mutex* DirectivesStack_lock = NULL; Mutex* MultiArray_lock = NULL; Monitor* Terminator_lock = NULL; +Monitor* InitCompleted_lock = NULL; Monitor* BeforeExit_lock = NULL; Monitor* Notify_lock = NULL; Mutex* ProfilePrint_lock = NULL; @@ -283,6 +284,7 @@ def(VMOperationRequest_lock , PaddedMonitor, nonleaf, true, Monitor::_safepoint_check_sometimes); def(RetData_lock , PaddedMutex , nonleaf, false, Monitor::_safepoint_check_always); def(Terminator_lock , PaddedMonitor, nonleaf, true, Monitor::_safepoint_check_sometimes); + def(InitCompleted_lock , PaddedMonitor, leaf, true, Monitor::_safepoint_check_never); def(VtableStubs_lock , PaddedMutex , nonleaf, true, Monitor::_safepoint_check_never); def(Notify_lock , PaddedMonitor, nonleaf, true, Monitor::_safepoint_check_always); def(JNIGlobalAlloc_lock , PaddedMutex , nonleaf, true, Monitor::_safepoint_check_never); diff -r 1b85f55c9aa2 -r 2f522c487791 src/hotspot/share/runtime/mutexLocker.hpp --- a/src/hotspot/share/runtime/mutexLocker.hpp Wed Mar 27 10:38:49 2019 +0100 +++ b/src/hotspot/share/runtime/mutexLocker.hpp Wed Mar 27 10:38:49 2019 +0100 @@ -96,6 +96,7 @@ extern Mutex* DirectivesStack_lock; // a lock held when mutating the dirstack and ref counting directives extern Mutex* MultiArray_lock; // a lock used to guard allocation of multi-dim arrays extern Monitor* Terminator_lock; // a lock used to guard termination of the vm +extern Monitor* InitCompleted_lock; // a lock used to signal threads waiting on init completed extern Monitor* BeforeExit_lock; // a lock used to guard cleanups and shutdown hooks extern Monitor* Notify_lock; // a lock used to synchronize the start-up of the vm extern Mutex* ProfilePrint_lock; // a lock used to serialize the printing of profiles