1 /* |
1 /* |
2 * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
27 class WorkGang; |
27 class WorkGang; |
28 class GangWorker; |
28 class GangWorker; |
29 class YieldingFlexibleGangWorker; |
29 class YieldingFlexibleGangWorker; |
30 class YieldingFlexibleGangTask; |
30 class YieldingFlexibleGangTask; |
31 class WorkData; |
31 class WorkData; |
|
32 class AbstractWorkGang; |
32 |
33 |
33 // An abstract task to be worked on by a gang. |
34 // An abstract task to be worked on by a gang. |
34 // You subclass this to supply your own work() method |
35 // You subclass this to supply your own work() method |
35 class AbstractGangTask VALUE_OBJ_CLASS_SPEC { |
36 class AbstractGangTask VALUE_OBJ_CLASS_SPEC { |
36 public: |
37 public: |
37 // The abstract work method. |
38 // The abstract work method. |
38 // The argument tells you which member of the gang you are. |
39 // The argument tells you which member of the gang you are. |
39 virtual void work(int i) = 0; |
40 virtual void work(int i) = 0; |
|
41 |
|
42 // This method configures the task for proper termination. |
|
43 // Some tasks do not have any requirements on termination |
|
44 // and may inherit this method that does nothing. Some |
|
45 // tasks do some coordination on termination and override |
|
46 // this method to implement that coordination. |
|
47 virtual void set_for_termination(int active_workers) {}; |
40 |
48 |
41 // Debugging accessor for the name. |
49 // Debugging accessor for the name. |
42 const char* name() const PRODUCT_RETURN_(return NULL;); |
50 const char* name() const PRODUCT_RETURN_(return NULL;); |
43 int counter() { return _counter; } |
51 int counter() { return _counter; } |
44 void set_counter(int value) { _counter = value; } |
52 void set_counter(int value) { _counter = value; } |
62 _counter = 0; |
70 _counter = 0; |
63 } |
71 } |
64 virtual ~AbstractGangTask() { } |
72 virtual ~AbstractGangTask() { } |
65 }; |
73 }; |
66 |
74 |
|
75 class AbstractGangTaskWOopQueues : public AbstractGangTask { |
|
76 OopTaskQueueSet* _queues; |
|
77 ParallelTaskTerminator _terminator; |
|
78 public: |
|
79 AbstractGangTaskWOopQueues(const char* name, OopTaskQueueSet* queues) : |
|
80 AbstractGangTask(name), _queues(queues), _terminator(0, _queues) {} |
|
81 ParallelTaskTerminator* terminator() { return &_terminator; } |
|
82 virtual void set_for_termination(int active_workers) { |
|
83 terminator()->reset_for_reuse(active_workers); |
|
84 } |
|
85 OopTaskQueueSet* queues() { return _queues; } |
|
86 }; |
67 |
87 |
68 // Class AbstractWorkGang: |
88 // Class AbstractWorkGang: |
69 // An abstract class representing a gang of workers. |
89 // An abstract class representing a gang of workers. |
70 // You subclass this to supply an implementation of run_task(). |
90 // You subclass this to supply an implementation of run_task(). |
71 class AbstractWorkGang: public CHeapObj { |
91 class AbstractWorkGang: public CHeapObj { |
112 return _monitor; |
132 return _monitor; |
113 } |
133 } |
114 int total_workers() const { |
134 int total_workers() const { |
115 return _total_workers; |
135 return _total_workers; |
116 } |
136 } |
|
137 virtual int active_workers() const { |
|
138 return _total_workers; |
|
139 } |
117 bool terminate() const { |
140 bool terminate() const { |
118 return _terminate; |
141 return _terminate; |
119 } |
142 } |
120 GangWorker** gang_workers() const { |
143 GangWorker** gang_workers() const { |
121 return _gang_workers; |
144 return _gang_workers; |
197 // Constructor |
220 // Constructor |
198 WorkGang(const char* name, int workers, |
221 WorkGang(const char* name, int workers, |
199 bool are_GC_task_threads, bool are_ConcurrentGC_threads); |
222 bool are_GC_task_threads, bool are_ConcurrentGC_threads); |
200 // Run a task, returns when the task is done (or terminated). |
223 // Run a task, returns when the task is done (or terminated). |
201 virtual void run_task(AbstractGangTask* task); |
224 virtual void run_task(AbstractGangTask* task); |
|
225 void run_task(AbstractGangTask* task, uint no_of_parallel_workers); |
|
226 // Allocate a worker and return a pointer to it. |
|
227 virtual GangWorker* allocate_worker(int which); |
|
228 // Initialize workers in the gang. Return true if initialization |
|
229 // succeeded. The type of the worker can be overridden in a derived |
|
230 // class with the appropriate implementation of allocate_worker(). |
|
231 bool initialize_workers(); |
202 }; |
232 }; |
203 |
233 |
204 // Class GangWorker: |
234 // Class GangWorker: |
205 // Several instances of this class run in parallel as workers for a gang. |
235 // Several instances of this class run in parallel as workers for a gang. |
206 class GangWorker: public WorkerThread { |
236 class GangWorker: public WorkerThread { |
224 |
254 |
225 public: |
255 public: |
226 AbstractWorkGang* gang() const { return _gang; } |
256 AbstractWorkGang* gang() const { return _gang; } |
227 }; |
257 }; |
228 |
258 |
|
259 class FlexibleWorkGang: public WorkGang { |
|
260 protected: |
|
261 int _active_workers; |
|
262 public: |
|
263 // Constructor and destructor. |
|
264 FlexibleWorkGang(const char* name, int workers, |
|
265 bool are_GC_task_threads, |
|
266 bool are_ConcurrentGC_threads) : |
|
267 WorkGang(name, workers, are_GC_task_threads, are_ConcurrentGC_threads) { |
|
268 _active_workers = ParallelGCThreads; |
|
269 }; |
|
270 // Accessors for fields |
|
271 virtual int active_workers() const { return _active_workers; } |
|
272 void set_active_workers(int v) { _active_workers = v; } |
|
273 }; |
|
274 |
|
275 // Work gangs in garbage collectors: 2009-06-10 |
|
276 // |
|
277 // SharedHeap - work gang for stop-the-world parallel collection. |
|
278 // Used by |
|
279 // ParNewGeneration |
|
280 // CMSParRemarkTask |
|
281 // CMSRefProcTaskExecutor |
|
282 // G1CollectedHeap |
|
283 // G1ParFinalCountTask |
|
284 // ConcurrentMark |
|
285 // CMSCollector |
|
286 |
229 // A class that acts as a synchronisation barrier. Workers enter |
287 // A class that acts as a synchronisation barrier. Workers enter |
230 // the barrier and must wait until all other workers have entered |
288 // the barrier and must wait until all other workers have entered |
231 // before any of them may leave. |
289 // before any of them may leave. |
232 |
290 |
233 class WorkGangBarrierSync : public StackObj { |
291 class WorkGangBarrierSync : public StackObj { |
284 SubTasksDone(int n); |
342 SubTasksDone(int n); |
285 |
343 |
286 // True iff the object is in a valid state. |
344 // True iff the object is in a valid state. |
287 bool valid(); |
345 bool valid(); |
288 |
346 |
289 // Set the number of parallel threads doing the tasks to "t". Can only |
347 // Get/set the number of parallel threads doing the tasks to "t". Can only |
290 // be called before tasks start or after they are complete. |
348 // be called before tasks start or after they are complete. |
291 void set_par_threads(int t); |
349 int n_threads() { return _n_threads; } |
|
350 void set_n_threads(int t); |
292 |
351 |
293 // Returns "false" if the task "t" is unclaimed, and ensures that task is |
352 // Returns "false" if the task "t" is unclaimed, and ensures that task is |
294 // claimed. The task "t" is required to be within the range of "this". |
353 // claimed. The task "t" is required to be within the range of "this". |
295 bool is_task_claimed(int t); |
354 bool is_task_claimed(int t); |
296 |
355 |
313 |
372 |
314 class SequentialSubTasksDone : public StackObj { |
373 class SequentialSubTasksDone : public StackObj { |
315 protected: |
374 protected: |
316 jint _n_tasks; // Total number of tasks available. |
375 jint _n_tasks; // Total number of tasks available. |
317 jint _n_claimed; // Number of tasks claimed. |
376 jint _n_claimed; // Number of tasks claimed. |
|
377 // _n_threads is used to determine when a sub task is done. |
|
378 // See comments on SubTasksDone::_n_threads |
318 jint _n_threads; // Total number of parallel threads. |
379 jint _n_threads; // Total number of parallel threads. |
319 jint _n_completed; // Number of completed threads. |
380 jint _n_completed; // Number of completed threads. |
320 |
381 |
321 void clear(); |
382 void clear(); |
322 |
383 |
323 public: |
384 public: |
324 SequentialSubTasksDone() { clear(); } |
385 SequentialSubTasksDone() { |
|
386 clear(); |
|
387 } |
325 ~SequentialSubTasksDone() {} |
388 ~SequentialSubTasksDone() {} |
326 |
389 |
327 // True iff the object is in a valid state. |
390 // True iff the object is in a valid state. |
328 bool valid(); |
391 bool valid(); |
329 |
392 |
330 // number of tasks |
393 // number of tasks |
331 jint n_tasks() const { return _n_tasks; } |
394 jint n_tasks() const { return _n_tasks; } |
332 |
395 |
333 // Set the number of parallel threads doing the tasks to t. |
396 // Get/set the number of parallel threads doing the tasks to t. |
334 // Should be called before the task starts but it is safe |
397 // Should be called before the task starts but it is safe |
335 // to call this once a task is running provided that all |
398 // to call this once a task is running provided that all |
336 // threads agree on the number of threads. |
399 // threads agree on the number of threads. |
337 void set_par_threads(int t) { _n_threads = t; } |
400 int n_threads() { return _n_threads; } |
|
401 void set_n_threads(int t) { _n_threads = t; } |
338 |
402 |
339 // Set the number of tasks to be claimed to t. As above, |
403 // Set the number of tasks to be claimed to t. As above, |
340 // should be called before the tasks start but it is safe |
404 // should be called before the tasks start but it is safe |
341 // to call this once a task is running provided all threads |
405 // to call this once a task is running provided all threads |
342 // agree on the number of tasks. |
406 // agree on the number of tasks. |