hotspot/src/share/vm/utilities/yieldingWorkgroup.hpp
changeset 6759 67b1a69ef5aa
parent 5547 f4b087cbb361
child 6763 711b8a44c4dd
equal deleted inserted replaced
6451:516540f1f076 6759:67b1a69ef5aa
     1 /*
     1 /*
     2  * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2005, 2010 Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    50   YieldingFlexibleWorkGang* yf_gang() const
    50   YieldingFlexibleWorkGang* yf_gang() const
    51     { return (YieldingFlexibleWorkGang*)gang(); }
    51     { return (YieldingFlexibleWorkGang*)gang(); }
    52 
    52 
    53 protected: // Override from parent class
    53 protected: // Override from parent class
    54   virtual void loop();
    54   virtual void loop();
       
    55 };
       
    56 
       
    57 class FlexibleGangTask: public AbstractGangTask {
       
    58   int _actual_size;                      // size of gang obtained
       
    59 protected:
       
    60   int _requested_size;                   // size of gang requested
       
    61 public:
       
    62  FlexibleGangTask(const char* name): AbstractGangTask(name),
       
    63     _requested_size(0) {}
       
    64 
       
    65   // The abstract work method.
       
    66   // The argument tells you which member of the gang you are.
       
    67   virtual void work(int i) = 0;
       
    68 
       
    69   int requested_size() const { return _requested_size; }
       
    70   int actual_size()    const { return _actual_size; }
       
    71 
       
    72   void set_requested_size(int sz) { _requested_size = sz; }
       
    73   void set_actual_size(int sz)    { _actual_size    = sz; }
    55 };
    74 };
    56 
    75 
    57 // An abstract task to be worked on by a flexible work gang,
    76 // An abstract task to be worked on by a flexible work gang,
    58 // and where the workers will periodically yield, usually
    77 // and where the workers will periodically yield, usually
    59 // in response to some condition that is signalled by means
    78 // in response to some condition that is signalled by means
    68 // gang workers waiting on the bench; in other words, the
    87 // gang workers waiting on the bench; in other words, the
    69 // size of the active worker pool can flex (up to an apriori
    88 // size of the active worker pool can flex (up to an apriori
    70 // maximum) in response to task requests at certain points.
    89 // maximum) in response to task requests at certain points.
    71 // The last part (the flexible part) has not yet been fully
    90 // The last part (the flexible part) has not yet been fully
    72 // fleshed out and is a work in progress.
    91 // fleshed out and is a work in progress.
    73 class YieldingFlexibleGangTask: public AbstractGangTask {
    92 class YieldingFlexibleGangTask: public FlexibleGangTask {
    74   Status _status;
    93   Status _status;
    75   YieldingFlexibleWorkGang* _gang;
    94   YieldingFlexibleWorkGang* _gang;
    76   int _actual_size;                      // size of gang obtained
       
    77 
    95 
    78 protected:
    96 protected:
    79   int _requested_size;                   // size of gang requested
       
    80 
       
    81   // Constructor and desctructor: only construct subclasses.
    97   // Constructor and desctructor: only construct subclasses.
    82   YieldingFlexibleGangTask(const char* name): AbstractGangTask(name),
    98   YieldingFlexibleGangTask(const char* name): FlexibleGangTask(name),
    83     _status(INACTIVE),
    99     _status(INACTIVE),
    84     _gang(NULL),
   100     _gang(NULL) { }
    85     _requested_size(0) { }
       
    86 
   101 
    87   virtual ~YieldingFlexibleGangTask() { }
   102   virtual ~YieldingFlexibleGangTask() { }
    88 
   103 
    89   friend class YieldingFlexibleWorkGang;
   104   friend class YieldingFlexibleWorkGang;
    90   friend class YieldingFlexibleGangWorker;
   105   friend class YieldingFlexibleGangWorker;
   124   Status status()  const { return _status; }
   139   Status status()  const { return _status; }
   125   bool yielded()   const { return _status == YIELDED; }
   140   bool yielded()   const { return _status == YIELDED; }
   126   bool completed() const { return _status == COMPLETED; }
   141   bool completed() const { return _status == COMPLETED; }
   127   bool aborted()   const { return _status == ABORTED; }
   142   bool aborted()   const { return _status == ABORTED; }
   128   bool active()    const { return _status == ACTIVE; }
   143   bool active()    const { return _status == ACTIVE; }
   129 
   144 };
   130   int requested_size() const { return _requested_size; }
       
   131   int actual_size()    const { return _actual_size; }
       
   132 
       
   133   void set_requested_size(int sz) { _requested_size = sz; }
       
   134   void set_actual_size(int sz)    { _actual_size    = sz; }
       
   135 };
       
   136 
       
   137 // Class YieldingWorkGang: A subclass of WorkGang.
   145 // Class YieldingWorkGang: A subclass of WorkGang.
   138 // In particular, a YieldingWorkGang is made up of
   146 // In particular, a YieldingWorkGang is made up of
   139 // YieldingGangWorkers, and provides infrastructure
   147 // YieldingGangWorkers, and provides infrastructure
   140 // supporting yielding to the "GangOverseer",
   148 // supporting yielding to the "GangOverseer",
   141 // being the thread that orchestrates the WorkGang via run_task().
   149 // being the thread that orchestrates the WorkGang via run_task().
   142 class YieldingFlexibleWorkGang: public AbstractWorkGang {
   150 class YieldingFlexibleWorkGang: public FlexibleWorkGang {
   143   // Here's the public interface to this class.
   151   // Here's the public interface to this class.
   144 public:
   152 public:
   145   // Constructor and destructor.
   153   // Constructor and destructor.
   146   YieldingFlexibleWorkGang(const char* name, int workers,
   154   YieldingFlexibleWorkGang(const char* name, int workers,
   147                            bool are_GC_task_threads);
   155                            bool are_GC_task_threads);
   149   YieldingFlexibleGangTask* yielding_task() const {
   157   YieldingFlexibleGangTask* yielding_task() const {
   150     assert(task() == NULL || task()->is_YieldingFlexibleGang_task(),
   158     assert(task() == NULL || task()->is_YieldingFlexibleGang_task(),
   151            "Incorrect cast");
   159            "Incorrect cast");
   152     return (YieldingFlexibleGangTask*)task();
   160     return (YieldingFlexibleGangTask*)task();
   153   }
   161   }
       
   162   // Allocate a worker and return a pointer to it.
       
   163   GangWorker* allocate_worker(int which);
       
   164 
   154   // Run a task; returns when the task is done, or the workers yield,
   165   // 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().
   166   // 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
   167   // 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.
   168   // by using the same task repeatedly as the argument to the call.
   158   // It is expected that the YieldingFlexibleGangTask carries the appropriate
   169   // It is expected that the YieldingFlexibleGangTask carries the appropriate
   178   // stations, whence they are ready for the next task dispatched
   189   // stations, whence they are ready for the next task dispatched
   179   // by the overseer.
   190   // by the overseer.
   180   void abort();
   191   void abort();
   181 
   192 
   182 private:
   193 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;
   194   int _active_workers;
   188   int _yielded_workers;
   195   int _yielded_workers;
   189   void wait_for_gang();
   196   void wait_for_gang();
   190 
   197 
   191 public:
   198 public:
   192   // Accessors for fields
   199   // Accessors for fields
   193   int active_workers() const {
   200   int active_workers() const {
   194     return _active_workers;
   201     return _active_workers;
   195   }
   202   }
   196 
   203 
       
   204   // Accessors for fields
   197   int yielded_workers() const {
   205   int yielded_workers() const {
   198     return _yielded_workers;
   206     return _yielded_workers;
   199   }
   207   }
   200 
   208 
   201 private:
   209 private: