Mercurial > hg > truffle
comparison src/share/vm/runtime/task.hpp @ 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 | b9a9ed0f8eeb |
children |
comparison
equal
deleted
inserted
replaced
6938:8940ddc1036f | 6939:c284cf4781f0 |
---|---|
47 max_interval = 10000 }; | 47 max_interval = 10000 }; |
48 | 48 |
49 static int num_tasks() { return _num_tasks; } | 49 static int num_tasks() { return _num_tasks; } |
50 | 50 |
51 private: | 51 private: |
52 size_t _counter; | 52 int _counter; |
53 const size_t _interval; | 53 const int _interval; |
54 | 54 |
55 static int _num_tasks; | 55 static int _num_tasks; |
56 static PeriodicTask* _tasks[PeriodicTask::max_tasks]; | 56 static PeriodicTask* _tasks[PeriodicTask::max_tasks]; |
57 static void real_time_tick(size_t delay_time); | 57 static void real_time_tick(int delay_time); |
58 | 58 |
59 #ifndef PRODUCT | 59 #ifndef PRODUCT |
60 static elapsedTimer _timer; // measures time between ticks | 60 static elapsedTimer _timer; // measures time between ticks |
61 static int _ticks; // total number of ticks | 61 static int _ticks; // total number of ticks |
62 static int _intervalHistogram[max_interval]; // to check spacing of timer interrupts | 62 static int _intervalHistogram[max_interval]; // to check spacing of timer interrupts |
67 friend class WatcherThread; | 67 friend class WatcherThread; |
68 public: | 68 public: |
69 PeriodicTask(size_t interval_time); // interval is in milliseconds of elapsed time | 69 PeriodicTask(size_t interval_time); // interval is in milliseconds of elapsed time |
70 ~PeriodicTask(); | 70 ~PeriodicTask(); |
71 | 71 |
72 // Tells whether is enrolled | |
73 bool is_enrolled() const; | |
74 | |
75 // Make the task active | 72 // Make the task active |
76 // NOTE: this may only be called before the WatcherThread has been started | 73 // For dynamic enrollment at the time T, the task will execute somewhere |
74 // between T and T + interval_time. | |
77 void enroll(); | 75 void enroll(); |
78 | 76 |
79 // Make the task deactive | 77 // Make the task deactive |
80 // NOTE: this may only be called either while the WatcherThread is | |
81 // inactive or by a task from within its task() method. One-shot or | |
82 // several-shot tasks may be implemented this way. | |
83 void disenroll(); | 78 void disenroll(); |
84 | 79 |
85 void execute_if_pending(size_t delay_time) { | 80 void execute_if_pending(int delay_time) { |
86 _counter += delay_time; | 81 // make sure we don't overflow |
87 if (_counter >= _interval) { | 82 jlong tmp = (jlong) _counter + (jlong) delay_time; |
83 | |
84 if (tmp >= (jlong) _interval) { | |
88 _counter = 0; | 85 _counter = 0; |
89 task(); | 86 task(); |
87 } else { | |
88 _counter += delay_time; | |
90 } | 89 } |
91 } | 90 } |
92 | 91 |
93 // Returns how long (time in milliseconds) before the next time we should | 92 // Returns how long (time in milliseconds) before the next time we should |
94 // execute this task. | 93 // execute this task. |
95 size_t time_to_next_interval() const { | 94 int time_to_next_interval() const { |
96 assert(_interval > _counter, "task counter greater than interval?"); | 95 assert(_interval > _counter, "task counter greater than interval?"); |
97 return _interval - _counter; | 96 return _interval - _counter; |
98 } | 97 } |
99 | 98 |
100 // Calculate when the next periodic task will fire. | 99 // Calculate when the next periodic task will fire. |
101 // Called by the WatcherThread's run method. | 100 // Called by the WatcherThread's run method. |
102 // This assumes that periodic tasks aren't entering the system | 101 static int time_to_wait(); |
103 // dynamically, except for during startup. | |
104 static size_t time_to_wait() { | |
105 if (_num_tasks == 0) { | |
106 // Don't wait any more; shut down the thread since we don't | |
107 // currently support dynamic enrollment. | |
108 return 0; | |
109 } | |
110 | |
111 size_t delay = _tasks[0]->time_to_next_interval(); | |
112 for (int index = 1; index < _num_tasks; index++) { | |
113 delay = MIN2(delay, _tasks[index]->time_to_next_interval()); | |
114 } | |
115 return delay; | |
116 } | |
117 | 102 |
118 // The task to perform at each period | 103 // The task to perform at each period |
119 virtual void task() = 0; | 104 virtual void task() = 0; |
120 }; | 105 }; |
121 | 106 |