Tue, 09 Oct 2012 10:09:34 -0700
7197424: update copyright year to match last edit in jdk8 hotspot repository
Summary: Update copyright year to 2012 for relevant files
Reviewed-by: dholmes, coleenp
1 /*
2 * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
25 #ifndef SHARE_VM_UTILITIES_WORKGROUP_HPP
26 #define SHARE_VM_UTILITIES_WORKGROUP_HPP
28 #include "utilities/taskqueue.hpp"
29 #ifdef TARGET_OS_FAMILY_linux
30 # include "thread_linux.inline.hpp"
31 #endif
32 #ifdef TARGET_OS_FAMILY_solaris
33 # include "thread_solaris.inline.hpp"
34 #endif
35 #ifdef TARGET_OS_FAMILY_windows
36 # include "thread_windows.inline.hpp"
37 #endif
38 #ifdef TARGET_OS_FAMILY_bsd
39 # include "thread_bsd.inline.hpp"
40 #endif
42 // Task class hierarchy:
43 // AbstractGangTask
44 // AbstractGangTaskWOopQueues
45 //
46 // Gang/Group class hierarchy:
47 // AbstractWorkGang
48 // WorkGang
49 // FlexibleWorkGang
50 // YieldingFlexibleWorkGang (defined in another file)
51 //
52 // Worker class hierarchy:
53 // GangWorker (subclass of WorkerThread)
54 // YieldingFlexibleGangWorker (defined in another file)
56 // Forward declarations of classes defined here
58 class WorkGang;
59 class GangWorker;
60 class YieldingFlexibleGangWorker;
61 class YieldingFlexibleGangTask;
62 class WorkData;
63 class AbstractWorkGang;
65 // An abstract task to be worked on by a gang.
66 // You subclass this to supply your own work() method
67 class AbstractGangTask VALUE_OBJ_CLASS_SPEC {
68 public:
69 // The abstract work method.
70 // The argument tells you which member of the gang you are.
71 virtual void work(uint worker_id) = 0;
73 // This method configures the task for proper termination.
74 // Some tasks do not have any requirements on termination
75 // and may inherit this method that does nothing. Some
76 // tasks do some coordination on termination and override
77 // this method to implement that coordination.
78 virtual void set_for_termination(int active_workers) {};
80 // Debugging accessor for the name.
81 const char* name() const PRODUCT_RETURN_(return NULL;);
82 int counter() { return _counter; }
83 void set_counter(int value) { _counter = value; }
84 int *address_of_counter() { return &_counter; }
86 // RTTI
87 NOT_PRODUCT(virtual bool is_YieldingFlexibleGang_task() const {
88 return false;
89 })
91 private:
92 NOT_PRODUCT(const char* _name;)
93 // ??? Should a task have a priority associated with it?
94 // ??? Or can the run method adjust priority as needed?
95 int _counter;
97 protected:
98 // Constructor and desctructor: only construct subclasses.
99 AbstractGangTask(const char* name)
100 {
101 NOT_PRODUCT(_name = name);
102 _counter = 0;
103 }
104 virtual ~AbstractGangTask() { }
106 public:
107 };
109 class AbstractGangTaskWOopQueues : public AbstractGangTask {
110 OopTaskQueueSet* _queues;
111 ParallelTaskTerminator _terminator;
112 public:
113 AbstractGangTaskWOopQueues(const char* name, OopTaskQueueSet* queues) :
114 AbstractGangTask(name), _queues(queues), _terminator(0, _queues) {}
115 ParallelTaskTerminator* terminator() { return &_terminator; }
116 virtual void set_for_termination(int active_workers) {
117 terminator()->reset_for_reuse(active_workers);
118 }
119 OopTaskQueueSet* queues() { return _queues; }
120 };
123 // Class AbstractWorkGang:
124 // An abstract class representing a gang of workers.
125 // You subclass this to supply an implementation of run_task().
126 class AbstractWorkGang: public CHeapObj<mtInternal> {
127 // Here's the public interface to this class.
128 public:
129 // Constructor and destructor.
130 AbstractWorkGang(const char* name, bool are_GC_task_threads,
131 bool are_ConcurrentGC_threads);
132 ~AbstractWorkGang();
133 // Run a task, returns when the task is done (or terminated).
134 virtual void run_task(AbstractGangTask* task) = 0;
135 // Stop and terminate all workers.
136 virtual void stop();
137 // Return true if more workers should be applied to the task.
138 virtual bool needs_more_workers() const { return true; }
139 public:
140 // Debugging.
141 const char* name() const;
142 protected:
143 // Initialize only instance data.
144 const bool _are_GC_task_threads;
145 const bool _are_ConcurrentGC_threads;
146 // Printing support.
147 const char* _name;
148 // The monitor which protects these data,
149 // and notifies of changes in it.
150 Monitor* _monitor;
151 // The count of the number of workers in the gang.
152 uint _total_workers;
153 // Whether the workers should terminate.
154 bool _terminate;
155 // The array of worker threads for this gang.
156 // This is only needed for cleaning up.
157 GangWorker** _gang_workers;
158 // The task for this gang.
159 AbstractGangTask* _task;
160 // A sequence number for the current task.
161 int _sequence_number;
162 // The number of started workers.
163 uint _started_workers;
164 // The number of finished workers.
165 uint _finished_workers;
166 public:
167 // Accessors for fields
168 Monitor* monitor() const {
169 return _monitor;
170 }
171 uint total_workers() const {
172 return _total_workers;
173 }
174 virtual uint active_workers() const {
175 return _total_workers;
176 }
177 bool terminate() const {
178 return _terminate;
179 }
180 GangWorker** gang_workers() const {
181 return _gang_workers;
182 }
183 AbstractGangTask* task() const {
184 return _task;
185 }
186 int sequence_number() const {
187 return _sequence_number;
188 }
189 uint started_workers() const {
190 return _started_workers;
191 }
192 uint finished_workers() const {
193 return _finished_workers;
194 }
195 bool are_GC_task_threads() const {
196 return _are_GC_task_threads;
197 }
198 bool are_ConcurrentGC_threads() const {
199 return _are_ConcurrentGC_threads;
200 }
201 // Predicates.
202 bool is_idle() const {
203 return (task() == NULL);
204 }
205 // Return the Ith gang worker.
206 GangWorker* gang_worker(uint i) const;
208 void threads_do(ThreadClosure* tc) const;
210 // Printing
211 void print_worker_threads_on(outputStream *st) const;
212 void print_worker_threads() const {
213 print_worker_threads_on(tty);
214 }
216 protected:
217 friend class GangWorker;
218 friend class YieldingFlexibleGangWorker;
219 // Note activation and deactivation of workers.
220 // These methods should only be called with the mutex held.
221 void internal_worker_poll(WorkData* data) const;
222 void internal_note_start();
223 void internal_note_finish();
224 };
226 class WorkData: public StackObj {
227 // This would be a struct, but I want accessor methods.
228 private:
229 bool _terminate;
230 AbstractGangTask* _task;
231 int _sequence_number;
232 public:
233 // Constructor and destructor
234 WorkData() {
235 _terminate = false;
236 _task = NULL;
237 _sequence_number = 0;
238 }
239 ~WorkData() {
240 }
241 // Accessors and modifiers
242 bool terminate() const { return _terminate; }
243 void set_terminate(bool value) { _terminate = value; }
244 AbstractGangTask* task() const { return _task; }
245 void set_task(AbstractGangTask* value) { _task = value; }
246 int sequence_number() const { return _sequence_number; }
247 void set_sequence_number(int value) { _sequence_number = value; }
249 YieldingFlexibleGangTask* yf_task() const {
250 return (YieldingFlexibleGangTask*)_task;
251 }
252 };
254 // Class WorkGang:
255 class WorkGang: public AbstractWorkGang {
256 public:
257 // Constructor
258 WorkGang(const char* name, uint workers,
259 bool are_GC_task_threads, bool are_ConcurrentGC_threads);
260 // Run a task, returns when the task is done (or terminated).
261 virtual void run_task(AbstractGangTask* task);
262 void run_task(AbstractGangTask* task, uint no_of_parallel_workers);
263 // Allocate a worker and return a pointer to it.
264 virtual GangWorker* allocate_worker(uint which);
265 // Initialize workers in the gang. Return true if initialization
266 // succeeded. The type of the worker can be overridden in a derived
267 // class with the appropriate implementation of allocate_worker().
268 bool initialize_workers();
269 };
271 // Class GangWorker:
272 // Several instances of this class run in parallel as workers for a gang.
273 class GangWorker: public WorkerThread {
274 public:
275 // Constructors and destructor.
276 GangWorker(AbstractWorkGang* gang, uint id);
278 // The only real method: run a task for the gang.
279 virtual void run();
280 // Predicate for Thread
281 virtual bool is_GC_task_thread() const;
282 virtual bool is_ConcurrentGC_thread() const;
283 // Printing
284 void print_on(outputStream* st) const;
285 virtual void print() const { print_on(tty); }
286 protected:
287 AbstractWorkGang* _gang;
289 virtual void initialize();
290 virtual void loop();
292 public:
293 AbstractWorkGang* gang() const { return _gang; }
294 };
296 // Dynamic number of worker threads
297 //
298 // This type of work gang is used to run different numbers of
299 // worker threads at different times. The
300 // number of workers run for a task is "_active_workers"
301 // instead of "_total_workers" in a WorkGang. The method
302 // "needs_more_workers()" returns true until "_active_workers"
303 // have been started and returns false afterwards. The
304 // implementation of "needs_more_workers()" in WorkGang always
305 // returns true so that all workers are started. The method
306 // "loop()" in GangWorker was modified to ask "needs_more_workers()"
307 // in its loop to decide if it should start working on a task.
308 // A worker in "loop()" waits for notification on the WorkGang
309 // monitor and execution of each worker as it checks for work
310 // is serialized via the same monitor. The "needs_more_workers()"
311 // call is serialized and additionally the calculation for the
312 // "part" (effectively the worker id for executing the task) is
313 // serialized to give each worker a unique "part". Workers that
314 // are not needed for this tasks (i.e., "_active_workers" have
315 // been started before it, continue to wait for work.
317 class FlexibleWorkGang: public WorkGang {
318 // The currently active workers in this gang.
319 // This is a number that is dynamically adjusted
320 // and checked in the run_task() method at each invocation.
321 // As described above _active_workers determines the number
322 // of threads started on a task. It must also be used to
323 // determine completion.
325 protected:
326 uint _active_workers;
327 public:
328 // Constructor and destructor.
329 // Initialize active_workers to a minimum value. Setting it to
330 // the parameter "workers" will initialize it to a maximum
331 // value which is not desirable.
332 FlexibleWorkGang(const char* name, uint workers,
333 bool are_GC_task_threads,
334 bool are_ConcurrentGC_threads) :
335 WorkGang(name, workers, are_GC_task_threads, are_ConcurrentGC_threads),
336 _active_workers(UseDynamicNumberOfGCThreads ? 1U : ParallelGCThreads) {}
337 // Accessors for fields
338 virtual uint active_workers() const { return _active_workers; }
339 void set_active_workers(uint v) {
340 assert(v <= _total_workers,
341 "Trying to set more workers active than there are");
342 _active_workers = MIN2(v, _total_workers);
343 assert(v != 0, "Trying to set active workers to 0");
344 _active_workers = MAX2(1U, _active_workers);
345 assert(UseDynamicNumberOfGCThreads || _active_workers == _total_workers,
346 "Unless dynamic should use total workers");
347 }
348 virtual void run_task(AbstractGangTask* task);
349 virtual bool needs_more_workers() const {
350 return _started_workers < _active_workers;
351 }
352 };
354 // Work gangs in garbage collectors: 2009-06-10
355 //
356 // SharedHeap - work gang for stop-the-world parallel collection.
357 // Used by
358 // ParNewGeneration
359 // CMSParRemarkTask
360 // CMSRefProcTaskExecutor
361 // G1CollectedHeap
362 // G1ParFinalCountTask
363 // ConcurrentMark
364 // CMSCollector
366 // A class that acts as a synchronisation barrier. Workers enter
367 // the barrier and must wait until all other workers have entered
368 // before any of them may leave.
370 class WorkGangBarrierSync : public StackObj {
371 protected:
372 Monitor _monitor;
373 uint _n_workers;
374 uint _n_completed;
375 bool _should_reset;
377 Monitor* monitor() { return &_monitor; }
378 uint n_workers() { return _n_workers; }
379 uint n_completed() { return _n_completed; }
380 bool should_reset() { return _should_reset; }
382 void zero_completed() { _n_completed = 0; }
383 void inc_completed() { _n_completed++; }
385 void set_should_reset(bool v) { _should_reset = v; }
387 public:
388 WorkGangBarrierSync();
389 WorkGangBarrierSync(uint n_workers, const char* name);
391 // Set the number of workers that will use the barrier.
392 // Must be called before any of the workers start running.
393 void set_n_workers(uint n_workers);
395 // Enter the barrier. A worker that enters the barrier will
396 // not be allowed to leave until all other threads have
397 // also entered the barrier.
398 void enter();
399 };
401 // A class to manage claiming of subtasks within a group of tasks. The
402 // subtasks will be identified by integer indices, usually elements of an
403 // enumeration type.
405 class SubTasksDone: public CHeapObj<mtInternal> {
406 uint* _tasks;
407 uint _n_tasks;
408 // _n_threads is used to determine when a sub task is done.
409 // It does not control how many threads will execute the subtask
410 // but must be initialized to the number that do execute the task
411 // in order to correctly decide when the subtask is done (all the
412 // threads working on the task have finished).
413 uint _n_threads;
414 uint _threads_completed;
415 #ifdef ASSERT
416 volatile uint _claimed;
417 #endif
419 // Set all tasks to unclaimed.
420 void clear();
422 public:
423 // Initializes "this" to a state in which there are "n" tasks to be
424 // processed, none of the which are originally claimed. The number of
425 // threads doing the tasks is initialized 1.
426 SubTasksDone(uint n);
428 // True iff the object is in a valid state.
429 bool valid();
431 // Get/set the number of parallel threads doing the tasks to "t". Can only
432 // be called before tasks start or after they are complete.
433 uint n_threads() { return _n_threads; }
434 void set_n_threads(uint t);
436 // Returns "false" if the task "t" is unclaimed, and ensures that task is
437 // claimed. The task "t" is required to be within the range of "this".
438 bool is_task_claimed(uint t);
440 // The calling thread asserts that it has attempted to claim all the
441 // tasks that it will try to claim. Every thread in the parallel task
442 // must execute this. (When the last thread does so, the task array is
443 // cleared.)
444 void all_tasks_completed();
446 // Destructor.
447 ~SubTasksDone();
448 };
450 // As above, but for sequential tasks, i.e. instead of claiming
451 // sub-tasks from a set (possibly an enumeration), claim sub-tasks
452 // in sequential order. This is ideal for claiming dynamically
453 // partitioned tasks (like striding in the parallel remembered
454 // set scanning). Note that unlike the above class this is
455 // a stack object - is there any reason for it not to be?
457 class SequentialSubTasksDone : public StackObj {
458 protected:
459 uint _n_tasks; // Total number of tasks available.
460 uint _n_claimed; // Number of tasks claimed.
461 // _n_threads is used to determine when a sub task is done.
462 // See comments on SubTasksDone::_n_threads
463 uint _n_threads; // Total number of parallel threads.
464 uint _n_completed; // Number of completed threads.
466 void clear();
468 public:
469 SequentialSubTasksDone() {
470 clear();
471 }
472 ~SequentialSubTasksDone() {}
474 // True iff the object is in a valid state.
475 bool valid();
477 // number of tasks
478 uint n_tasks() const { return _n_tasks; }
480 // Get/set the number of parallel threads doing the tasks to t.
481 // Should be called before the task starts but it is safe
482 // to call this once a task is running provided that all
483 // threads agree on the number of threads.
484 uint n_threads() { return _n_threads; }
485 void set_n_threads(uint t) { _n_threads = t; }
487 // Set the number of tasks to be claimed to t. As above,
488 // should be called before the tasks start but it is safe
489 // to call this once a task is running provided all threads
490 // agree on the number of tasks.
491 void set_n_tasks(uint t) { _n_tasks = t; }
493 // Returns false if the next task in the sequence is unclaimed,
494 // and ensures that it is claimed. Will set t to be the index
495 // of the claimed task in the sequence. Will return true if
496 // the task cannot be claimed and there are none left to claim.
497 bool is_task_claimed(uint& t);
499 // The calling thread asserts that it has attempted to claim
500 // all the tasks it possibly can in the sequence. Every thread
501 // claiming tasks must promise call this. Returns true if this
502 // is the last thread to complete so that the thread can perform
503 // cleanup if necessary.
504 bool all_tasks_completed();
505 };
507 // Represents a set of free small integer ids.
508 class FreeIdSet {
509 enum {
510 end_of_list = -1,
511 claimed = -2
512 };
514 int _sz;
515 Monitor* _mon;
517 int* _ids;
518 int _hd;
519 int _waiters;
520 int _claimed;
522 static bool _safepoint;
523 typedef FreeIdSet* FreeIdSetPtr;
524 static const int NSets = 10;
525 static FreeIdSetPtr _sets[NSets];
526 static bool _stat_init;
527 int _index;
529 public:
530 FreeIdSet(int sz, Monitor* mon);
531 ~FreeIdSet();
533 static void set_safepoint(bool b);
535 // Attempt to claim the given id permanently. Returns "true" iff
536 // successful.
537 bool claim_perm_id(int i);
539 // Returns an unclaimed parallel id (waiting for one to be released if
540 // necessary). Returns "-1" if a GC wakes up a wait for an id.
541 int claim_par_id();
543 void release_par_id(int id);
544 };
546 #endif // SHARE_VM_UTILITIES_WORKGROUP_HPP