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 void 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 };
197 friend class GangWorker;
198
199 // Never deleted.
200 ~WorkGang();
201
202 GangTaskDispatcher* const _dispatcher;
203 GangTaskDispatcher* dispatcher() const {
204 return _dispatcher;
205 }
206
207 public:
208 WorkGang(const char* name,
209 uint workers,
210 bool are_GC_task_threads,
211 bool are_ConcurrentGC_threads);
212
213 // Run a task using the current active number of workers, returns when the task is done.
214 virtual void run_task(AbstractGangTask* task);
215 // Run a task with the given number of workers, returns
216 // when the task is done. The number of workers must be at most the number of
217 // active workers.
218 void run_task(AbstractGangTask* task, uint num_workers);
219
220 protected:
221 virtual AbstractGangWorker* allocate_worker(uint which);
222 };
223
224 // Several instances of this class run in parallel as workers for a gang.
225 class AbstractGangWorker: public WorkerThread {
226 public:
227 AbstractGangWorker(AbstractWorkGang* gang, uint id);
228
229 // The only real method: run a task for the gang.
230 virtual void run();
231 // Predicate for Thread
232 virtual bool is_GC_task_thread() const;
233 virtual bool is_ConcurrentGC_thread() const;
234 // Printing
235 void print_on(outputStream* st) const;
236 virtual void print() const { print_on(tty); }
237
|
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 void add_workers(bool initializing);
172
173 // Add GC workers as needed to reach the specified number of workers.
174 void add_workers(uint active_workers, bool initializing);
175
176 // Return the Ith worker.
177 AbstractGangWorker* worker(uint i) const;
178
179 void threads_do(ThreadClosure* tc) const;
180
181 // Create a GC worker and install it into the work gang.
182 virtual AbstractGangWorker* install_worker(uint which);
183
184 // Debugging.
185 const char* name() const { return _name; }
186
187 // Printing
188 void print_worker_threads_on(outputStream *st) const;
189 void print_worker_threads() const {
190 print_worker_threads_on(tty);
191 }
192
193 protected:
194 virtual AbstractGangWorker* allocate_worker(uint which) = 0;
195 };
200 friend class GangWorker;
201
202 // Never deleted.
203 ~WorkGang();
204
205 GangTaskDispatcher* const _dispatcher;
206 GangTaskDispatcher* dispatcher() const {
207 return _dispatcher;
208 }
209
210 public:
211 WorkGang(const char* name,
212 uint workers,
213 bool are_GC_task_threads,
214 bool are_ConcurrentGC_threads);
215
216 // Run a task using the current active number of workers, returns when the task is done.
217 virtual void run_task(AbstractGangTask* task);
218 // Run a task with the given number of workers, returns
219 // when the task is done. The number of workers must be at most the number of
220 // active workers. Additional workers may be created if an insufficient
221 // number currently exists.
222 void run_task(AbstractGangTask* task, uint num_workers);
223
224 protected:
225 virtual AbstractGangWorker* allocate_worker(uint which);
226 };
227
228 // Several instances of this class run in parallel as workers for a gang.
229 class AbstractGangWorker: public WorkerThread {
230 public:
231 AbstractGangWorker(AbstractWorkGang* gang, uint id);
232
233 // The only real method: run a task for the gang.
234 virtual void run();
235 // Predicate for Thread
236 virtual bool is_GC_task_thread() const;
237 virtual bool is_ConcurrentGC_thread() const;
238 // Printing
239 void print_on(outputStream* st) const;
240 virtual void print() const { print_on(tty); }
241
|