8221392: Reduce ConcurrentGCThreads spinning during start up

Reviewed-by: eosterlund, kbarrett
This commit is contained in:
Per Lidén 2019-03-27 10:38:49 +01:00
parent 229d923b27
commit 8e258756bb
5 changed files with 17 additions and 11 deletions

@ -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 @@ void ConcurrentGCThread::initialize_in_thread() {
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::terminate() {
void ConcurrentGCThread::run() {
initialize_in_thread();
wait_for_universe_init();
wait_init_completed();
run_service();

@ -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 @@ void exit_globals() {
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();
}

@ -40,6 +40,7 @@ void vm_init_globals(); // call constructors at startup (VM thread)
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

@ -97,6 +97,7 @@ Mutex* CompileStatistics_lock = NULL;
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 @@ void mutex_init() {
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);

@ -96,6 +96,7 @@ extern Mutex* CompileStatistics_lock; // a lock held when updating co
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