8340547: Starting many threads can delay safepoints
Reviewed-by: shade, qamai, dholmes
This commit is contained in:
parent
c30ad0124e
commit
e704c055a4
@ -2948,9 +2948,10 @@ JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread))
|
||||
// We must release the Threads_lock before we can post a jvmti event
|
||||
// in Thread::start.
|
||||
{
|
||||
ConditionalMutexLocker throttle_ml(ThreadsLockThrottle_lock, UseThreadsLockThrottleLock);
|
||||
// Ensure that the C++ Thread and OSThread structures aren't freed before
|
||||
// we operate.
|
||||
MutexLocker mu(Threads_lock);
|
||||
MutexLocker ml(Threads_lock);
|
||||
|
||||
// Since JDK 5 the java.lang.Thread threadStatus is used to prevent
|
||||
// re-starting an already started thread, so we should usually find
|
||||
|
@ -1991,6 +1991,10 @@ const int ObjectAlignmentInBytes = 8;
|
||||
\
|
||||
product(bool, StressSecondarySupers, false, DIAGNOSTIC, \
|
||||
"Use a terrible hash function in order to generate many collisions.") \
|
||||
\
|
||||
product(bool, UseThreadsLockThrottleLock, true, DIAGNOSTIC, \
|
||||
"Use an extra lock during Thread start and exit to alleviate" \
|
||||
"contention on Threads_lock.") \
|
||||
|
||||
// end of RUNTIME_FLAGS
|
||||
|
||||
|
@ -66,6 +66,7 @@ Monitor* CodeCache_lock = nullptr;
|
||||
Mutex* TouchedMethodLog_lock = nullptr;
|
||||
Mutex* RetData_lock = nullptr;
|
||||
Monitor* VMOperation_lock = nullptr;
|
||||
Monitor* ThreadsLockThrottle_lock = nullptr;
|
||||
Monitor* Threads_lock = nullptr;
|
||||
Mutex* NonJavaThreadsList_lock = nullptr;
|
||||
Mutex* NonJavaThreadsListSync_lock = nullptr;
|
||||
@ -317,6 +318,8 @@ void mutex_init() {
|
||||
MUTEX_DEFN(JVMCIRuntime_lock , PaddedMonitor, safepoint, true);
|
||||
#endif
|
||||
|
||||
MUTEX_DEFN(ThreadsLockThrottle_lock , PaddedMonitor, safepoint);
|
||||
|
||||
// These locks have relative rankings, and inherit safepoint checking attributes from that rank.
|
||||
MUTEX_DEFL(VtableStubs_lock , PaddedMutex , CompiledIC_lock); // Also holds DumpTimeTable_lock
|
||||
MUTEX_DEFL(CodeCache_lock , PaddedMonitor, VtableStubs_lock);
|
||||
|
@ -61,6 +61,8 @@ extern Monitor* CodeCache_lock; // a lock on the CodeCache
|
||||
extern Mutex* TouchedMethodLog_lock; // a lock on allocation of LogExecutedMethods info
|
||||
extern Mutex* RetData_lock; // a lock on installation of RetData inside method data
|
||||
extern Monitor* VMOperation_lock; // a lock on queue of vm_operations waiting to execute
|
||||
extern Monitor* ThreadsLockThrottle_lock; // used by Thread start/exit to reduce competition for Threads_lock,
|
||||
// so a VM thread calling a safepoint is prioritized
|
||||
extern Monitor* Threads_lock; // a lock on the Threads table of active Java threads
|
||||
// (also used by Safepoints too to block threads creation/destruction)
|
||||
extern Mutex* NonJavaThreadsList_lock; // a lock on the NonJavaThreads list
|
||||
|
@ -1028,7 +1028,9 @@ void Threads::add(JavaThread* p, bool force_daemon) {
|
||||
void Threads::remove(JavaThread* p, bool is_daemon) {
|
||||
// Extra scope needed for Thread_lock, so we can check
|
||||
// that we do not remove thread without safepoint code notice
|
||||
{ MonitorLocker ml(Threads_lock);
|
||||
{
|
||||
ConditionalMutexLocker throttle_ml(ThreadsLockThrottle_lock, UseThreadsLockThrottleLock);
|
||||
MonitorLocker ml(Threads_lock);
|
||||
|
||||
if (ThreadIdTable::is_initialized()) {
|
||||
// This cleanup must be done before the current thread's GC barrier
|
||||
@ -1076,7 +1078,7 @@ void Threads::remove(JavaThread* p, bool is_daemon) {
|
||||
|
||||
// Notify threads waiting in EscapeBarriers
|
||||
EscapeBarrier::thread_removed(p);
|
||||
} // unlock Threads_lock
|
||||
} // unlock Threads_lock and ThreadsLockThrottle_lock
|
||||
|
||||
// Reduce the ObjectMonitor ceiling for the exiting thread.
|
||||
ObjectSynchronizer::dec_in_use_list_ceiling();
|
||||
|
Loading…
Reference in New Issue
Block a user