diff -r b788134d664a -r c2364e06aa8d hotspot/src/share/vm/runtime/thread.cpp --- a/hotspot/src/share/vm/runtime/thread.cpp Wed Mar 04 02:23:38 2015 +0100 +++ b/hotspot/src/share/vm/runtime/thread.cpp Thu Mar 05 17:27:16 2015 +0100 @@ -1201,8 +1201,15 @@ } int WatcherThread::sleep() const { + // The WatcherThread does not participate in the safepoint protocol + // for the PeriodicTask_lock because it is not a JavaThread. MutexLockerEx ml(PeriodicTask_lock, Mutex::_no_safepoint_check_flag); + if (_should_terminate) { + // check for termination before we do any housekeeping or wait + return 0; // we did not sleep. + } + // remaining will be zero if there are no tasks, // causing the WatcherThread to sleep until a task is // enrolled @@ -1215,8 +1222,9 @@ jlong time_before_loop = os::javaTimeNanos(); - for (;;) { - bool timedout = PeriodicTask_lock->wait(Mutex::_no_safepoint_check_flag, remaining); + while (true) { + bool timedout = PeriodicTask_lock->wait(Mutex::_no_safepoint_check_flag, + remaining); jlong now = os::javaTimeNanos(); if (remaining == 0) { @@ -1257,7 +1265,7 @@ this->initialize_thread_local_storage(); this->set_native_thread_name(this->name()); this->set_active_handles(JNIHandleBlock::allocate_block()); - while (!_should_terminate) { + while (true) { assert(watcher_thread() == Thread::current(), "thread consistency check"); assert(watcher_thread() == this, "thread consistency check"); @@ -1293,6 +1301,11 @@ } } + if (_should_terminate) { + // check for termination before posting the next tick + break; + } + PeriodicTask::real_time_tick(time_waited); } @@ -1323,27 +1336,19 @@ } void WatcherThread::stop() { - // Get the PeriodicTask_lock if we can. If we cannot, then the - // WatcherThread is using it and we don't want to block on that lock - // here because that might cause a safepoint deadlock depending on - // what the current WatcherThread tasks are doing. - bool have_lock = PeriodicTask_lock->try_lock(); - - _should_terminate = true; - OrderAccess::fence(); // ensure WatcherThread sees update in main loop - - if (have_lock) { + { + // Follow normal safepoint aware lock enter protocol since the + // WatcherThread is stopped by another JavaThread. + MutexLocker ml(PeriodicTask_lock); + _should_terminate = true; + WatcherThread* watcher = watcher_thread(); if (watcher != NULL) { - // If we managed to get the lock, then we should unpark the - // WatcherThread so that it can see we want it to stop. + // unpark the WatcherThread so it can see that it should terminate watcher->unpark(); } - - PeriodicTask_lock->unlock(); } - // it is ok to take late safepoints here, if needed MutexLocker mu(Terminator_lock); while (watcher_thread() != NULL) { @@ -1363,9 +1368,7 @@ } void WatcherThread::unpark() { - MutexLockerEx ml(PeriodicTask_lock->owned_by_self() - ? NULL - : PeriodicTask_lock, Mutex::_no_safepoint_check_flag); + assert(PeriodicTask_lock->owned_by_self(), "PeriodicTask_lock required"); PeriodicTask_lock->notify(); } @@ -3562,8 +3565,8 @@ } { - MutexLockerEx ml(PeriodicTask_lock, Mutex::_no_safepoint_check_flag); - // Make sure the watcher thread can be started by WatcherThread::start() + MutexLocker ml(PeriodicTask_lock); + // Make sure the WatcherThread can be started by WatcherThread::start() // or by dynamic enrollment. WatcherThread::make_startable(); // Start up the WatcherThread if there are any periodic tasks