src/share/vm/runtime/task.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.
*** 45,54 **** --- 45,56 ---- } } #endif void PeriodicTask::real_time_tick(int delay_time) { + assert(Thread::current()->is_Watcher_thread(), "must be WatcherThread"); + #ifndef PRODUCT if (ProfilerCheckIntervals) { _ticks++; _timer.stop(); int ms = (int)(_timer.seconds() * 1000.0);
*** 58,67 **** --- 60,71 ---- _intervalHistogram[ms]++; } #endif { + // 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); int orig_num_tasks = _num_tasks; for(int index = 0; index < _num_tasks; index++) { _tasks[index]->execute_if_pending(delay_time);
*** 72,83 **** } } } int PeriodicTask::time_to_wait() { ! MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ? ! NULL : PeriodicTask_lock, Mutex::_no_safepoint_check_flag); if (_num_tasks == 0) { return 0; // sleep until shutdown or a task is enrolled } --- 76,86 ---- } } } int PeriodicTask::time_to_wait() { ! assert(PeriodicTask_lock->owned_by_self(), "PeriodicTask_lock required"); if (_num_tasks == 0) { return 0; // sleep until shutdown or a task is enrolled }
*** 96,132 **** _interval % PeriodicTask::interval_gran == 0, "improper PeriodicTask interval time"); } PeriodicTask::~PeriodicTask() { disenroll(); } ! /* enroll could be called from a JavaThread, so we have to check for ! * safepoint when taking the lock to avoid deadlocking */ void PeriodicTask::enroll() { ! MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ? ! NULL : PeriodicTask_lock); if (_num_tasks == PeriodicTask::max_tasks) { fatal("Overflow in PeriodicTask table"); } _tasks[_num_tasks++] = this; WatcherThread* thread = WatcherThread::watcher_thread(); ! if (thread) { thread->unpark(); } else { WatcherThread::start(); } } ! /* disenroll could be called from a JavaThread, so we have to check for ! * safepoint when taking the lock to avoid deadlocking */ void PeriodicTask::disenroll() { ! MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ? ! NULL : PeriodicTask_lock); int index; for(index = 0; index < _num_tasks && _tasks[index] != this; index++) ; --- 99,143 ---- _interval % PeriodicTask::interval_gran == 0, "improper PeriodicTask interval time"); } PeriodicTask::~PeriodicTask() { + // This PeriodicTask may have already been disenrolled by a call + // to disenroll() before the PeriodicTask was deleted. disenroll(); } ! // enroll the current PeriodicTask void PeriodicTask::enroll() { ! // Follow normal safepoint aware lock enter protocol if the caller does ! // not already own the PeriodicTask_lock. Otherwise, we don't try to ! // enter it again because VM internal Mutexes do not support recursion. ! // ! MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ? NULL ! : PeriodicTask_lock); if (_num_tasks == PeriodicTask::max_tasks) { fatal("Overflow in PeriodicTask table"); } _tasks[_num_tasks++] = this; WatcherThread* thread = WatcherThread::watcher_thread(); ! if (thread != NULL) { thread->unpark(); } else { WatcherThread::start(); } } ! // disenroll the current PeriodicTask void PeriodicTask::disenroll() { ! // Follow normal safepoint aware lock enter protocol if the caller does ! // not already own the PeriodicTask_lock. Otherwise, we don't try to ! // enter it again because VM internal Mutexes do not support recursion. ! // ! MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ? NULL ! : PeriodicTask_lock); int index; for(index = 0; index < _num_tasks && _tasks[index] != this; index++) ;