185 WorkGang(const char* name, 186 uint workers, 187 bool are_GC_task_threads, 188 bool are_ConcurrentGC_threads); 189 190 ~WorkGang(); 191 192 // Run a task using the current active number of workers, returns when the task is done. 193 virtual void run_task(AbstractGangTask* task); 194 // Run a task with the given number of workers, returns 195 // when the task is done. The number of workers must be at most the number of 196 // active workers. Additional workers may be created if an insufficient 197 // number currently exists. If the add_foreground_work flag is true, the current thread 198 // is used to run the task too. 199 void run_task(AbstractGangTask* task, uint num_workers, bool add_foreground_work = false); 200 201 protected: 202 virtual AbstractGangWorker* allocate_worker(uint which); 203 }; 204 205 // Several instances of this class run in parallel as workers for a gang. 206 class AbstractGangWorker: public WorkerThread { 207 public: 208 AbstractGangWorker(AbstractWorkGang* gang, uint id); 209 210 // The only real method: run a task for the gang. 211 virtual void run(); 212 // Predicate for Thread 213 virtual bool is_GC_task_thread() const; 214 virtual bool is_ConcurrentGC_thread() const; 215 // Printing 216 void print_on(outputStream* st) const; 217 virtual void print() const; 218 219 protected: 220 AbstractWorkGang* _gang; 221 222 virtual void initialize(); 223 virtual void loop() = 0; 224 | 185 WorkGang(const char* name, 186 uint workers, 187 bool are_GC_task_threads, 188 bool are_ConcurrentGC_threads); 189 190 ~WorkGang(); 191 192 // Run a task using the current active number of workers, returns when the task is done. 193 virtual void run_task(AbstractGangTask* task); 194 // Run a task with the given number of workers, returns 195 // when the task is done. The number of workers must be at most the number of 196 // active workers. Additional workers may be created if an insufficient 197 // number currently exists. If the add_foreground_work flag is true, the current thread 198 // is used to run the task too. 199 void run_task(AbstractGangTask* task, uint num_workers, bool add_foreground_work = false); 200 201 protected: 202 virtual AbstractGangWorker* allocate_worker(uint which); 203 }; 204 205 // Temporarily try to set the number of active workers. 206 // It's not guaranteed that it succeeds, and users need to 207 // query the number of active workers. 208 class WithUpdatedActiveWorkers : public StackObj { 209 private: 210 AbstractWorkGang* const _gang; 211 const uint _old_active_workers; 212 213 public: 214 WithUpdatedActiveWorkers(AbstractWorkGang* gang, uint requested_num_workers) : 215 _gang(gang), 216 _old_active_workers(gang->active_workers()) { 217 uint capped_num_workers = MIN2(requested_num_workers, gang->total_workers()); 218 gang->update_active_workers(capped_num_workers); 219 } 220 221 ~WithUpdatedActiveWorkers() { 222 _gang->update_active_workers(_old_active_workers); 223 } 224 }; 225 226 // Several instances of this class run in parallel as workers for a gang. 227 class AbstractGangWorker: public WorkerThread { 228 public: 229 AbstractGangWorker(AbstractWorkGang* gang, uint id); 230 231 // The only real method: run a task for the gang. 232 virtual void run(); 233 // Predicate for Thread 234 virtual bool is_GC_task_thread() const; 235 virtual bool is_ConcurrentGC_thread() const; 236 // Printing 237 void print_on(outputStream* st) const; 238 virtual void print() const; 239 240 protected: 241 AbstractWorkGang* _gang; 242 243 virtual void initialize(); 244 virtual void loop() = 0; 245 |