src/share/vm/runtime/thread.cpp

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 1997, 2014, 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. --- 1,7 ---- /* ! * Copyright (c) 1997, 2015, 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.
*** 1194,1205 **** --- 1194,1212 ---- } } } int WatcherThread::sleep() const { + // The WatcherThread is not a JavaThread so we do not honor the + // safepoint protocol for the PeriodicTask_lock. 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 int remaining = PeriodicTask::time_to_wait(); int time_slept = 0;
*** 1208,1219 **** // we should terminate or when a new task has been enrolled OSThreadWaitState osts(this->osthread(), false /* not Object.wait() */); jlong time_before_loop = os::javaTimeNanos(); ! for (;;) { ! bool timedout = PeriodicTask_lock->wait(Mutex::_no_safepoint_check_flag, remaining); jlong now = os::javaTimeNanos(); if (remaining == 0) { // if we didn't have any tasks we could have waited for a long time // consider the time_slept zero and reset time_before_loop --- 1215,1227 ---- // we should terminate or when a new task has been enrolled OSThreadWaitState osts(this->osthread(), false /* not Object.wait() */); jlong time_before_loop = os::javaTimeNanos(); ! while (true) { ! bool timedout = PeriodicTask_lock->wait(Mutex::_no_safepoint_check_flag, ! remaining); jlong now = os::javaTimeNanos(); if (remaining == 0) { // if we didn't have any tasks we could have waited for a long time // consider the time_slept zero and reset time_before_loop
*** 1250,1260 **** this->record_stack_base_and_size(); this->initialize_thread_local_storage(); this->set_native_thread_name(this->name()); this->set_active_handles(JNIHandleBlock::allocate_block()); ! while (!_should_terminate) { assert(watcher_thread() == Thread::current(), "thread consistency check"); assert(watcher_thread() == this, "thread consistency check"); // Calculate how long it'll be until the next PeriodicTask work // should be done, and sleep that amount of time. --- 1258,1268 ---- this->record_stack_base_and_size(); this->initialize_thread_local_storage(); this->set_native_thread_name(this->name()); this->set_active_handles(JNIHandleBlock::allocate_block()); ! while (true) { assert(watcher_thread() == Thread::current(), "thread consistency check"); assert(watcher_thread() == this, "thread consistency check"); // Calculate how long it'll be until the next PeriodicTask work // should be done, and sleep that amount of time.
*** 1286,1295 **** --- 1294,1308 ---- // ShowMessageBoxOnError when it is ready to abort. os::sleep(this, 5 * 1000, false); } } + if (_should_terminate) { + // check for termination before posting the next tick + break; + } + PeriodicTask::real_time_tick(time_waited); } // Signal that it is terminated {
*** 1316,1346 **** assert(PeriodicTask_lock->owned_by_self(), "PeriodicTask_lock required"); _startable = true; } 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) { 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. watcher->unpark(); } - - PeriodicTask_lock->unlock(); } - // it is ok to take late safepoints here, if needed MutexLocker mu(Terminator_lock); while (watcher_thread() != NULL) { // This wait should make safepoint checks, wait without a timeout, // and wait as a suspend-equivalent condition. --- 1329,1352 ---- assert(PeriodicTask_lock->owned_by_self(), "PeriodicTask_lock required"); _startable = true; } void WatcherThread::stop() { ! { ! // Follow normal safepoint aware lock enter protocol since the ! // WatcherThread is stopped by another JavaThread. ! MutexLocker ml(PeriodicTask_lock); _should_terminate = true; OrderAccess::fence(); // ensure WatcherThread sees update in main loop WatcherThread* watcher = watcher_thread(); if (watcher != NULL) { ! // unpark the WatcherThread so it can see that it should terminate watcher->unpark(); } } MutexLocker mu(Terminator_lock); while (watcher_thread() != NULL) { // This wait should make safepoint checks, wait without a timeout, // and wait as a suspend-equivalent condition.
*** 1356,1368 **** Mutex::_as_suspend_equivalent_flag); } } void WatcherThread::unpark() { ! MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ! ? NULL ! : PeriodicTask_lock, Mutex::_no_safepoint_check_flag); PeriodicTask_lock->notify(); } void WatcherThread::print_on(outputStream* st) const { st->print("\"%s\" ", name()); --- 1362,1372 ---- Mutex::_as_suspend_equivalent_flag); } } void WatcherThread::unpark() { ! assert(PeriodicTask_lock->owned_by_self(), "PeriodicTask_lock required"); PeriodicTask_lock->notify(); } void WatcherThread::print_on(outputStream* st) const { st->print("\"%s\" ", name());
*** 3555,3566 **** CLEAR_PENDING_EXCEPTION; } } { ! MutexLockerEx ml(PeriodicTask_lock, Mutex::_no_safepoint_check_flag); ! // Make sure the watcher thread can be started by WatcherThread::start() // or by dynamic enrollment. WatcherThread::make_startable(); // 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 --- 3559,3570 ---- CLEAR_PENDING_EXCEPTION; } } { ! 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 // NOTE: All PeriodicTasks should be registered by now. If they // aren't, late joiners might appear to start slowly (we might