comparison src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.hpp @ 0:a61af66fc99e jdk7-b24

Initial load
author duke
date Sat, 01 Dec 2007 00:00:00 +0000
parents
children c18cbe5936b8
comparison
equal deleted inserted replaced
-1:000000000000 0:a61af66fc99e
1 /*
2 * Copyright 2002-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 *
23 */
24
25 //
26 // The GCTaskManager is a queue of GCTasks, and accessors
27 // to allow the queue to be accessed from many threads.
28 //
29
30 // Forward declarations of types defined in this file.
31 class GCTask;
32 class GCTaskQueue;
33 class SynchronizedGCTaskQueue;
34 class GCTaskManager;
35 class NotifyDoneClosure;
36 // Some useful subclasses of GCTask. You can also make up your own.
37 class NoopGCTask;
38 class BarrierGCTask;
39 class ReleasingBarrierGCTask;
40 class NotifyingBarrierGCTask;
41 class WaitForBarrierGCTask;
42 // A free list of Monitor*'s.
43 class MonitorSupply;
44
45 // Forward declarations of classes referenced in this file via pointer.
46 class GCTaskThread;
47 class Mutex;
48 class Monitor;
49 class ThreadClosure;
50
51 // The abstract base GCTask.
52 class GCTask : public ResourceObj {
53 public:
54 // Known kinds of GCTasks, for predicates.
55 class Kind : AllStatic {
56 public:
57 enum kind {
58 unknown_task,
59 ordinary_task,
60 barrier_task,
61 noop_task
62 };
63 static const char* to_string(kind value);
64 };
65 private:
66 // Instance state.
67 const Kind::kind _kind; // For runtime type checking.
68 const uint _affinity; // Which worker should run task.
69 GCTask* _newer; // Tasks are on doubly-linked ...
70 GCTask* _older; // ... lists.
71 public:
72 virtual char* name() { return (char *)"task"; }
73
74 // Abstract do_it method
75 virtual void do_it(GCTaskManager* manager, uint which) = 0;
76 // Accessors
77 Kind::kind kind() const {
78 return _kind;
79 }
80 uint affinity() const {
81 return _affinity;
82 }
83 GCTask* newer() const {
84 return _newer;
85 }
86 void set_newer(GCTask* n) {
87 _newer = n;
88 }
89 GCTask* older() const {
90 return _older;
91 }
92 void set_older(GCTask* p) {
93 _older = p;
94 }
95 // Predicates.
96 bool is_ordinary_task() const {
97 return kind()==Kind::ordinary_task;
98 }
99 bool is_barrier_task() const {
100 return kind()==Kind::barrier_task;
101 }
102 bool is_noop_task() const {
103 return kind()==Kind::noop_task;
104 }
105 void print(const char* message) const PRODUCT_RETURN;
106 protected:
107 // Constructors: Only create subclasses.
108 // An ordinary GCTask.
109 GCTask();
110 // A GCTask of a particular kind, usually barrier or noop.
111 GCTask(Kind::kind kind);
112 // An ordinary GCTask with an affinity.
113 GCTask(uint affinity);
114 // A GCTask of a particular kind, with and affinity.
115 GCTask(Kind::kind kind, uint affinity);
116 // We want a virtual destructor because virtual methods,
117 // but since ResourceObj's don't have their destructors
118 // called, we don't have one at all. Instead we have
119 // this method, which gets called by subclasses to clean up.
120 virtual void destruct();
121 // Methods.
122 void initialize();
123 };
124
125 // A doubly-linked list of GCTasks.
126 // The list is not synchronized, because sometimes we want to
127 // build up a list and then make it available to other threads.
128 // See also: SynchronizedGCTaskQueue.
129 class GCTaskQueue : public ResourceObj {
130 private:
131 // Instance state.
132 GCTask* _insert_end; // Tasks are enqueued at this end.
133 GCTask* _remove_end; // Tasks are dequeued from this end.
134 uint _length; // The current length of the queue.
135 const bool _is_c_heap_obj; // Is this a CHeapObj?
136 public:
137 // Factory create and destroy methods.
138 // Create as ResourceObj.
139 static GCTaskQueue* create();
140 // Create as CHeapObj.
141 static GCTaskQueue* create_on_c_heap();
142 // Destroyer.
143 static void destroy(GCTaskQueue* that);
144 // Accessors.
145 // These just examine the state of the queue.
146 bool is_empty() const {
147 assert(((insert_end() == NULL && remove_end() == NULL) ||
148 (insert_end() != NULL && remove_end() != NULL)),
149 "insert_end and remove_end don't match");
150 return insert_end() == NULL;
151 }
152 uint length() const {
153 return _length;
154 }
155 // Methods.
156 // Enqueue one task.
157 void enqueue(GCTask* task);
158 // Enqueue a list of tasks. Empties the argument list.
159 void enqueue(GCTaskQueue* list);
160 // Dequeue one task.
161 GCTask* dequeue();
162 // Dequeue one task, preferring one with affinity.
163 GCTask* dequeue(uint affinity);
164 protected:
165 // Constructor. Clients use factory, but there might be subclasses.
166 GCTaskQueue(bool on_c_heap);
167 // Destructor-like method.
168 // Because ResourceMark doesn't call destructors.
169 // This method cleans up like one.
170 virtual void destruct();
171 // Accessors.
172 GCTask* insert_end() const {
173 return _insert_end;
174 }
175 void set_insert_end(GCTask* value) {
176 _insert_end = value;
177 }
178 GCTask* remove_end() const {
179 return _remove_end;
180 }
181 void set_remove_end(GCTask* value) {
182 _remove_end = value;
183 }
184 void increment_length() {
185 _length += 1;
186 }
187 void decrement_length() {
188 _length -= 1;
189 }
190 void set_length(uint value) {
191 _length = value;
192 }
193 bool is_c_heap_obj() const {
194 return _is_c_heap_obj;
195 }
196 // Methods.
197 void initialize();
198 GCTask* remove(); // Remove from remove end.
199 GCTask* remove(GCTask* task); // Remove from the middle.
200 void print(const char* message) const PRODUCT_RETURN;
201 };
202
203 // A GCTaskQueue that can be synchronized.
204 // This "has-a" GCTaskQueue and a mutex to do the exclusion.
205 class SynchronizedGCTaskQueue : public CHeapObj {
206 private:
207 // Instance state.
208 GCTaskQueue* _unsynchronized_queue; // Has-a unsynchronized queue.
209 Monitor * _lock; // Lock to control access.
210 public:
211 // Factory create and destroy methods.
212 static SynchronizedGCTaskQueue* create(GCTaskQueue* queue, Monitor * lock) {
213 return new SynchronizedGCTaskQueue(queue, lock);
214 }
215 static void destroy(SynchronizedGCTaskQueue* that) {
216 if (that != NULL) {
217 delete that;
218 }
219 }
220 // Accessors
221 GCTaskQueue* unsynchronized_queue() const {
222 return _unsynchronized_queue;
223 }
224 Monitor * lock() const {
225 return _lock;
226 }
227 // GCTaskQueue wrapper methods.
228 // These check that you hold the lock
229 // and then call the method on the queue.
230 bool is_empty() const {
231 guarantee(own_lock(), "don't own the lock");
232 return unsynchronized_queue()->is_empty();
233 }
234 void enqueue(GCTask* task) {
235 guarantee(own_lock(), "don't own the lock");
236 unsynchronized_queue()->enqueue(task);
237 }
238 void enqueue(GCTaskQueue* list) {
239 guarantee(own_lock(), "don't own the lock");
240 unsynchronized_queue()->enqueue(list);
241 }
242 GCTask* dequeue() {
243 guarantee(own_lock(), "don't own the lock");
244 return unsynchronized_queue()->dequeue();
245 }
246 GCTask* dequeue(uint affinity) {
247 guarantee(own_lock(), "don't own the lock");
248 return unsynchronized_queue()->dequeue(affinity);
249 }
250 uint length() const {
251 guarantee(own_lock(), "don't own the lock");
252 return unsynchronized_queue()->length();
253 }
254 // For guarantees.
255 bool own_lock() const {
256 return lock()->owned_by_self();
257 }
258 protected:
259 // Constructor. Clients use factory, but there might be subclasses.
260 SynchronizedGCTaskQueue(GCTaskQueue* queue, Monitor * lock);
261 // Destructor. Not virtual because no virtuals.
262 ~SynchronizedGCTaskQueue();
263 };
264
265 // This is an abstract base class for getting notifications
266 // when a GCTaskManager is done.
267 class NotifyDoneClosure : public CHeapObj {
268 public:
269 // The notification callback method.
270 virtual void notify(GCTaskManager* manager) = 0;
271 protected:
272 // Constructor.
273 NotifyDoneClosure() {
274 // Nothing to do.
275 }
276 // Virtual destructor because virtual methods.
277 virtual ~NotifyDoneClosure() {
278 // Nothing to do.
279 }
280 };
281
282 class GCTaskManager : public CHeapObj {
283 friend class ParCompactionManager;
284 friend class PSParallelCompact;
285 friend class PSScavenge;
286 friend class PSRefProcTaskExecutor;
287 friend class RefProcTaskExecutor;
288 private:
289 // Instance state.
290 NotifyDoneClosure* _ndc; // Notify on completion.
291 const uint _workers; // Number of workers.
292 Monitor* _monitor; // Notification of changes.
293 SynchronizedGCTaskQueue* _queue; // Queue of tasks.
294 GCTaskThread** _thread; // Array of worker threads.
295 uint _busy_workers; // Number of busy workers.
296 uint _blocking_worker; // The worker that's blocking.
297 bool* _resource_flag; // Array of flag per threads.
298 uint _delivered_tasks; // Count of delivered tasks.
299 uint _completed_tasks; // Count of completed tasks.
300 uint _barriers; // Count of barrier tasks.
301 uint _emptied_queue; // Times we emptied the queue.
302 NoopGCTask* _noop_task; // The NoopGCTask instance.
303 uint _noop_tasks; // Count of noop tasks.
304 public:
305 // Factory create and destroy methods.
306 static GCTaskManager* create(uint workers) {
307 return new GCTaskManager(workers);
308 }
309 static GCTaskManager* create(uint workers, NotifyDoneClosure* ndc) {
310 return new GCTaskManager(workers, ndc);
311 }
312 static void destroy(GCTaskManager* that) {
313 if (that != NULL) {
314 delete that;
315 }
316 }
317 // Accessors.
318 uint busy_workers() const {
319 return _busy_workers;
320 }
321 // Pun between Monitor* and Mutex*
322 Monitor* monitor() const {
323 return _monitor;
324 }
325 Monitor * lock() const {
326 return _monitor;
327 }
328 // Methods.
329 // Add the argument task to be run.
330 void add_task(GCTask* task);
331 // Add a list of tasks. Removes task from the argument list.
332 void add_list(GCTaskQueue* list);
333 // Claim a task for argument worker.
334 GCTask* get_task(uint which);
335 // Note the completion of a task by the argument worker.
336 void note_completion(uint which);
337 // Is the queue blocked from handing out new tasks?
338 bool is_blocked() const {
339 return (blocking_worker() != sentinel_worker());
340 }
341 // Request that all workers release their resources.
342 void release_all_resources();
343 // Ask if a particular worker should release its resources.
344 bool should_release_resources(uint which); // Predicate.
345 // Note the release of resources by the argument worker.
346 void note_release(uint which);
347 // Constants.
348 // A sentinel worker identifier.
349 static uint sentinel_worker() {
350 return (uint) -1; // Why isn't there a max_uint?
351 }
352
353 // Execute the task queue and wait for the completion.
354 void execute_and_wait(GCTaskQueue* list);
355
356 void print_task_time_stamps();
357 void print_threads_on(outputStream* st);
358 void threads_do(ThreadClosure* tc);
359
360 protected:
361 // Constructors. Clients use factory, but there might be subclasses.
362 // Create a GCTaskManager with the appropriate number of workers.
363 GCTaskManager(uint workers);
364 // Create a GCTaskManager that calls back when there's no more work.
365 GCTaskManager(uint workers, NotifyDoneClosure* ndc);
366 // Make virtual if necessary.
367 ~GCTaskManager();
368 // Accessors.
369 uint workers() const {
370 return _workers;
371 }
372 NotifyDoneClosure* notify_done_closure() const {
373 return _ndc;
374 }
375 SynchronizedGCTaskQueue* queue() const {
376 return _queue;
377 }
378 NoopGCTask* noop_task() const {
379 return _noop_task;
380 }
381 // Bounds-checking per-thread data accessors.
382 GCTaskThread* thread(uint which);
383 void set_thread(uint which, GCTaskThread* value);
384 bool resource_flag(uint which);
385 void set_resource_flag(uint which, bool value);
386 // Modifier methods with some semantics.
387 // Is any worker blocking handing out new tasks?
388 uint blocking_worker() const {
389 return _blocking_worker;
390 }
391 void set_blocking_worker(uint value) {
392 _blocking_worker = value;
393 }
394 void set_unblocked() {
395 set_blocking_worker(sentinel_worker());
396 }
397 // Count of busy workers.
398 void reset_busy_workers() {
399 _busy_workers = 0;
400 }
401 uint increment_busy_workers();
402 uint decrement_busy_workers();
403 // Count of tasks delivered to workers.
404 uint delivered_tasks() const {
405 return _delivered_tasks;
406 }
407 void increment_delivered_tasks() {
408 _delivered_tasks += 1;
409 }
410 void reset_delivered_tasks() {
411 _delivered_tasks = 0;
412 }
413 // Count of tasks completed by workers.
414 uint completed_tasks() const {
415 return _completed_tasks;
416 }
417 void increment_completed_tasks() {
418 _completed_tasks += 1;
419 }
420 void reset_completed_tasks() {
421 _completed_tasks = 0;
422 }
423 // Count of barrier tasks completed.
424 uint barriers() const {
425 return _barriers;
426 }
427 void increment_barriers() {
428 _barriers += 1;
429 }
430 void reset_barriers() {
431 _barriers = 0;
432 }
433 // Count of how many times the queue has emptied.
434 uint emptied_queue() const {
435 return _emptied_queue;
436 }
437 void increment_emptied_queue() {
438 _emptied_queue += 1;
439 }
440 void reset_emptied_queue() {
441 _emptied_queue = 0;
442 }
443 // Count of the number of noop tasks we've handed out,
444 // e.g., to handle resource release requests.
445 uint noop_tasks() const {
446 return _noop_tasks;
447 }
448 void increment_noop_tasks() {
449 _noop_tasks += 1;
450 }
451 void reset_noop_tasks() {
452 _noop_tasks = 0;
453 }
454 // Other methods.
455 void initialize();
456 };
457
458 //
459 // Some exemplary GCTasks.
460 //
461
462 // A noop task that does nothing,
463 // except take us around the GCTaskThread loop.
464 class NoopGCTask : public GCTask {
465 private:
466 const bool _is_c_heap_obj; // Is this a CHeapObj?
467 public:
468 // Factory create and destroy methods.
469 static NoopGCTask* create();
470 static NoopGCTask* create_on_c_heap();
471 static void destroy(NoopGCTask* that);
472 // Methods from GCTask.
473 void do_it(GCTaskManager* manager, uint which) {
474 // Nothing to do.
475 }
476 protected:
477 // Constructor.
478 NoopGCTask(bool on_c_heap) :
479 GCTask(GCTask::Kind::noop_task),
480 _is_c_heap_obj(on_c_heap) {
481 // Nothing to do.
482 }
483 // Destructor-like method.
484 void destruct();
485 // Accessors.
486 bool is_c_heap_obj() const {
487 return _is_c_heap_obj;
488 }
489 };
490
491 // A BarrierGCTask blocks other tasks from starting,
492 // and waits until it is the only task running.
493 class BarrierGCTask : public GCTask {
494 public:
495 // Factory create and destroy methods.
496 static BarrierGCTask* create() {
497 return new BarrierGCTask();
498 }
499 static void destroy(BarrierGCTask* that) {
500 if (that != NULL) {
501 that->destruct();
502 delete that;
503 }
504 }
505 // Methods from GCTask.
506 void do_it(GCTaskManager* manager, uint which);
507 protected:
508 // Constructor. Clients use factory, but there might be subclasses.
509 BarrierGCTask() :
510 GCTask(GCTask::Kind::barrier_task) {
511 // Nothing to do.
512 }
513 // Destructor-like method.
514 void destruct();
515 // Methods.
516 // Wait for this to be the only task running.
517 void do_it_internal(GCTaskManager* manager, uint which);
518 };
519
520 // A ReleasingBarrierGCTask is a BarrierGCTask
521 // that tells all the tasks to release their resource areas.
522 class ReleasingBarrierGCTask : public BarrierGCTask {
523 public:
524 // Factory create and destroy methods.
525 static ReleasingBarrierGCTask* create() {
526 return new ReleasingBarrierGCTask();
527 }
528 static void destroy(ReleasingBarrierGCTask* that) {
529 if (that != NULL) {
530 that->destruct();
531 delete that;
532 }
533 }
534 // Methods from GCTask.
535 void do_it(GCTaskManager* manager, uint which);
536 protected:
537 // Constructor. Clients use factory, but there might be subclasses.
538 ReleasingBarrierGCTask() :
539 BarrierGCTask() {
540 // Nothing to do.
541 }
542 // Destructor-like method.
543 void destruct();
544 };
545
546 // A NotifyingBarrierGCTask is a BarrierGCTask
547 // that calls a notification method when it is the only task running.
548 class NotifyingBarrierGCTask : public BarrierGCTask {
549 private:
550 // Instance state.
551 NotifyDoneClosure* _ndc; // The callback object.
552 public:
553 // Factory create and destroy methods.
554 static NotifyingBarrierGCTask* create(NotifyDoneClosure* ndc) {
555 return new NotifyingBarrierGCTask(ndc);
556 }
557 static void destroy(NotifyingBarrierGCTask* that) {
558 if (that != NULL) {
559 that->destruct();
560 delete that;
561 }
562 }
563 // Methods from GCTask.
564 void do_it(GCTaskManager* manager, uint which);
565 protected:
566 // Constructor. Clients use factory, but there might be subclasses.
567 NotifyingBarrierGCTask(NotifyDoneClosure* ndc) :
568 BarrierGCTask(),
569 _ndc(ndc) {
570 assert(notify_done_closure() != NULL, "can't notify on NULL");
571 }
572 // Destructor-like method.
573 void destruct();
574 // Accessor.
575 NotifyDoneClosure* notify_done_closure() const { return _ndc; }
576 };
577
578 // A WaitForBarrierGCTask is a BarrierGCTask
579 // with a method you can call to wait until
580 // the BarrierGCTask is done.
581 // This may cover many of the uses of NotifyingBarrierGCTasks.
582 class WaitForBarrierGCTask : public BarrierGCTask {
583 private:
584 // Instance state.
585 Monitor* _monitor; // Guard and notify changes.
586 bool _should_wait; // true=>wait, false=>proceed.
587 const bool _is_c_heap_obj; // Was allocated on the heap.
588 public:
589 virtual char* name() { return (char *) "waitfor-barrier-task"; }
590
591 // Factory create and destroy methods.
592 static WaitForBarrierGCTask* create();
593 static WaitForBarrierGCTask* create_on_c_heap();
594 static void destroy(WaitForBarrierGCTask* that);
595 // Methods.
596 void do_it(GCTaskManager* manager, uint which);
597 void wait_for();
598 protected:
599 // Constructor. Clients use factory, but there might be subclasses.
600 WaitForBarrierGCTask(bool on_c_heap);
601 // Destructor-like method.
602 void destruct();
603 // Accessors.
604 Monitor* monitor() const {
605 return _monitor;
606 }
607 bool should_wait() const {
608 return _should_wait;
609 }
610 void set_should_wait(bool value) {
611 _should_wait = value;
612 }
613 bool is_c_heap_obj() {
614 return _is_c_heap_obj;
615 }
616 };
617
618 class MonitorSupply : public AllStatic {
619 private:
620 // State.
621 // Control multi-threaded access.
622 static Mutex* _lock;
623 // The list of available Monitor*'s.
624 static GrowableArray<Monitor*>* _freelist;
625 public:
626 // Reserve a Monitor*.
627 static Monitor* reserve();
628 // Release a Monitor*.
629 static void release(Monitor* instance);
630 private:
631 // Accessors.
632 static Mutex* lock() {
633 return _lock;
634 }
635 static GrowableArray<Monitor*>* freelist() {
636 return _freelist;
637 }
638 };