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