src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.hpp

Thu, 16 Jun 2011 15:51:57 -0400

author
tonyp
date
Thu, 16 Jun 2011 15:51:57 -0400
changeset 2971
c9ca3f51cf41
parent 2314
f95d63e2154a
child 3294
bca17e38de00
permissions
-rw-r--r--

6994322: Remove the is_tlab and is_noref / is_large_noref parameters from the CollectedHeap
Summary: Remove two unused parameters from the mem_allocate() method and update its uses accordingly.
Reviewed-by: stefank, johnc

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

mercurial