Mercurial > hg > truffle
comparison src/share/vm/runtime/task.cpp @ 6939:c284cf4781f0
7127792: Add the ability to change an existing PeriodicTask's execution interval
Summary: Enables dynamic enrollment / disenrollment from the PeriodicTasks in WatcherThread.
Reviewed-by: dholmes, mgronlun
author | rbackman |
---|---|
date | Thu, 04 Oct 2012 14:55:57 +0200 |
parents | f08d439fab8c |
children | f34d701e952e |
comparison
equal
deleted
inserted
replaced
6938:8940ddc1036f | 6939:c284cf4781f0 |
---|---|
59 } | 59 } |
60 } | 60 } |
61 } | 61 } |
62 #endif | 62 #endif |
63 | 63 |
64 void PeriodicTask::real_time_tick(size_t delay_time) { | 64 void PeriodicTask::real_time_tick(int delay_time) { |
65 #ifndef PRODUCT | 65 #ifndef PRODUCT |
66 if (ProfilerCheckIntervals) { | 66 if (ProfilerCheckIntervals) { |
67 _ticks++; | 67 _ticks++; |
68 _timer.stop(); | 68 _timer.stop(); |
69 int ms = (int)(_timer.seconds() * 1000.0); | 69 int ms = (int)(_timer.seconds() * 1000.0); |
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 } |