From 4d0da18ab6e83549e81074e15011cf8a4fbd4ea9 Mon Sep 17 00:00:00 2001 From: David Holmes Date: Wed, 8 Oct 2025 20:28:21 +0000 Subject: [PATCH] 8369250: Assess and remedy any unsafe usage of the Semaphore used by NonJavaThread::List Reviewed-by: kbarrett, stefank --- src/hotspot/share/runtime/nonJavaThread.cpp | 21 ++++++++++++--------- src/hotspot/share/runtime/nonJavaThread.hpp | 12 +++++++++--- src/hotspot/share/runtime/threads.cpp | 3 +++ 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/hotspot/share/runtime/nonJavaThread.cpp b/src/hotspot/share/runtime/nonJavaThread.cpp index 2fb4c2dce02..cb0c3f8910d 100644 --- a/src/hotspot/share/runtime/nonJavaThread.cpp +++ b/src/hotspot/share/runtime/nonJavaThread.cpp @@ -50,15 +50,19 @@ public: List() : _head(nullptr), _protect() {} }; -NonJavaThread::List NonJavaThread::_the_list; +DeferredStatic NonJavaThread::_the_list; + +void NonJavaThread::init() { + _the_list.initialize(); +} NonJavaThread::Iterator::Iterator() : - _protect_enter(_the_list._protect.enter()), - _current(AtomicAccess::load_acquire(&_the_list._head)) + _protect_enter(_the_list->_protect.enter()), + _current(AtomicAccess::load_acquire(&_the_list->_head)) {} NonJavaThread::Iterator::~Iterator() { - _the_list._protect.exit(_protect_enter); + _the_list->_protect.exit(_protect_enter); } void NonJavaThread::Iterator::step() { @@ -76,8 +80,8 @@ void NonJavaThread::add_to_the_list() { MutexLocker ml(NonJavaThreadsList_lock, Mutex::_no_safepoint_check_flag); // Initialize BarrierSet-related data before adding to list. BarrierSet::barrier_set()->on_thread_attach(this); - AtomicAccess::release_store(&_next, _the_list._head); - AtomicAccess::release_store(&_the_list._head, this); + AtomicAccess::release_store(&_next, _the_list->_head); + AtomicAccess::release_store(&_the_list->_head, this); } void NonJavaThread::remove_from_the_list() { @@ -85,7 +89,7 @@ void NonJavaThread::remove_from_the_list() { MutexLocker ml(NonJavaThreadsList_lock, Mutex::_no_safepoint_check_flag); // Cleanup BarrierSet-related data before removing from list. BarrierSet::barrier_set()->on_thread_detach(this); - NonJavaThread* volatile* p = &_the_list._head; + NonJavaThread* volatile* p = &_the_list->_head; for (NonJavaThread* t = *p; t != nullptr; p = &t->_next, t = *p) { if (t == this) { *p = _next; @@ -97,7 +101,7 @@ void NonJavaThread::remove_from_the_list() { // allowed, so do it while holding a dedicated lock. Outside and distinct // from NJTList_lock in case an iteration attempts to lock it. MutexLocker ml(NonJavaThreadsListSync_lock, Mutex::_no_safepoint_check_flag); - _the_list._protect.synchronize(); + _the_list->_protect.synchronize(); _next = nullptr; // Safe to drop the link now. } @@ -344,4 +348,3 @@ void WatcherThread::print_on(outputStream* st) const { Thread::print_on(st); st->cr(); } - diff --git a/src/hotspot/share/runtime/nonJavaThread.hpp b/src/hotspot/share/runtime/nonJavaThread.hpp index b2ac6a31737..aaf0dcdfa2d 100644 --- a/src/hotspot/share/runtime/nonJavaThread.hpp +++ b/src/hotspot/share/runtime/nonJavaThread.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, 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 @@ -26,12 +26,18 @@ #define SHARE_RUNTIME_NONJAVATHREAD_HPP #include "runtime/thread.hpp" +#include "utilities/deferredStatic.hpp" class NonJavaThread: public Thread { - NonJavaThread* volatile _next; + friend class Threads; class List; - static List _the_list; + static DeferredStatic _the_list; + + // Deferred static initialization + static void init(); + + NonJavaThread* volatile _next; void add_to_the_list(); void remove_from_the_list(); diff --git a/src/hotspot/share/runtime/threads.cpp b/src/hotspot/share/runtime/threads.cpp index d098343c354..ffe1a86cda5 100644 --- a/src/hotspot/share/runtime/threads.cpp +++ b/src/hotspot/share/runtime/threads.cpp @@ -446,6 +446,9 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { // Check version if (!is_supported_jni_version(args->version)) return JNI_EVERSION; + // Deferred "static" initialization + NonJavaThread::init(); + // Initialize library-based TLS ThreadLocalStorage::init();