hotspot/src/share/vm/runtime/task.cpp
changeset 14390 bd0d881cf1c5
parent 10565 dc90c239f4ec
child 14583 d70ee55535f4
--- a/hotspot/src/share/vm/runtime/task.cpp	Mon Nov 05 13:55:31 2012 -0800
+++ b/hotspot/src/share/vm/runtime/task.cpp	Thu Oct 04 14:55:57 2012 +0200
@@ -61,7 +61,7 @@
 }
 #endif
 
-void PeriodicTask::real_time_tick(size_t delay_time) {
+void PeriodicTask::real_time_tick(int delay_time) {
 #ifndef PRODUCT
   if (ProfilerCheckIntervals) {
     _ticks++;
@@ -73,19 +73,39 @@
     _intervalHistogram[ms]++;
   }
 #endif
-  int orig_num_tasks = _num_tasks;
-  for(int index = 0; index < _num_tasks; index++) {
-    _tasks[index]->execute_if_pending(delay_time);
-    if (_num_tasks < orig_num_tasks) { // task dis-enrolled itself
-      index--;  // re-do current slot as it has changed
-      orig_num_tasks = _num_tasks;
+
+  {
+    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);
+      if (_num_tasks < orig_num_tasks) { // task dis-enrolled itself
+        index--;  // re-do current slot as it has changed
+        orig_num_tasks = _num_tasks;
+      }
     }
   }
 }
 
+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
+  }
+
+  int delay = _tasks[0]->time_to_next_interval();
+  for (int index = 1; index < _num_tasks; index++) {
+    delay = MIN2(delay, _tasks[index]->time_to_next_interval());
+  }
+  return delay;
+}
+
 
 PeriodicTask::PeriodicTask(size_t interval_time) :
-  _counter(0), _interval(interval_time) {
+  _counter(0), _interval((int) interval_time) {
   // Sanity check the interval time
   assert(_interval >= PeriodicTask::min_interval &&
          _interval <= PeriodicTask::max_interval &&
@@ -94,33 +114,40 @@
 }
 
 PeriodicTask::~PeriodicTask() {
-  if (is_enrolled())
-    disenroll();
-}
-
-bool PeriodicTask::is_enrolled() const {
-  for(int index = 0; index < _num_tasks; index++)
-    if (_tasks[index] == this) return true;
-  return false;
+  disenroll();
 }
 
 void PeriodicTask::enroll() {
-  assert(WatcherThread::watcher_thread() == NULL, "dynamic enrollment of tasks not yet supported");
+  MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ?
+                     NULL : PeriodicTask_lock, Mutex::_no_safepoint_check_flag);
 
-  if (_num_tasks == PeriodicTask::max_tasks)
+  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();
+  }
 }
 
 void PeriodicTask::disenroll() {
-  assert(WatcherThread::watcher_thread() == NULL ||
-         Thread::current() == WatcherThread::watcher_thread(),
-         "dynamic disenrollment currently only handled from WatcherThread from within task() method");
+  MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ?
+                     NULL : PeriodicTask_lock, Mutex::_no_safepoint_check_flag);
 
   int index;
-  for(index = 0; index < _num_tasks && _tasks[index] != this; index++);
-  if (index == _num_tasks) return;
+  for(index = 0; index < _num_tasks && _tasks[index] != this; index++)
+    ;
+
+  if (index == _num_tasks) {
+    return;
+  }
+
   _num_tasks--;
+
   for (; index < _num_tasks; index++) {
     _tasks[index] = _tasks[index+1];
   }