This commit is contained in:
Jesper Wilhelmsson 2015-03-05 17:27:16 +01:00
commit 3ea0bee55c
24 changed files with 359 additions and 194 deletions

View file

@ -1201,8 +1201,15 @@ WatcherThread::WatcherThread() : Thread(), _crash_protection(NULL) {
}
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 @@ int WatcherThread::sleep() const {
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 @@ void WatcherThread::run() {
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 @@ void WatcherThread::run() {
}
}
if (_should_terminate) {
// check for termination before posting the next tick
break;
}
PeriodicTask::real_time_tick(time_waited);
}
@ -1323,27 +1336,19 @@ void WatcherThread::make_startable() {
}
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();
{
// Follow normal safepoint aware lock enter protocol since the
// WatcherThread is stopped by another JavaThread.
MutexLocker ml(PeriodicTask_lock);
_should_terminate = true;
_should_terminate = true;
OrderAccess::fence(); // ensure WatcherThread sees update in main loop
if (have_lock) {
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::stop() {
}
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 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
}
{
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