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

Tue, 23 Nov 2010 13:22:55 -0800

author
stefank
date
Tue, 23 Nov 2010 13:22:55 -0800
changeset 2314
f95d63e2154a
parent 1907
c18cbe5936b8
child 3294
bca17e38de00
permissions
-rw-r--r--

6989984: Use standard include model for Hospot
Summary: Replaced MakeDeps and the includeDB files with more standardized solutions.
Reviewed-by: coleenp, kvn, kamg

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

mercurial