8221392: Reduce ConcurrentGCThreads spinning during start up
authorpliden
Wed, 27 Mar 2019 10:38:49 +0100
changeset 54301 2f522c487791
parent 54300 1b85f55c9aa2
child 54302 0a2d73e02076
8221392: Reduce ConcurrentGCThreads spinning during start up Reviewed-by: eosterlund, kbarrett
src/hotspot/share/gc/shared/concurrentGCThread.cpp
src/hotspot/share/runtime/init.cpp
src/hotspot/share/runtime/init.hpp
src/hotspot/share/runtime/mutexLocker.cpp
src/hotspot/share/runtime/mutexLocker.hpp
--- 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();
 
--- 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();
 }
--- 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
--- 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);
--- 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