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

Mon, 28 Jul 2008 15:30:23 -0700

author
jmasa
date
Mon, 28 Jul 2008 15:30:23 -0700
changeset 704
850fdf70db2b
parent 435
a61af66fc99e
child 1907
c18cbe5936b8
permissions
-rw-r--r--

Merge

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

mercurial