8309637: runtime/handshake/HandshakeTimeoutTest.java fails with "has not cleared handshake op" and SIGILL

Reviewed-by: dholmes, coleenp
This commit is contained in:
Patricio Chilano Mateo 2023-07-10 19:09:27 +00:00
parent 63f32fbe97
commit 57e7e82fa1
5 changed files with 34 additions and 34 deletions

View File

@ -471,9 +471,7 @@ void before_exit(JavaThread* thread, bool halt) {
// Stop the WatcherThread. We do this before disenrolling various // Stop the WatcherThread. We do this before disenrolling various
// PeriodicTasks to reduce the likelihood of races. // PeriodicTasks to reduce the likelihood of races.
if (PeriodicTask::num_tasks() > 0) { WatcherThread::stop();
WatcherThread::stop();
}
// shut down the StatSampler task // shut down the StatSampler task
StatSampler::disengage(); StatSampler::disengage();

View File

@ -156,7 +156,7 @@ void NamedThread::print_on(outputStream* st) const {
// timer interrupts exists on the platform. // timer interrupts exists on the platform.
WatcherThread* WatcherThread::_watcher_thread = nullptr; WatcherThread* WatcherThread::_watcher_thread = nullptr;
bool WatcherThread::_startable = false; bool WatcherThread::_run_all_tasks = false;
volatile bool WatcherThread::_should_terminate = false; volatile bool WatcherThread::_should_terminate = false;
WatcherThread::WatcherThread() : NonJavaThread() { WatcherThread::WatcherThread() : NonJavaThread() {
@ -185,6 +185,11 @@ int WatcherThread::sleep() const {
return 0; // we did not sleep. return 0; // we did not sleep.
} }
if (!_run_all_tasks) {
ml.wait(100);
return 0;
}
// remaining will be zero if there are no tasks, // remaining will be zero if there are no tasks,
// causing the WatcherThread to sleep until a task is // causing the WatcherThread to sleep until a task is
// enrolled // enrolled
@ -280,7 +285,10 @@ void WatcherThread::run() {
break; break;
} }
PeriodicTask::real_time_tick(time_waited); // Don't process enrolled tasks until VM is fully initialized.
if (_run_all_tasks) {
PeriodicTask::real_time_tick(time_waited);
}
} }
// Signal that it is terminated // Signal that it is terminated
@ -293,18 +301,16 @@ void WatcherThread::run() {
} }
void WatcherThread::start() { void WatcherThread::start() {
assert(PeriodicTask_lock->owned_by_self(), "PeriodicTask_lock required"); MonitorLocker ml(PeriodicTask_lock);
_should_terminate = false;
if (watcher_thread() == nullptr && _startable) { // Create the single instance of WatcherThread
_should_terminate = false; new WatcherThread();
// Create the single instance of WatcherThread
new WatcherThread();
}
} }
void WatcherThread::make_startable() { void WatcherThread::run_all_tasks() {
assert(PeriodicTask_lock->owned_by_self(), "PeriodicTask_lock required"); MonitorLocker ml(PeriodicTask_lock);
_startable = true; _run_all_tasks = true;
ml.notify();
} }
void WatcherThread::stop() { void WatcherThread::stop() {

View File

@ -110,7 +110,7 @@ class WatcherThread: public NonJavaThread {
private: private:
static WatcherThread* _watcher_thread; static WatcherThread* _watcher_thread;
static bool _startable; static bool _run_all_tasks;
// volatile due to at least one lock-free read // volatile due to at least one lock-free read
volatile static bool _should_terminate; volatile static bool _should_terminate;
public: public:
@ -137,9 +137,9 @@ class WatcherThread: public NonJavaThread {
// Create and start the single instance of WatcherThread, or stop it on shutdown // Create and start the single instance of WatcherThread, or stop it on shutdown
static void start(); static void start();
static void stop(); static void stop();
// Only allow start once the VM is sufficiently initialized // Allow executing registered tasks once the VM is sufficiently
// Otherwise the first task to enroll will trigger the start // initialized. Meanwhile only error reporting will be checked.
static void make_startable(); static void run_all_tasks();
private: private:
int sleep() const; int sleep() const;
}; };

View File

@ -29,6 +29,7 @@
#include "runtime/mutexLocker.hpp" #include "runtime/mutexLocker.hpp"
#include "runtime/nonJavaThread.hpp" #include "runtime/nonJavaThread.hpp"
#include "runtime/task.hpp" #include "runtime/task.hpp"
#include "runtime/threads.hpp"
#include "runtime/timer.hpp" #include "runtime/timer.hpp"
int PeriodicTask::_num_tasks = 0; int PeriodicTask::_num_tasks = 0;
@ -95,10 +96,9 @@ void PeriodicTask::enroll() {
} }
WatcherThread* thread = WatcherThread::watcher_thread(); WatcherThread* thread = WatcherThread::watcher_thread();
assert(thread != nullptr || !Threads::is_vm_complete(), "vm created but no WatcherThread");
if (thread != nullptr) { if (thread != nullptr) {
thread->unpark(); thread->unpark();
} else {
WatcherThread::start();
} }
} }

View File

@ -553,6 +553,10 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
return status; return status;
} }
// Create WatcherThread as soon as we can since we need it in case
// of hangs during error reporting.
WatcherThread::start();
// Add main_thread to threads list to finish barrier setup with // Add main_thread to threads list to finish barrier setup with
// on_thread_attach. Should be before starting to build Java objects in // on_thread_attach. Should be before starting to build Java objects in
// init_globals2, which invokes barriers. // init_globals2, which invokes barriers.
@ -792,19 +796,11 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
CLEAR_PENDING_EXCEPTION; CLEAR_PENDING_EXCEPTION;
} }
{ // Let WatcherThread run all registered periodic tasks now.
MutexLocker ml(PeriodicTask_lock); // NOTE: All PeriodicTasks should be registered by now. If they
// Make sure the WatcherThread can be started by WatcherThread::start() // aren't, late joiners might appear to start slowly (we might
// or by dynamic enrollment. // take a while to process their first tick).
WatcherThread::make_startable(); WatcherThread::run_all_tasks();
// Start up the WatcherThread if there are any periodic tasks
// NOTE: All PeriodicTasks should be registered by now. If they
// aren't, late joiners might appear to start slowly (we might
// take a while to process their first tick).
if (PeriodicTask::num_tasks() > 0) {
WatcherThread::start();
}
}
create_vm_timer.end(); create_vm_timer.end();
#ifdef ASSERT #ifdef ASSERT