1 /* 2 * Copyright (c) 2002, 2015, 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 */ 24 25 #ifndef SHARE_VM_GC_PARALLEL_GCTASKMANAGER_HPP 26 #define SHARE_VM_GC_PARALLEL_GCTASKMANAGER_HPP 27 28 #include "runtime/mutex.hpp" 29 #include "utilities/growableArray.hpp" 30 31 // 32 // The GCTaskManager is a queue of GCTasks, and accessors 33 // to allow the queue to be accessed from many threads. 34 // 35 36 // Forward declarations of types defined in this file. 37 class GCTask; 38 class GCTaskQueue; 39 class SynchronizedGCTaskQueue; 40 class GCTaskManager; 41 class NotifyDoneClosure; 42 // Some useful subclasses of GCTask. You can also make up your own. 43 class NoopGCTask; 44 class BarrierGCTask; 45 class ReleasingBarrierGCTask; 46 class NotifyingBarrierGCTask; 47 class WaitForBarrierGCTask; 48 class IdleGCTask; 49 // A free list of Monitor*'s. 50 class MonitorSupply; 51 52 // Forward declarations of classes referenced in this file via pointer. 53 class GCTaskThread; 54 class Mutex; 55 class Monitor; 56 class ThreadClosure; 57 58 // The abstract base GCTask. 59 class GCTask : public ResourceObj { 60 public: 61 // Known kinds of GCTasks, for predicates. 62 class Kind : AllStatic { 63 public: 64 enum kind { 65 unknown_task, 66 ordinary_task, 67 barrier_task, 68 noop_task, 69 idle_task 70 }; 71 static const char* to_string(kind value); 72 }; 73 private: 74 // Instance state. 75 const Kind::kind _kind; // For runtime type checking. 76 const uint _affinity; // Which worker should run task. 77 GCTask* _newer; // Tasks are on doubly-linked ... 78 GCTask* _older; // ... lists. 79 public: 80 virtual char* name() { return (char *)"task"; } 81 82 // Abstract do_it method 83 virtual void do_it(GCTaskManager* manager, uint which) = 0; 84 // Accessors 85 Kind::kind kind() const { 86 return _kind; 87 } 88 uint affinity() const { 89 return _affinity; 90 } 91 GCTask* newer() const { 92 return _newer; 93 } 94 void set_newer(GCTask* n) { 95 _newer = n; 96 } 97 GCTask* older() const { 98 return _older; 99 } 100 void set_older(GCTask* p) { 101 _older = p; 102 } 103 // Predicates. 104 bool is_ordinary_task() const { 105 return kind()==Kind::ordinary_task; 106 } 107 bool is_barrier_task() const { 108 return kind()==Kind::barrier_task; 109 } 110 bool is_noop_task() const { 111 return kind()==Kind::noop_task; 112 } 113 bool is_idle_task() const { 114 return kind()==Kind::idle_task; 115 } 116 void print(const char* message) const PRODUCT_RETURN; 117 protected: 118 // Constructors: Only create subclasses. 119 // An ordinary GCTask. 120 GCTask(); 121 // A GCTask of a particular kind, usually barrier or noop. 122 GCTask(Kind::kind kind); 123 // An ordinary GCTask with an affinity. 124 GCTask(uint affinity); 125 // A GCTask of a particular kind, with and affinity. 126 GCTask(Kind::kind kind, uint affinity); 127 // We want a virtual destructor because virtual methods, 128 // but since ResourceObj's don't have their destructors 129 // called, we don't have one at all. Instead we have 130 // this method, which gets called by subclasses to clean up. 131 virtual void destruct(); 132 // Methods. 133 void initialize(); 134 }; 135 136 // A doubly-linked list of GCTasks. 137 // The list is not synchronized, because sometimes we want to 138 // build up a list and then make it available to other threads. 139 // See also: SynchronizedGCTaskQueue. 140 class GCTaskQueue : public ResourceObj { 141 private: 142 // Instance state. 143 GCTask* _insert_end; // Tasks are enqueued at this end. 144 GCTask* _remove_end; // Tasks are dequeued from this end. 145 uint _length; // The current length of the queue. 146 const bool _is_c_heap_obj; // Is this a CHeapObj? 147 public: 148 // Factory create and destroy methods. 149 // Create as ResourceObj. 150 static GCTaskQueue* create(); 151 // Create as CHeapObj. 152 static GCTaskQueue* create_on_c_heap(); 153 // Destroyer. 154 static void destroy(GCTaskQueue* that); 155 // Accessors. 156 // These just examine the state of the queue. 157 bool is_empty() const { 158 assert(((insert_end() == NULL && remove_end() == NULL) || 159 (insert_end() != NULL && remove_end() != NULL)), 160 "insert_end and remove_end don't match"); 161 assert((insert_end() != NULL) || (_length == 0), "Not empty"); 162 return insert_end() == NULL; 163 } 164 uint length() const { 165 return _length; 166 } 167 // Methods. 168 // Enqueue one task. 169 void enqueue(GCTask* task); 170 // Enqueue a list of tasks. Empties the argument list. 171 void enqueue(GCTaskQueue* list); 172 // Dequeue one task. 173 GCTask* dequeue(); 174 // Dequeue one task, preferring one with affinity. 175 GCTask* dequeue(uint affinity); 176 protected: 177 // Constructor. Clients use factory, but there might be subclasses. 178 GCTaskQueue(bool on_c_heap); 179 // Destructor-like method. 180 // Because ResourceMark doesn't call destructors. 181 // This method cleans up like one. 182 virtual void destruct(); 183 // Accessors. 184 GCTask* insert_end() const { 185 return _insert_end; 186 } 187 void set_insert_end(GCTask* value) { 188 _insert_end = value; 189 } 190 GCTask* remove_end() const { 191 return _remove_end; 192 } 193 void set_remove_end(GCTask* value) { 194 _remove_end = value; 195 } 196 void increment_length() { 197 _length += 1; 198 } 199 void decrement_length() { 200 _length -= 1; 201 } 202 void set_length(uint value) { 203 _length = value; 204 } 205 bool is_c_heap_obj() const { 206 return _is_c_heap_obj; 207 } 208 // Methods. 209 void initialize(); 210 GCTask* remove(); // Remove from remove end. 211 GCTask* remove(GCTask* task); // Remove from the middle. 212 void print(const char* message) const PRODUCT_RETURN; 213 // Debug support 214 void verify_length() const PRODUCT_RETURN; 215 }; 216 217 // A GCTaskQueue that can be synchronized. 218 // This "has-a" GCTaskQueue and a mutex to do the exclusion. 219 class SynchronizedGCTaskQueue : public CHeapObj<mtGC> { 220 private: 221 // Instance state. 222 GCTaskQueue* _unsynchronized_queue; // Has-a unsynchronized queue. 223 Monitor * _lock; // Lock to control access. 224 public: 225 // Factory create and destroy methods. 226 static SynchronizedGCTaskQueue* create(GCTaskQueue* queue, Monitor * lock) { 227 return new SynchronizedGCTaskQueue(queue, lock); 228 } 229 static void destroy(SynchronizedGCTaskQueue* that) { 230 if (that != NULL) { 231 delete that; 232 } 233 } 234 // Accessors 235 GCTaskQueue* unsynchronized_queue() const { 236 return _unsynchronized_queue; 237 } 238 Monitor * lock() const { 239 return _lock; 240 } 241 // GCTaskQueue wrapper methods. 242 // These check that you hold the lock 243 // and then call the method on the queue. 244 bool is_empty() const { 245 guarantee(own_lock(), "don't own the lock"); 246 return unsynchronized_queue()->is_empty(); 247 } 248 void enqueue(GCTask* task) { 249 guarantee(own_lock(), "don't own the lock"); 250 unsynchronized_queue()->enqueue(task); 251 } 252 void enqueue(GCTaskQueue* list) { 253 guarantee(own_lock(), "don't own the lock"); 254 unsynchronized_queue()->enqueue(list); 255 } 256 GCTask* dequeue() { 257 guarantee(own_lock(), "don't own the lock"); 258 return unsynchronized_queue()->dequeue(); 259 } 260 GCTask* dequeue(uint affinity) { 261 guarantee(own_lock(), "don't own the lock"); 262 return unsynchronized_queue()->dequeue(affinity); 263 } 264 uint length() const { 265 guarantee(own_lock(), "don't own the lock"); 266 return unsynchronized_queue()->length(); 267 } 268 // For guarantees. 269 bool own_lock() const { 270 return lock()->owned_by_self(); 271 } 272 protected: 273 // Constructor. Clients use factory, but there might be subclasses. 274 SynchronizedGCTaskQueue(GCTaskQueue* queue, Monitor * lock); 275 // Destructor. Not virtual because no virtuals. 276 ~SynchronizedGCTaskQueue(); 277 }; 278 279 // This is an abstract base class for getting notifications 280 // when a GCTaskManager is done. 281 class NotifyDoneClosure : public CHeapObj<mtGC> { 282 public: 283 // The notification callback method. 284 virtual void notify(GCTaskManager* manager) = 0; 285 protected: 286 // Constructor. 287 NotifyDoneClosure() { 288 // Nothing to do. 289 } 290 // Virtual destructor because virtual methods. 291 virtual ~NotifyDoneClosure() { 292 // Nothing to do. 293 } 294 }; 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 threads 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 358 class GCTaskManager : public CHeapObj<mtGC> { 359 friend class ParCompactionManager; 360 friend class PSParallelCompact; 361 friend class PSScavenge; 362 friend class PSRefProcTaskExecutor; 363 friend class RefProcTaskExecutor; 364 friend class GCTaskThread; 365 friend class IdleGCTask; 366 private: 367 // Instance state. 368 NotifyDoneClosure* _ndc; // Notify on completion. 369 const uint _workers; // Number of workers. 370 Monitor* _monitor; // Notification of changes. 371 SynchronizedGCTaskQueue* _queue; // Queue of tasks. 372 GCTaskThread** _thread; // Array of worker threads. 373 uint _active_workers; // Number of active workers. 374 uint _busy_workers; // Number of busy workers. 375 uint _blocking_worker; // The worker that's blocking. 376 bool* _resource_flag; // Array of flag per threads. 377 uint _delivered_tasks; // Count of delivered tasks. 378 uint _completed_tasks; // Count of completed tasks. 379 uint _barriers; // Count of barrier tasks. 380 uint _emptied_queue; // Times we emptied the queue. 381 NoopGCTask* _noop_task; // The NoopGCTask instance. 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 385 public: 386 // Factory create and destroy methods. 387 static GCTaskManager* create(uint workers) { 388 return new GCTaskManager(workers); 389 } 390 static GCTaskManager* create(uint workers, NotifyDoneClosure* ndc) { 391 return new GCTaskManager(workers, ndc); 392 } 393 static void destroy(GCTaskManager* that) { 394 if (that != NULL) { 395 delete that; 396 } 397 } 398 // Accessors. 399 uint busy_workers() const { 400 return _busy_workers; 401 } 402 volatile uint idle_workers() const { 403 return _idle_workers; 404 } 405 // Pun between Monitor* and Mutex* 406 Monitor* monitor() const { 407 return _monitor; 408 } 409 Monitor * lock() const { 410 return _monitor; 411 } 412 WaitForBarrierGCTask* idle_inactive_task() { 413 return _idle_inactive_task; 414 } 415 // Methods. 416 // Add the argument task to be run. 417 void add_task(GCTask* task); 418 // Add a list of tasks. Removes task from the argument list. 419 void add_list(GCTaskQueue* list); 420 // Claim a task for argument worker. 421 GCTask* get_task(uint which); 422 // Note the completion of a task by the argument worker. 423 void note_completion(uint which); 424 // Is the queue blocked from handing out new tasks? 425 bool is_blocked() const { 426 return (blocking_worker() != sentinel_worker()); 427 } 428 // Request that all workers release their resources. 429 void release_all_resources(); 430 // Ask if a particular worker should release its resources. 431 bool should_release_resources(uint which); // Predicate. 432 // Note the release of resources by the argument worker. 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(); 438 // Constants. 439 // A sentinel worker identifier. 440 static uint sentinel_worker() { 441 return (uint) -1; // Why isn't there a max_uint? 442 } 443 444 // Execute the task queue and wait for the completion. 445 void execute_and_wait(GCTaskQueue* list); 446 447 void print_task_time_stamps(); 448 void print_threads_on(outputStream* st); 449 void threads_do(ThreadClosure* tc); 450 451 protected: 452 // Constructors. Clients use factory, but there might be subclasses. 453 // Create a GCTaskManager with the appropriate number of workers. 454 GCTaskManager(uint workers); 455 // Create a GCTaskManager that calls back when there's no more work. 456 GCTaskManager(uint workers, NotifyDoneClosure* ndc); 457 // Make virtual if necessary. 458 ~GCTaskManager(); 459 // Accessors. 460 uint workers() const { 461 return _workers; 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 472 NotifyDoneClosure* notify_done_closure() const { 473 return _ndc; 474 } 475 SynchronizedGCTaskQueue* queue() const { 476 return _queue; 477 } 478 NoopGCTask* noop_task() const { 479 return _noop_task; 480 } 481 // Bounds-checking per-thread data accessors. 482 GCTaskThread* thread(uint which); 483 void set_thread(uint which, GCTaskThread* value); 484 bool resource_flag(uint which); 485 void set_resource_flag(uint which, bool value); 486 // Modifier methods with some semantics. 487 // Is any worker blocking handing out new tasks? 488 uint blocking_worker() const { 489 return _blocking_worker; 490 } 491 void set_blocking_worker(uint value) { 492 _blocking_worker = value; 493 } 494 void set_unblocked() { 495 set_blocking_worker(sentinel_worker()); 496 } 497 // Count of busy workers. 498 void reset_busy_workers() { 499 _busy_workers = 0; 500 } 501 uint increment_busy_workers(); 502 uint decrement_busy_workers(); 503 // Count of tasks delivered to workers. 504 uint delivered_tasks() const { 505 return _delivered_tasks; 506 } 507 void increment_delivered_tasks() { 508 _delivered_tasks += 1; 509 } 510 void reset_delivered_tasks() { 511 _delivered_tasks = 0; 512 } 513 // Count of tasks completed by workers. 514 uint completed_tasks() const { 515 return _completed_tasks; 516 } 517 void increment_completed_tasks() { 518 _completed_tasks += 1; 519 } 520 void reset_completed_tasks() { 521 _completed_tasks = 0; 522 } 523 // Count of barrier tasks completed. 524 uint barriers() const { 525 return _barriers; 526 } 527 void increment_barriers() { 528 _barriers += 1; 529 } 530 void reset_barriers() { 531 _barriers = 0; 532 } 533 // Count of how many times the queue has emptied. 534 uint emptied_queue() const { 535 return _emptied_queue; 536 } 537 void increment_emptied_queue() { 538 _emptied_queue += 1; 539 } 540 void reset_emptied_queue() { 541 _emptied_queue = 0; 542 } 543 // Count of the number of noop tasks we've handed out, 544 // e.g., to handle resource release requests. 545 uint noop_tasks() const { 546 return _noop_tasks; 547 } 548 void increment_noop_tasks() { 549 _noop_tasks += 1; 550 } 551 void reset_noop_tasks() { 552 _noop_tasks = 0; 553 } 554 void increment_idle_workers() { 555 _idle_workers++; 556 } 557 void decrement_idle_workers() { 558 _idle_workers--; 559 } 560 // Other methods. 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 } 569 }; 570 571 // 572 // Some exemplary GCTasks. 573 // 574 575 // A noop task that does nothing, 576 // except take us around the GCTaskThread loop. 577 class NoopGCTask : public GCTask { 578 private: 579 const bool _is_c_heap_obj; // Is this a CHeapObj? 580 public: 581 // Factory create and destroy methods. 582 static NoopGCTask* create(); 583 static NoopGCTask* create_on_c_heap(); 584 static void destroy(NoopGCTask* that); 585 586 virtual char* name() { return (char *)"noop task"; } 587 // Methods from GCTask. 588 void do_it(GCTaskManager* manager, uint which) { 589 // Nothing to do. 590 } 591 protected: 592 // Constructor. 593 NoopGCTask(bool on_c_heap) : 594 GCTask(GCTask::Kind::noop_task), 595 _is_c_heap_obj(on_c_heap) { 596 // Nothing to do. 597 } 598 // Destructor-like method. 599 void destruct(); 600 // Accessors. 601 bool is_c_heap_obj() const { 602 return _is_c_heap_obj; 603 } 604 }; 605 606 // A BarrierGCTask blocks other tasks from starting, 607 // and waits until it is the only task running. 608 class BarrierGCTask : public GCTask { 609 public: 610 // Factory create and destroy methods. 611 static BarrierGCTask* create() { 612 return new BarrierGCTask(); 613 } 614 static void destroy(BarrierGCTask* that) { 615 if (that != NULL) { 616 that->destruct(); 617 delete that; 618 } 619 } 620 // Methods from GCTask. 621 void do_it(GCTaskManager* manager, uint which); 622 protected: 623 // Constructor. Clients use factory, but there might be subclasses. 624 BarrierGCTask() : 625 GCTask(GCTask::Kind::barrier_task) { 626 // Nothing to do. 627 } 628 // Destructor-like method. 629 void destruct(); 630 631 virtual char* name() { return (char *)"barrier task"; } 632 // Methods. 633 // Wait for this to be the only task running. 634 void do_it_internal(GCTaskManager* manager, uint which); 635 }; 636 637 // A ReleasingBarrierGCTask is a BarrierGCTask 638 // that tells all the tasks to release their resource areas. 639 class ReleasingBarrierGCTask : public BarrierGCTask { 640 public: 641 // Factory create and destroy methods. 642 static ReleasingBarrierGCTask* create() { 643 return new ReleasingBarrierGCTask(); 644 } 645 static void destroy(ReleasingBarrierGCTask* that) { 646 if (that != NULL) { 647 that->destruct(); 648 delete that; 649 } 650 } 651 // Methods from GCTask. 652 void do_it(GCTaskManager* manager, uint which); 653 protected: 654 // Constructor. Clients use factory, but there might be subclasses. 655 ReleasingBarrierGCTask() : 656 BarrierGCTask() { 657 // Nothing to do. 658 } 659 // Destructor-like method. 660 void destruct(); 661 }; 662 663 // A NotifyingBarrierGCTask is a BarrierGCTask 664 // that calls a notification method when it is the only task running. 665 class NotifyingBarrierGCTask : public BarrierGCTask { 666 private: 667 // Instance state. 668 NotifyDoneClosure* _ndc; // The callback object. 669 public: 670 // Factory create and destroy methods. 671 static NotifyingBarrierGCTask* create(NotifyDoneClosure* ndc) { 672 return new NotifyingBarrierGCTask(ndc); 673 } 674 static void destroy(NotifyingBarrierGCTask* that) { 675 if (that != NULL) { 676 that->destruct(); 677 delete that; 678 } 679 } 680 // Methods from GCTask. 681 void do_it(GCTaskManager* manager, uint which); 682 protected: 683 // Constructor. Clients use factory, but there might be subclasses. 684 NotifyingBarrierGCTask(NotifyDoneClosure* ndc) : 685 BarrierGCTask(), 686 _ndc(ndc) { 687 assert(notify_done_closure() != NULL, "can't notify on NULL"); 688 } 689 // Destructor-like method. 690 void destruct(); 691 // Accessor. 692 NotifyDoneClosure* notify_done_closure() const { return _ndc; } 693 }; 694 695 // A WaitForBarrierGCTask is a BarrierGCTask 696 // with a method you can call to wait until 697 // the BarrierGCTask is done. 698 // This may cover many of the uses of NotifyingBarrierGCTasks. 699 class WaitForBarrierGCTask : public BarrierGCTask { 700 friend class GCTaskManager; 701 friend class IdleGCTask; 702 private: 703 // Instance state. 704 Monitor* _monitor; // Guard and notify changes. 705 volatile bool _should_wait; // true=>wait, false=>proceed. 706 const bool _is_c_heap_obj; // Was allocated on the heap. 707 public: 708 virtual char* name() { return (char *) "waitfor-barrier-task"; } 709 710 // Factory create and destroy methods. 711 static WaitForBarrierGCTask* create(); 712 static WaitForBarrierGCTask* create_on_c_heap(); 713 static void destroy(WaitForBarrierGCTask* that); 714 // Methods. 715 void do_it(GCTaskManager* manager, uint which); 716 void wait_for(bool reset); 717 void set_should_wait(bool value) { 718 _should_wait = value; 719 } 720 protected: 721 // Constructor. Clients use factory, but there might be subclasses. 722 WaitForBarrierGCTask(bool on_c_heap); 723 // Destructor-like method. 724 void destruct(); 725 // Accessors. 726 Monitor* monitor() const { 727 return _monitor; 728 } 729 bool should_wait() const { 730 return _should_wait; 731 } 732 bool is_c_heap_obj() { 733 return _is_c_heap_obj; 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(); 762 }; 763 764 class MonitorSupply : public AllStatic { 765 private: 766 // State. 767 // Control multi-threaded access. 768 static Mutex* _lock; 769 // The list of available Monitor*'s. 770 static GrowableArray<Monitor*>* _freelist; 771 public: 772 // Reserve a Monitor*. 773 static Monitor* reserve(); 774 // Release a Monitor*. 775 static void release(Monitor* instance); 776 private: 777 // Accessors. 778 static Mutex* lock() { 779 return _lock; 780 } 781 static GrowableArray<Monitor*>* freelist() { 782 return _freelist; 783 } 784 }; 785 786 #endif // SHARE_VM_GC_PARALLEL_GCTASKMANAGER_HPP