70 // You subclass this to supply an implementation of run_task(). |
70 // You subclass this to supply an implementation of run_task(). |
71 class AbstractWorkGang: public CHeapObj { |
71 class AbstractWorkGang: public CHeapObj { |
72 // Here's the public interface to this class. |
72 // Here's the public interface to this class. |
73 public: |
73 public: |
74 // Constructor and destructor. |
74 // Constructor and destructor. |
75 AbstractWorkGang(const char* name, bool are_GC_threads); |
75 AbstractWorkGang(const char* name, bool are_GC_task_threads, |
|
76 bool are_ConcurrentGC_threads); |
76 ~AbstractWorkGang(); |
77 ~AbstractWorkGang(); |
77 // Run a task, returns when the task is done (or terminated). |
78 // Run a task, returns when the task is done (or terminated). |
78 virtual void run_task(AbstractGangTask* task) = 0; |
79 virtual void run_task(AbstractGangTask* task) = 0; |
79 // Stop and terminate all workers. |
80 // Stop and terminate all workers. |
80 virtual void stop(); |
81 virtual void stop(); |
81 public: |
82 public: |
82 // Debugging. |
83 // Debugging. |
83 const char* name() const; |
84 const char* name() const; |
84 protected: |
85 protected: |
85 // Initialize only instance data. |
86 // Initialize only instance data. |
86 const bool _are_GC_threads; |
87 const bool _are_GC_task_threads; |
|
88 const bool _are_ConcurrentGC_threads; |
87 // Printing support. |
89 // Printing support. |
88 const char* _name; |
90 const char* _name; |
89 // The monitor which protects these data, |
91 // The monitor which protects these data, |
90 // and notifies of changes in it. |
92 // and notifies of changes in it. |
91 Monitor* _monitor; |
93 Monitor* _monitor; |
128 return _started_workers; |
130 return _started_workers; |
129 } |
131 } |
130 int finished_workers() const { |
132 int finished_workers() const { |
131 return _finished_workers; |
133 return _finished_workers; |
132 } |
134 } |
133 bool are_GC_threads() const { |
135 bool are_GC_task_threads() const { |
134 return _are_GC_threads; |
136 return _are_GC_task_threads; |
|
137 } |
|
138 bool are_ConcurrentGC_threads() const { |
|
139 return _are_ConcurrentGC_threads; |
135 } |
140 } |
136 // Predicates. |
141 // Predicates. |
137 bool is_idle() const { |
142 bool is_idle() const { |
138 return (task() == NULL); |
143 return (task() == NULL); |
139 } |
144 } |
188 |
193 |
189 // Class WorkGang: |
194 // Class WorkGang: |
190 class WorkGang: public AbstractWorkGang { |
195 class WorkGang: public AbstractWorkGang { |
191 public: |
196 public: |
192 // Constructor |
197 // Constructor |
193 WorkGang(const char* name, int workers, bool are_GC_threads); |
198 WorkGang(const char* name, int workers, |
|
199 bool are_GC_task_threads, bool are_ConcurrentGC_threads); |
194 // Run a task, returns when the task is done (or terminated). |
200 // Run a task, returns when the task is done (or terminated). |
195 virtual void run_task(AbstractGangTask* task); |
201 virtual void run_task(AbstractGangTask* task); |
196 }; |
202 }; |
197 |
203 |
198 // Class GangWorker: |
204 // Class GangWorker: |
204 |
210 |
205 // The only real method: run a task for the gang. |
211 // The only real method: run a task for the gang. |
206 virtual void run(); |
212 virtual void run(); |
207 // Predicate for Thread |
213 // Predicate for Thread |
208 virtual bool is_GC_task_thread() const; |
214 virtual bool is_GC_task_thread() const; |
|
215 virtual bool is_ConcurrentGC_thread() const; |
209 // Printing |
216 // Printing |
210 void print_on(outputStream* st) const; |
217 void print_on(outputStream* st) const; |
211 virtual void print() const { print_on(tty); } |
218 virtual void print() const { print_on(tty); } |
212 protected: |
219 protected: |
213 AbstractWorkGang* _gang; |
220 AbstractWorkGang* _gang; |
226 class WorkGangBarrierSync : public StackObj { |
233 class WorkGangBarrierSync : public StackObj { |
227 protected: |
234 protected: |
228 Monitor _monitor; |
235 Monitor _monitor; |
229 int _n_workers; |
236 int _n_workers; |
230 int _n_completed; |
237 int _n_completed; |
231 |
238 bool _should_reset; |
232 Monitor* monitor() { return &_monitor; } |
239 |
233 int n_workers() { return _n_workers; } |
240 Monitor* monitor() { return &_monitor; } |
234 int n_completed() { return _n_completed; } |
241 int n_workers() { return _n_workers; } |
235 |
242 int n_completed() { return _n_completed; } |
236 void inc_completed() { _n_completed++; } |
243 bool should_reset() { return _should_reset; } |
|
244 |
|
245 void zero_completed() { _n_completed = 0; } |
|
246 void inc_completed() { _n_completed++; } |
|
247 |
|
248 void set_should_reset(bool v) { _should_reset = v; } |
237 |
249 |
238 public: |
250 public: |
239 WorkGangBarrierSync(); |
251 WorkGangBarrierSync(); |
240 WorkGangBarrierSync(int n_workers, const char* name); |
252 WorkGangBarrierSync(int n_workers, const char* name); |
241 |
253 |
341 // claiming tasks must promise call this. Returns true if this |
353 // claiming tasks must promise call this. Returns true if this |
342 // is the last thread to complete so that the thread can perform |
354 // is the last thread to complete so that the thread can perform |
343 // cleanup if necessary. |
355 // cleanup if necessary. |
344 bool all_tasks_completed(); |
356 bool all_tasks_completed(); |
345 }; |
357 }; |
|
358 |
|
359 // Represents a set of free small integer ids. |
|
360 class FreeIdSet { |
|
361 enum { |
|
362 end_of_list = -1, |
|
363 claimed = -2 |
|
364 }; |
|
365 |
|
366 int _sz; |
|
367 Monitor* _mon; |
|
368 |
|
369 int* _ids; |
|
370 int _hd; |
|
371 int _waiters; |
|
372 int _claimed; |
|
373 |
|
374 static bool _safepoint; |
|
375 typedef FreeIdSet* FreeIdSetPtr; |
|
376 static const int NSets = 10; |
|
377 static FreeIdSetPtr _sets[NSets]; |
|
378 static bool _stat_init; |
|
379 int _index; |
|
380 |
|
381 public: |
|
382 FreeIdSet(int sz, Monitor* mon); |
|
383 ~FreeIdSet(); |
|
384 |
|
385 static void set_safepoint(bool b); |
|
386 |
|
387 // Attempt to claim the given id permanently. Returns "true" iff |
|
388 // successful. |
|
389 bool claim_perm_id(int i); |
|
390 |
|
391 // Returns an unclaimed parallel id (waiting for one to be released if |
|
392 // necessary). Returns "-1" if a GC wakes up a wait for an id. |
|
393 int claim_par_id(); |
|
394 |
|
395 void release_par_id(int id); |
|
396 }; |