src/share/vm/runtime/thread.cpp

Print this page

        

*** 1195,1206 **** --- 1195,1213 ---- } } } 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;
*** 1209,1220 **** // 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 --- 1216,1228 ---- // 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
*** 1251,1261 **** 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. --- 1259,1269 ---- 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.
*** 1287,1296 **** --- 1295,1309 ---- // 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 {
*** 1317,1347 **** 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. --- 1330,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; 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.
*** 1357,1369 **** 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());
*** 3556,3567 **** 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