src/share/vm/utilities/yieldingWorkgroup.hpp

Thu, 20 Nov 2008 16:56:09 -0800

author
ysr
date
Thu, 20 Nov 2008 16:56:09 -0800
changeset 888
c96030fff130
parent 777
37f87013dfd8
child 1907
c18cbe5936b8
permissions
-rw-r--r--

6684579: SoftReference processing can be made more efficient
Summary: For current soft-ref clearing policies, we can decide at marking time if a soft-reference will definitely not be cleared, postponing the decision of whether it will definitely be cleared to the final reference processing phase. This can be especially beneficial in the case of concurrent collectors where the marking is usually concurrent but reference processing is usually not.
Reviewed-by: jmasa

     1 /*
     2  * Copyright 2005 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  */
    26 // Forward declarations
    27 class YieldingFlexibleWorkGang;
    29 // Status of tasks
    30 enum Status {
    31     INACTIVE,
    32     ACTIVE,
    33     YIELDING,
    34     YIELDED,
    35     ABORTING,
    36     ABORTED,
    37     COMPLETING,
    38     COMPLETED
    39 };
    41 // Class YieldingFlexibleGangWorker:
    42 //   Several instances of this class run in parallel as workers for a gang.
    43 class YieldingFlexibleGangWorker: public GangWorker {
    44 public:
    45   // Ctor
    46   YieldingFlexibleGangWorker(AbstractWorkGang* gang, int id) :
    47     GangWorker(gang, id) { }
    49 public:
    50   YieldingFlexibleWorkGang* yf_gang() const
    51     { return (YieldingFlexibleWorkGang*)gang(); }
    53 protected: // Override from parent class
    54   virtual void loop();
    55 };
    57 // An abstract task to be worked on by a flexible work gang,
    58 // and where the workers will periodically yield, usually
    59 // in response to some condition that is signalled by means
    60 // that are specific to the task at hand.
    61 // You subclass this to supply your own work() method.
    62 // A second feature of this kind of work gang is that
    63 // it allows for the signalling of certain exceptional
    64 // conditions that may be encountered during the performance
    65 // of the task and that may require the task at hand to be
    66 // `aborted' forthwith. Finally, these gangs are `flexible'
    67 // in that they can operate at partial capacity with some
    68 // gang workers waiting on the bench; in other words, the
    69 // size of the active worker pool can flex (up to an apriori
    70 // maximum) in response to task requests at certain points.
    71 // The last part (the flexible part) has not yet been fully
    72 // fleshed out and is a work in progress.
    73 class YieldingFlexibleGangTask: public AbstractGangTask {
    74   Status _status;
    75   YieldingFlexibleWorkGang* _gang;
    76   int _actual_size;                      // size of gang obtained
    78 protected:
    79   int _requested_size;                   // size of gang requested
    81   // Constructor and desctructor: only construct subclasses.
    82   YieldingFlexibleGangTask(const char* name): AbstractGangTask(name),
    83     _status(INACTIVE),
    84     _gang(NULL),
    85     _requested_size(0) { }
    87   virtual ~YieldingFlexibleGangTask() { }
    89   friend class YieldingFlexibleWorkGang;
    90   friend class YieldingFlexibleGangWorker;
    91   NOT_PRODUCT(virtual bool is_YieldingFlexibleGang_task() const {
    92     return true;
    93   })
    95   void set_status(Status s) {
    96     _status = s;
    97   }
    98   YieldingFlexibleWorkGang* gang() {
    99     return _gang;
   100   }
   101   void set_gang(YieldingFlexibleWorkGang* gang) {
   102     assert(_gang == NULL || gang == NULL, "Clobber without intermediate reset?");
   103     _gang = gang;
   104   }
   106 public:
   107   // The abstract work method.
   108   // The argument tells you which member of the gang you are.
   109   virtual void work(int i) = 0;
   111   // Subclasses should call the parent's yield() method
   112   // after having done any work specific to the subclass.
   113   virtual void yield();
   115   // An abstract method supplied by
   116   // a concrete sub-class which is used by the coordinator
   117   // to do any "central yielding" work.
   118   virtual void coordinator_yield() = 0;
   120   // Subclasses should call the parent's abort() method
   121   // after having done any work specific to the sunbclass.
   122   virtual void abort();
   124   Status status()  const { return _status; }
   125   bool yielded()   const { return _status == YIELDED; }
   126   bool completed() const { return _status == COMPLETED; }
   127   bool aborted()   const { return _status == ABORTED; }
   128   bool active()    const { return _status == ACTIVE; }
   130   int requested_size() const { return _requested_size; }
   131   int actual_size()    const { return _actual_size; }
   133   void set_requested_size(int sz) { _requested_size = sz; }
   134   void set_actual_size(int sz)    { _actual_size    = sz; }
   135 };
   137 // Class YieldingWorkGang: A subclass of WorkGang.
   138 // In particular, a YieldingWorkGang is made up of
   139 // YieldingGangWorkers, and provides infrastructure
   140 // supporting yielding to the "GangOverseer",
   141 // being the thread that orchestrates the WorkGang via run_task().
   142 class YieldingFlexibleWorkGang: public AbstractWorkGang {
   143   // Here's the public interface to this class.
   144 public:
   145   // Constructor and destructor.
   146   YieldingFlexibleWorkGang(const char* name, int workers,
   147                            bool are_GC_task_threads);
   149   YieldingFlexibleGangTask* yielding_task() const {
   150     assert(task() == NULL || task()->is_YieldingFlexibleGang_task(),
   151            "Incorrect cast");
   152     return (YieldingFlexibleGangTask*)task();
   153   }
   154   // Run a task; returns when the task is done, or the workers yield,
   155   // or the task is aborted, or the work gang is terminated via stop().
   156   // A task that has been yielded can be continued via this same interface
   157   // by using the same task repeatedly as the argument to the call.
   158   // It is expected that the YieldingFlexibleGangTask carries the appropriate
   159   // continuation information used by workers to continue the task
   160   // from its last yield point. Thus, a completed task will return
   161   // immediately with no actual work having been done by the workers.
   162   void run_task(AbstractGangTask* task) {
   163     guarantee(false, "Use start_task instead");
   164   }
   165   void start_task(YieldingFlexibleGangTask* new_task);
   166   void continue_task(YieldingFlexibleGangTask* gang_task);
   168   // Abort a currently running task, if any; returns when all the workers
   169   // have stopped working on the current task and have returned to their
   170   // waiting stations.
   171   void abort_task();
   173   // Yield: workers wait at their current working stations
   174   // until signalled to proceed by the overseer.
   175   void yield();
   177   // Abort: workers are expected to return to their waiting
   178   // stations, whence they are ready for the next task dispatched
   179   // by the overseer.
   180   void abort();
   182 private:
   183   // The currently active workers in this gang.
   184   // This is a number that is dynamically adjusted by
   185   // the run_task() method at each subsequent invocation,
   186   // using data in the YieldingFlexibleGangTask.
   187   int _active_workers;
   188   int _yielded_workers;
   189   void wait_for_gang();
   191 public:
   192   // Accessors for fields
   193   int active_workers() const {
   194     return _active_workers;
   195   }
   197   int yielded_workers() const {
   198     return _yielded_workers;
   199   }
   201 private:
   202   friend class YieldingFlexibleGangWorker;
   203   void reset(); // NYI
   204 };

mercurial