< prev index next >

src/share/vm/gc/shared/workgroup.hpp

Print this page
rev 11036 : 6858051: Create GC worker threads dynamically
Reviewed-by:


  95 
  96   // Waits for a task to become available to the worker.
  97   // Returns when the worker has been assigned a task.
  98   virtual WorkData worker_wait_for_task() = 0;
  99 
 100   // Signal to the coordinator that the worker is done with the assigned task.
 101   virtual void     worker_done_with_task() = 0;
 102 };
 103 
 104 // The work gang is the collection of workers to execute tasks.
 105 // The number of workers run for a task is "_active_workers"
 106 // while "_total_workers" is the number of available of workers.
 107 class AbstractWorkGang : public CHeapObj<mtInternal> {
 108  protected:
 109   // The array of worker threads for this gang.
 110   AbstractGangWorker** _workers;
 111   // The count of the number of workers in the gang.
 112   uint _total_workers;
 113   // The currently active workers in this gang.
 114   uint _active_workers;


 115   // Printing support.
 116   const char* _name;
 117 
 118  private:
 119   // Initialize only instance data.
 120   const bool _are_GC_task_threads;
 121   const bool _are_ConcurrentGC_threads;
 122 




 123  public:
 124   AbstractWorkGang(const char* name, uint workers, bool are_GC_task_threads, bool are_ConcurrentGC_threads) :
 125       _name(name),
 126       _total_workers(workers),
 127       _active_workers(UseDynamicNumberOfGCThreads ? 1U : workers),

 128       _are_GC_task_threads(are_GC_task_threads),
 129       _are_ConcurrentGC_threads(are_ConcurrentGC_threads)
 130   { }
 131 
 132   // Initialize workers in the gang.  Return true if initialization succeeded.
 133   bool initialize_workers();
 134 
 135   bool are_GC_task_threads()      const { return _are_GC_task_threads; }
 136   bool are_ConcurrentGC_threads() const { return _are_ConcurrentGC_threads; }
 137 
 138   uint total_workers() const { return _total_workers; }
 139 




 140   virtual uint active_workers() const {
 141     assert(_active_workers <= _total_workers,
 142            "_active_workers: %u > _total_workers: %u", _active_workers, _total_workers);
 143     assert(UseDynamicNumberOfGCThreads || _active_workers == _total_workers,
 144            "Unless dynamic should use total workers");
 145     return _active_workers;
 146   }

 147   void set_active_workers(uint v) {
 148     assert(v <= _total_workers,
 149            "Trying to set more workers active than there are");
 150     _active_workers = MIN2(v, _total_workers);

 151     assert(v != 0, "Trying to set active workers to 0");
 152     _active_workers = MAX2(1U, _active_workers);
 153     assert(UseDynamicNumberOfGCThreads || _active_workers == _total_workers,
 154            "Unless dynamic should use total workers");
 155     log_info(gc, task)("GC Workers: using %d out of %d", _active_workers, _total_workers);
 156   }
 157 



 158   // Return the Ith worker.
 159   AbstractGangWorker* worker(uint i) const;
 160 
 161   void threads_do(ThreadClosure* tc) const;



 162 
 163   // Debugging.
 164   const char* name() const { return _name; }
 165 
 166   // Printing
 167   void print_worker_threads_on(outputStream *st) const;
 168   void print_worker_threads() const {
 169     print_worker_threads_on(tty);
 170   }
 171 
 172  protected:
 173   virtual AbstractGangWorker* allocate_worker(uint which) = 0;
 174 };
 175 
 176 // An class representing a gang of workers.
 177 class WorkGang: public AbstractWorkGang {
 178   // To get access to the GangTaskDispatcher instance.
 179   friend class GangWorker;
 180 
 181   // Never deleted.




  95 
  96   // Waits for a task to become available to the worker.
  97   // Returns when the worker has been assigned a task.
  98   virtual WorkData worker_wait_for_task() = 0;
  99 
 100   // Signal to the coordinator that the worker is done with the assigned task.
 101   virtual void     worker_done_with_task() = 0;
 102 };
 103 
 104 // The work gang is the collection of workers to execute tasks.
 105 // The number of workers run for a task is "_active_workers"
 106 // while "_total_workers" is the number of available of workers.
 107 class AbstractWorkGang : public CHeapObj<mtInternal> {
 108  protected:
 109   // The array of worker threads for this gang.
 110   AbstractGangWorker** _workers;
 111   // The count of the number of workers in the gang.
 112   uint _total_workers;
 113   // The currently active workers in this gang.
 114   uint _active_workers;
 115   // The count of created workers in the gang.
 116   uint _created_workers;
 117   // Printing support.
 118   const char* _name;
 119 
 120  private:
 121   // Initialize only instance data.
 122   const bool _are_GC_task_threads;
 123   const bool _are_ConcurrentGC_threads;
 124 
 125   void set_thread(uint worker_id, AbstractGangWorker* worker) {
 126     _workers[worker_id] = worker;
 127   }
 128 
 129  public:
 130   AbstractWorkGang(const char* name, uint workers, bool are_GC_task_threads, bool are_ConcurrentGC_threads) :
 131       _name(name),
 132       _total_workers(workers),
 133       _active_workers(UseDynamicNumberOfGCThreads ? 1U : workers),
 134       _created_workers(0),
 135       _are_GC_task_threads(are_GC_task_threads),
 136       _are_ConcurrentGC_threads(are_ConcurrentGC_threads)
 137   { }
 138 
 139   // Initialize workers in the gang.  Return true if initialization succeeded.
 140   bool initialize_workers();
 141 
 142   bool are_GC_task_threads()      const { return _are_GC_task_threads; }
 143   bool are_ConcurrentGC_threads() const { return _are_ConcurrentGC_threads; }
 144 
 145   uint total_workers() const { return _total_workers; }
 146 
 147   uint created_workers() const {
 148     return _created_workers;
 149   }
 150 
 151   virtual uint active_workers() const {
 152     assert(_active_workers <= _total_workers,
 153            "_active_workers: %u > _total_workers: %u", _active_workers, _total_workers);
 154     assert(UseDynamicNumberOfGCThreads || _active_workers == _total_workers,
 155            "Unless dynamic should use total workers");
 156     return _active_workers;
 157   }
 158 
 159   void set_active_workers(uint v) {
 160     assert(v <= _total_workers,
 161            "Trying to set more workers active than there are");
 162     _active_workers = MIN2(v, _total_workers);
 163     add_workers(false /* exit_on_failure */);
 164     assert(v != 0, "Trying to set active workers to 0");

 165     assert(UseDynamicNumberOfGCThreads || _active_workers == _total_workers,
 166            "Unless dynamic should use total workers");
 167     log_info(gc, task)("GC Workers: using %d out of %d", _active_workers, _total_workers);
 168   }
 169 
 170   // Add GC workers as needed.
 171   bool add_workers(bool initializing);
 172 
 173   // Return the Ith worker.
 174   AbstractGangWorker* worker(uint i) const;
 175 
 176   void threads_do(ThreadClosure* tc) const;
 177 
 178   // Create a GC worker and install it into the work gang.
 179   virtual AbstractGangWorker* install_worker(uint which);
 180 
 181   // Debugging.
 182   const char* name() const { return _name; }
 183 
 184   // Printing
 185   void print_worker_threads_on(outputStream *st) const;
 186   void print_worker_threads() const {
 187     print_worker_threads_on(tty);
 188   }
 189 
 190  protected:
 191   virtual AbstractGangWorker* allocate_worker(uint which) = 0;
 192 };
 193 
 194 // An class representing a gang of workers.
 195 class WorkGang: public AbstractWorkGang {
 196   // To get access to the GangTaskDispatcher instance.
 197   friend class GangWorker;
 198 
 199   // Never deleted.


< prev index next >