diff -r d4bd9341ded3 -r b7582a690cb9 hotspot/src/share/vm/runtime/thread.cpp --- a/hotspot/src/share/vm/runtime/thread.cpp Mon Mar 02 05:32:01 2015 -0800 +++ b/hotspot/src/share/vm/runtime/thread.cpp Mon Mar 02 16:31:25 2015 -0800 @@ -1197,8 +1197,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 @@ -1211,8 +1218,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) { @@ -1253,7 +1261,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"); @@ -1289,6 +1297,11 @@ } } + if (_should_terminate) { + // check for termination before posting the next tick + break; + } + PeriodicTask::real_time_tick(time_waited); } @@ -1319,27 +1332,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) { @@ -1359,9 +1364,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(); } @@ -3558,8 +3561,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