Mercurial > hg > graal-jvmci-8
comparison src/share/vm/utilities/workgroup.hpp @ 1833:8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
Summary: Associate number of GC workers with the workgang as opposed to the task.
Reviewed-by: johnc, ysr
author | jmasa |
---|---|
date | Mon, 20 Sep 2010 14:38:38 -0700 |
parents | c18cbe5936b8 |
children | f95d63e2154a |
comparison
equal
deleted
inserted
replaced
1781:97fbf5beff7b | 1833:8b10f48633dc |
---|---|
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 { |
269 jint* _tasks; | 327 jint* _tasks; |
270 int _n_tasks; | 328 int _n_tasks; |
271 int _n_threads; | 329 int _n_threads; |
272 jint _threads_completed; | 330 jint _threads_completed; |
273 #ifdef ASSERT | 331 #ifdef ASSERT |
274 jint _claimed; | 332 volatile jint _claimed; |
275 #endif | 333 #endif |
276 | 334 |
277 // Set all tasks to unclaimed. | 335 // Set all tasks to unclaimed. |
278 void clear(); | 336 void clear(); |
279 | 337 |
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. |