71 _timer.start(); |
71 _timer.start(); |
72 if (ms >= PeriodicTask::max_interval) ms = PeriodicTask::max_interval - 1; |
72 if (ms >= PeriodicTask::max_interval) ms = PeriodicTask::max_interval - 1; |
73 _intervalHistogram[ms]++; |
73 _intervalHistogram[ms]++; |
74 } |
74 } |
75 #endif |
75 #endif |
76 int orig_num_tasks = _num_tasks; |
76 |
77 for(int index = 0; index < _num_tasks; index++) { |
77 { |
78 _tasks[index]->execute_if_pending(delay_time); |
78 MutexLockerEx ml(PeriodicTask_lock, Mutex::_no_safepoint_check_flag); |
79 if (_num_tasks < orig_num_tasks) { // task dis-enrolled itself |
79 int orig_num_tasks = _num_tasks; |
80 index--; // re-do current slot as it has changed |
80 |
81 orig_num_tasks = _num_tasks; |
81 for(int index = 0; index < _num_tasks; index++) { |
|
82 _tasks[index]->execute_if_pending(delay_time); |
|
83 if (_num_tasks < orig_num_tasks) { // task dis-enrolled itself |
|
84 index--; // re-do current slot as it has changed |
|
85 orig_num_tasks = _num_tasks; |
|
86 } |
82 } |
87 } |
83 } |
88 } |
84 } |
89 } |
85 |
90 |
|
91 int PeriodicTask::time_to_wait() { |
|
92 MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ? |
|
93 NULL : PeriodicTask_lock, Mutex::_no_safepoint_check_flag); |
|
94 |
|
95 if (_num_tasks == 0) { |
|
96 return 0; // sleep until shutdown or a task is enrolled |
|
97 } |
|
98 |
|
99 int delay = _tasks[0]->time_to_next_interval(); |
|
100 for (int index = 1; index < _num_tasks; index++) { |
|
101 delay = MIN2(delay, _tasks[index]->time_to_next_interval()); |
|
102 } |
|
103 return delay; |
|
104 } |
|
105 |
86 |
106 |
87 PeriodicTask::PeriodicTask(size_t interval_time) : |
107 PeriodicTask::PeriodicTask(size_t interval_time) : |
88 _counter(0), _interval(interval_time) { |
108 _counter(0), _interval((int) interval_time) { |
89 // Sanity check the interval time |
109 // Sanity check the interval time |
90 assert(_interval >= PeriodicTask::min_interval && |
110 assert(_interval >= PeriodicTask::min_interval && |
91 _interval <= PeriodicTask::max_interval && |
111 _interval <= PeriodicTask::max_interval && |
92 _interval % PeriodicTask::interval_gran == 0, |
112 _interval % PeriodicTask::interval_gran == 0, |
93 "improper PeriodicTask interval time"); |
113 "improper PeriodicTask interval time"); |
94 } |
114 } |
95 |
115 |
96 PeriodicTask::~PeriodicTask() { |
116 PeriodicTask::~PeriodicTask() { |
97 if (is_enrolled()) |
117 disenroll(); |
98 disenroll(); |
|
99 } |
|
100 |
|
101 bool PeriodicTask::is_enrolled() const { |
|
102 for(int index = 0; index < _num_tasks; index++) |
|
103 if (_tasks[index] == this) return true; |
|
104 return false; |
|
105 } |
118 } |
106 |
119 |
107 void PeriodicTask::enroll() { |
120 void PeriodicTask::enroll() { |
108 assert(WatcherThread::watcher_thread() == NULL, "dynamic enrollment of tasks not yet supported"); |
121 MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ? |
|
122 NULL : PeriodicTask_lock, Mutex::_no_safepoint_check_flag); |
109 |
123 |
110 if (_num_tasks == PeriodicTask::max_tasks) |
124 if (_num_tasks == PeriodicTask::max_tasks) { |
111 fatal("Overflow in PeriodicTask table"); |
125 fatal("Overflow in PeriodicTask table"); |
|
126 } |
112 _tasks[_num_tasks++] = this; |
127 _tasks[_num_tasks++] = this; |
|
128 |
|
129 WatcherThread* thread = WatcherThread::watcher_thread(); |
|
130 if (thread) { |
|
131 thread->unpark(); |
|
132 } else { |
|
133 WatcherThread::start(); |
|
134 } |
113 } |
135 } |
114 |
136 |
115 void PeriodicTask::disenroll() { |
137 void PeriodicTask::disenroll() { |
116 assert(WatcherThread::watcher_thread() == NULL || |
138 MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ? |
117 Thread::current() == WatcherThread::watcher_thread(), |
139 NULL : PeriodicTask_lock, Mutex::_no_safepoint_check_flag); |
118 "dynamic disenrollment currently only handled from WatcherThread from within task() method"); |
|
119 |
140 |
120 int index; |
141 int index; |
121 for(index = 0; index < _num_tasks && _tasks[index] != this; index++); |
142 for(index = 0; index < _num_tasks && _tasks[index] != this; index++) |
122 if (index == _num_tasks) return; |
143 ; |
|
144 |
|
145 if (index == _num_tasks) { |
|
146 return; |
|
147 } |
|
148 |
123 _num_tasks--; |
149 _num_tasks--; |
|
150 |
124 for (; index < _num_tasks; index++) { |
151 for (; index < _num_tasks; index++) { |
125 _tasks[index] = _tasks[index+1]; |
152 _tasks[index] = _tasks[index+1]; |
126 } |
153 } |
127 } |
154 } |