comparison src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.hpp @ 4095:bca17e38de00

6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads Summary: Select number of GC threads dynamically based on heap usage and number of Java threads Reviewed-by: johnc, ysr, jcoomes
author jmasa
date Tue, 09 Aug 2011 10:16:01 -0700
parents f95d63e2154a
children d2a62e0f25eb
comparison
equal deleted inserted replaced
4094:3a298e04d914 4095:bca17e38de00
43 class NoopGCTask; 43 class NoopGCTask;
44 class BarrierGCTask; 44 class BarrierGCTask;
45 class ReleasingBarrierGCTask; 45 class ReleasingBarrierGCTask;
46 class NotifyingBarrierGCTask; 46 class NotifyingBarrierGCTask;
47 class WaitForBarrierGCTask; 47 class WaitForBarrierGCTask;
48 class IdleGCTask;
48 // A free list of Monitor*'s. 49 // A free list of Monitor*'s.
49 class MonitorSupply; 50 class MonitorSupply;
50 51
51 // Forward declarations of classes referenced in this file via pointer. 52 // Forward declarations of classes referenced in this file via pointer.
52 class GCTaskThread; 53 class GCTaskThread;
62 public: 63 public:
63 enum kind { 64 enum kind {
64 unknown_task, 65 unknown_task,
65 ordinary_task, 66 ordinary_task,
66 barrier_task, 67 barrier_task,
67 noop_task 68 noop_task,
69 idle_task
68 }; 70 };
69 static const char* to_string(kind value); 71 static const char* to_string(kind value);
70 }; 72 };
71 private: 73 private:
72 // Instance state. 74 // Instance state.
105 bool is_barrier_task() const { 107 bool is_barrier_task() const {
106 return kind()==Kind::barrier_task; 108 return kind()==Kind::barrier_task;
107 } 109 }
108 bool is_noop_task() const { 110 bool is_noop_task() const {
109 return kind()==Kind::noop_task; 111 return kind()==Kind::noop_task;
112 }
113 bool is_idle_task() const {
114 return kind()==Kind::idle_task;
110 } 115 }
111 void print(const char* message) const PRODUCT_RETURN; 116 void print(const char* message) const PRODUCT_RETURN;
112 protected: 117 protected:
113 // Constructors: Only create subclasses. 118 // Constructors: Only create subclasses.
114 // An ordinary GCTask. 119 // An ordinary GCTask.
151 // These just examine the state of the queue. 156 // These just examine the state of the queue.
152 bool is_empty() const { 157 bool is_empty() const {
153 assert(((insert_end() == NULL && remove_end() == NULL) || 158 assert(((insert_end() == NULL && remove_end() == NULL) ||
154 (insert_end() != NULL && remove_end() != NULL)), 159 (insert_end() != NULL && remove_end() != NULL)),
155 "insert_end and remove_end don't match"); 160 "insert_end and remove_end don't match");
161 assert((insert_end() != NULL) || (_length == 0), "Not empty");
156 return insert_end() == NULL; 162 return insert_end() == NULL;
157 } 163 }
158 uint length() const { 164 uint length() const {
159 return _length; 165 return _length;
160 } 166 }
202 // Methods. 208 // Methods.
203 void initialize(); 209 void initialize();
204 GCTask* remove(); // Remove from remove end. 210 GCTask* remove(); // Remove from remove end.
205 GCTask* remove(GCTask* task); // Remove from the middle. 211 GCTask* remove(GCTask* task); // Remove from the middle.
206 void print(const char* message) const PRODUCT_RETURN; 212 void print(const char* message) const PRODUCT_RETURN;
213 // Debug support
214 void verify_length() const PRODUCT_RETURN;
207 }; 215 };
208 216
209 // A GCTaskQueue that can be synchronized. 217 // A GCTaskQueue that can be synchronized.
210 // This "has-a" GCTaskQueue and a mutex to do the exclusion. 218 // This "has-a" GCTaskQueue and a mutex to do the exclusion.
211 class SynchronizedGCTaskQueue : public CHeapObj { 219 class SynchronizedGCTaskQueue : public CHeapObj {
283 virtual ~NotifyDoneClosure() { 291 virtual ~NotifyDoneClosure() {
284 // Nothing to do. 292 // Nothing to do.
285 } 293 }
286 }; 294 };
287 295
296 // Dynamic number of GC threads
297 //
298 // GC threads wait in get_task() for work (i.e., a task) to perform.
299 // When the number of GC threads was static, the number of tasks
300 // created to do a job was equal to or greater than the maximum
301 // number of GC threads (ParallelGCThreads). The job might be divided
302 // into a number of tasks greater than the number of GC threads for
303 // load balancing (i.e., over partitioning). The last task to be
304 // executed by a GC thread in a job is a work stealing task. A
305 // GC thread that gets a work stealing task continues to execute
306 // that task until the job is done. In the static number of GC theads
307 // case, tasks are added to a queue (FIFO). The work stealing tasks are
308 // the last to be added. Once the tasks are added, the GC threads grab
309 // a task and go. A single thread can do all the non-work stealing tasks
310 // and then execute a work stealing and wait for all the other GC threads
311 // to execute their work stealing task.
312 // In the dynamic number of GC threads implementation, idle-tasks are
313 // created to occupy the non-participating or "inactive" threads. An
314 // idle-task makes the GC thread wait on a barrier that is part of the
315 // GCTaskManager. The GC threads that have been "idled" in a IdleGCTask
316 // are released once all the active GC threads have finished their work
317 // stealing tasks. The GCTaskManager does not wait for all the "idled"
318 // GC threads to resume execution. When those GC threads do resume
319 // execution in the course of the thread scheduling, they call get_tasks()
320 // as all the other GC threads do. Because all the "idled" threads are
321 // not required to execute in order to finish a job, it is possible for
322 // a GC thread to still be "idled" when the next job is started. Such
323 // a thread stays "idled" for the next job. This can result in a new
324 // job not having all the expected active workers. For example if on
325 // job requests 4 active workers out of a total of 10 workers so the
326 // remaining 6 are "idled", if the next job requests 6 active workers
327 // but all 6 of the "idled" workers are still idle, then the next job
328 // will only get 4 active workers.
329 // The implementation for the parallel old compaction phase has an
330 // added complication. In the static case parold partitions the chunks
331 // ready to be filled into stacks, one for each GC thread. A GC thread
332 // executing a draining task (drains the stack of ready chunks)
333 // claims a stack according to it's id (the unique ordinal value assigned
334 // to each GC thread). In the dynamic case not all GC threads will
335 // actively participate so stacks with ready to fill chunks can only be
336 // given to the active threads. An initial implementation chose stacks
337 // number 1-n to get the ready chunks and required that GC threads
338 // 1-n be the active workers. This was undesirable because it required
339 // certain threads to participate. In the final implementation a
340 // list of stacks equal in number to the active workers are filled
341 // with ready chunks. GC threads that participate get a stack from
342 // the task (DrainStacksCompactionTask), empty the stack, and then add it to a
343 // recycling list at the end of the task. If the same GC thread gets
344 // a second task, it gets a second stack to drain and returns it. The
345 // stacks are added to a recycling list so that later stealing tasks
346 // for this tasks can get a stack from the recycling list. Stealing tasks
347 // use the stacks in its work in a way similar to the draining tasks.
348 // A thread is not guaranteed to get anything but a stealing task and
349 // a thread that only gets a stealing task has to get a stack. A failed
350 // implementation tried to have the GC threads keep the stack they used
351 // during a draining task for later use in the stealing task but that didn't
352 // work because as noted a thread is not guaranteed to get a draining task.
353 //
354 // For PSScavenge and ParCompactionManager the GC threads are
355 // held in the GCTaskThread** _thread array in GCTaskManager.
356
357
288 class GCTaskManager : public CHeapObj { 358 class GCTaskManager : public CHeapObj {
289 friend class ParCompactionManager; 359 friend class ParCompactionManager;
290 friend class PSParallelCompact; 360 friend class PSParallelCompact;
291 friend class PSScavenge; 361 friend class PSScavenge;
292 friend class PSRefProcTaskExecutor; 362 friend class PSRefProcTaskExecutor;
293 friend class RefProcTaskExecutor; 363 friend class RefProcTaskExecutor;
364 friend class GCTaskThread;
365 friend class IdleGCTask;
294 private: 366 private:
295 // Instance state. 367 // Instance state.
296 NotifyDoneClosure* _ndc; // Notify on completion. 368 NotifyDoneClosure* _ndc; // Notify on completion.
297 const uint _workers; // Number of workers. 369 const uint _workers; // Number of workers.
298 Monitor* _monitor; // Notification of changes. 370 Monitor* _monitor; // Notification of changes.
299 SynchronizedGCTaskQueue* _queue; // Queue of tasks. 371 SynchronizedGCTaskQueue* _queue; // Queue of tasks.
300 GCTaskThread** _thread; // Array of worker threads. 372 GCTaskThread** _thread; // Array of worker threads.
373 uint _active_workers; // Number of active workers.
301 uint _busy_workers; // Number of busy workers. 374 uint _busy_workers; // Number of busy workers.
302 uint _blocking_worker; // The worker that's blocking. 375 uint _blocking_worker; // The worker that's blocking.
303 bool* _resource_flag; // Array of flag per threads. 376 bool* _resource_flag; // Array of flag per threads.
304 uint _delivered_tasks; // Count of delivered tasks. 377 uint _delivered_tasks; // Count of delivered tasks.
305 uint _completed_tasks; // Count of completed tasks. 378 uint _completed_tasks; // Count of completed tasks.
306 uint _barriers; // Count of barrier tasks. 379 uint _barriers; // Count of barrier tasks.
307 uint _emptied_queue; // Times we emptied the queue. 380 uint _emptied_queue; // Times we emptied the queue.
308 NoopGCTask* _noop_task; // The NoopGCTask instance. 381 NoopGCTask* _noop_task; // The NoopGCTask instance.
309 uint _noop_tasks; // Count of noop tasks. 382 uint _noop_tasks; // Count of noop tasks.
383 WaitForBarrierGCTask* _idle_inactive_task;// Task for inactive workers
384 volatile uint _idle_workers; // Number of idled workers
310 public: 385 public:
311 // Factory create and destroy methods. 386 // Factory create and destroy methods.
312 static GCTaskManager* create(uint workers) { 387 static GCTaskManager* create(uint workers) {
313 return new GCTaskManager(workers); 388 return new GCTaskManager(workers);
314 } 389 }
322 } 397 }
323 // Accessors. 398 // Accessors.
324 uint busy_workers() const { 399 uint busy_workers() const {
325 return _busy_workers; 400 return _busy_workers;
326 } 401 }
402 volatile uint idle_workers() const {
403 return _idle_workers;
404 }
327 // Pun between Monitor* and Mutex* 405 // Pun between Monitor* and Mutex*
328 Monitor* monitor() const { 406 Monitor* monitor() const {
329 return _monitor; 407 return _monitor;
330 } 408 }
331 Monitor * lock() const { 409 Monitor * lock() const {
332 return _monitor; 410 return _monitor;
411 }
412 WaitForBarrierGCTask* idle_inactive_task() {
413 return _idle_inactive_task;
333 } 414 }
334 // Methods. 415 // Methods.
335 // Add the argument task to be run. 416 // Add the argument task to be run.
336 void add_task(GCTask* task); 417 void add_task(GCTask* task);
337 // Add a list of tasks. Removes task from the argument list. 418 // Add a list of tasks. Removes task from the argument list.
348 void release_all_resources(); 429 void release_all_resources();
349 // Ask if a particular worker should release its resources. 430 // Ask if a particular worker should release its resources.
350 bool should_release_resources(uint which); // Predicate. 431 bool should_release_resources(uint which); // Predicate.
351 // Note the release of resources by the argument worker. 432 // Note the release of resources by the argument worker.
352 void note_release(uint which); 433 void note_release(uint which);
434 // Create IdleGCTasks for inactive workers and start workers
435 void task_idle_workers();
436 // Release the workers in IdleGCTasks
437 void release_idle_workers();
353 // Constants. 438 // Constants.
354 // A sentinel worker identifier. 439 // A sentinel worker identifier.
355 static uint sentinel_worker() { 440 static uint sentinel_worker() {
356 return (uint) -1; // Why isn't there a max_uint? 441 return (uint) -1; // Why isn't there a max_uint?
357 } 442 }
373 ~GCTaskManager(); 458 ~GCTaskManager();
374 // Accessors. 459 // Accessors.
375 uint workers() const { 460 uint workers() const {
376 return _workers; 461 return _workers;
377 } 462 }
463 void set_active_workers(uint v) {
464 assert(v <= _workers, "Trying to set more workers active than there are");
465 _active_workers = MIN2(v, _workers);
466 assert(v != 0, "Trying to set active workers to 0");
467 _active_workers = MAX2(1U, _active_workers);
468 }
469 // Sets the number of threads that will be used in a collection
470 void set_active_gang();
471
378 NotifyDoneClosure* notify_done_closure() const { 472 NotifyDoneClosure* notify_done_closure() const {
379 return _ndc; 473 return _ndc;
380 } 474 }
381 SynchronizedGCTaskQueue* queue() const { 475 SynchronizedGCTaskQueue* queue() const {
382 return _queue; 476 return _queue;
455 _noop_tasks += 1; 549 _noop_tasks += 1;
456 } 550 }
457 void reset_noop_tasks() { 551 void reset_noop_tasks() {
458 _noop_tasks = 0; 552 _noop_tasks = 0;
459 } 553 }
554 void increment_idle_workers() {
555 _idle_workers++;
556 }
557 void decrement_idle_workers() {
558 _idle_workers--;
559 }
460 // Other methods. 560 // Other methods.
461 void initialize(); 561 void initialize();
562
563 public:
564 // Return true if all workers are currently active.
565 bool all_workers_active() { return workers() == active_workers(); }
566 uint active_workers() const {
567 return _active_workers;
568 }
462 }; 569 };
463 570
464 // 571 //
465 // Some exemplary GCTasks. 572 // Some exemplary GCTasks.
466 // 573 //
473 public: 580 public:
474 // Factory create and destroy methods. 581 // Factory create and destroy methods.
475 static NoopGCTask* create(); 582 static NoopGCTask* create();
476 static NoopGCTask* create_on_c_heap(); 583 static NoopGCTask* create_on_c_heap();
477 static void destroy(NoopGCTask* that); 584 static void destroy(NoopGCTask* that);
585
586 virtual char* name() { return (char *)"noop task"; }
478 // Methods from GCTask. 587 // Methods from GCTask.
479 void do_it(GCTaskManager* manager, uint which) { 588 void do_it(GCTaskManager* manager, uint which) {
480 // Nothing to do. 589 // Nothing to do.
481 } 590 }
482 protected: 591 protected:
516 GCTask(GCTask::Kind::barrier_task) { 625 GCTask(GCTask::Kind::barrier_task) {
517 // Nothing to do. 626 // Nothing to do.
518 } 627 }
519 // Destructor-like method. 628 // Destructor-like method.
520 void destruct(); 629 void destruct();
630
631 virtual char* name() { return (char *)"barrier task"; }
521 // Methods. 632 // Methods.
522 // Wait for this to be the only task running. 633 // Wait for this to be the only task running.
523 void do_it_internal(GCTaskManager* manager, uint which); 634 void do_it_internal(GCTaskManager* manager, uint which);
524 }; 635 };
525 636
584 // A WaitForBarrierGCTask is a BarrierGCTask 695 // A WaitForBarrierGCTask is a BarrierGCTask
585 // with a method you can call to wait until 696 // with a method you can call to wait until
586 // the BarrierGCTask is done. 697 // the BarrierGCTask is done.
587 // This may cover many of the uses of NotifyingBarrierGCTasks. 698 // This may cover many of the uses of NotifyingBarrierGCTasks.
588 class WaitForBarrierGCTask : public BarrierGCTask { 699 class WaitForBarrierGCTask : public BarrierGCTask {
700 friend class GCTaskManager;
701 friend class IdleGCTask;
589 private: 702 private:
590 // Instance state. 703 // Instance state.
591 Monitor* _monitor; // Guard and notify changes. 704 Monitor* _monitor; // Guard and notify changes.
592 bool _should_wait; // true=>wait, false=>proceed. 705 volatile bool _should_wait; // true=>wait, false=>proceed.
593 const bool _is_c_heap_obj; // Was allocated on the heap. 706 const bool _is_c_heap_obj; // Was allocated on the heap.
594 public: 707 public:
595 virtual char* name() { return (char *) "waitfor-barrier-task"; } 708 virtual char* name() { return (char *) "waitfor-barrier-task"; }
596 709
597 // Factory create and destroy methods. 710 // Factory create and destroy methods.
598 static WaitForBarrierGCTask* create(); 711 static WaitForBarrierGCTask* create();
599 static WaitForBarrierGCTask* create_on_c_heap(); 712 static WaitForBarrierGCTask* create_on_c_heap();
600 static void destroy(WaitForBarrierGCTask* that); 713 static void destroy(WaitForBarrierGCTask* that);
601 // Methods. 714 // Methods.
602 void do_it(GCTaskManager* manager, uint which); 715 void do_it(GCTaskManager* manager, uint which);
603 void wait_for(); 716 void wait_for(bool reset);
717 void set_should_wait(bool value) {
718 _should_wait = value;
719 }
604 protected: 720 protected:
605 // Constructor. Clients use factory, but there might be subclasses. 721 // Constructor. Clients use factory, but there might be subclasses.
606 WaitForBarrierGCTask(bool on_c_heap); 722 WaitForBarrierGCTask(bool on_c_heap);
607 // Destructor-like method. 723 // Destructor-like method.
608 void destruct(); 724 void destruct();
611 return _monitor; 727 return _monitor;
612 } 728 }
613 bool should_wait() const { 729 bool should_wait() const {
614 return _should_wait; 730 return _should_wait;
615 } 731 }
616 void set_should_wait(bool value) {
617 _should_wait = value;
618 }
619 bool is_c_heap_obj() { 732 bool is_c_heap_obj() {
620 return _is_c_heap_obj; 733 return _is_c_heap_obj;
621 } 734 }
735 };
736
737 // Task that is used to idle a GC task when fewer than
738 // the maximum workers are wanted.
739 class IdleGCTask : public GCTask {
740 const bool _is_c_heap_obj; // Was allocated on the heap.
741 public:
742 bool is_c_heap_obj() {
743 return _is_c_heap_obj;
744 }
745 // Factory create and destroy methods.
746 static IdleGCTask* create();
747 static IdleGCTask* create_on_c_heap();
748 static void destroy(IdleGCTask* that);
749
750 virtual char* name() { return (char *)"idle task"; }
751 // Methods from GCTask.
752 virtual void do_it(GCTaskManager* manager, uint which);
753 protected:
754 // Constructor.
755 IdleGCTask(bool on_c_heap) :
756 GCTask(GCTask::Kind::idle_task),
757 _is_c_heap_obj(on_c_heap) {
758 // Nothing to do.
759 }
760 // Destructor-like method.
761 void destruct();
622 }; 762 };
623 763
624 class MonitorSupply : public AllStatic { 764 class MonitorSupply : public AllStatic {
625 private: 765 private:
626 // State. 766 // State.