1 /* 2 * Copyright (c) 2002, 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #ifndef SHARE_VM_UTILITIES_WORKGROUP_HPP 26 #define SHARE_VM_UTILITIES_WORKGROUP_HPP 27 28 #include "runtime/thread.inline.hpp" 29 #include "utilities/taskqueue.hpp" 30 31 // Task class hierarchy: 32 // AbstractGangTask 33 // AbstractGangTaskWOopQueues 34 // 35 // Gang/Group class hierarchy: 36 // AbstractWorkGang 37 // WorkGang 38 // FlexibleWorkGang 39 // YieldingFlexibleWorkGang (defined in another file) 40 // 41 // Worker class hierarchy: 42 // GangWorker (subclass of WorkerThread) 43 // YieldingFlexibleGangWorker (defined in another file) 44 45 // Forward declarations of classes defined here 46 47 class WorkGang; 48 class GangWorker; 49 class YieldingFlexibleGangWorker; 50 class YieldingFlexibleGangTask; 51 class WorkData; 52 class AbstractWorkGang; 53 54 // An abstract task to be worked on by a gang. 55 // You subclass this to supply your own work() method 56 class AbstractGangTask VALUE_OBJ_CLASS_SPEC { 57 public: 58 // The abstract work method. 59 // The argument tells you which member of the gang you are. 60 virtual void work(uint worker_id) = 0; 61 62 // This method configures the task for proper termination. 63 // Some tasks do not have any requirements on termination 64 // and may inherit this method that does nothing. Some 65 // tasks do some coordination on termination and override 66 // this method to implement that coordination. set_for_termination(int active_workers)67 virtual void set_for_termination(int active_workers) {}; 68 69 // Debugging accessor for the name. 70 const char* name() const PRODUCT_RETURN_(return NULL;); counter()71 int counter() { return _counter; } set_counter(int value)72 void set_counter(int value) { _counter = value; } address_of_counter()73 int *address_of_counter() { return &_counter; } 74 75 // RTTI 76 NOT_PRODUCT(virtual bool is_YieldingFlexibleGang_task() const { 77 return false; 78 }) 79 80 private: 81 NOT_PRODUCT(const char* _name;) 82 // ??? Should a task have a priority associated with it? 83 // ??? Or can the run method adjust priority as needed? 84 int _counter; 85 86 protected: 87 // Constructor and desctructor: only construct subclasses. AbstractGangTask(const char * name)88 AbstractGangTask(const char* name) 89 { 90 NOT_PRODUCT(_name = name); 91 _counter = 0; 92 } ~AbstractGangTask()93 ~AbstractGangTask() { } 94 95 public: 96 }; 97 98 class AbstractGangTaskWOopQueues : public AbstractGangTask { 99 OopTaskQueueSet* _queues; 100 ParallelTaskTerminator _terminator; 101 public: AbstractGangTaskWOopQueues(const char * name,OopTaskQueueSet * queues)102 AbstractGangTaskWOopQueues(const char* name, OopTaskQueueSet* queues) : 103 AbstractGangTask(name), _queues(queues), _terminator(0, _queues) {} terminator()104 ParallelTaskTerminator* terminator() { return &_terminator; } set_for_termination(int active_workers)105 virtual void set_for_termination(int active_workers) { 106 terminator()->reset_for_reuse(active_workers); 107 } queues()108 OopTaskQueueSet* queues() { return _queues; } 109 }; 110 111 112 // Class AbstractWorkGang: 113 // An abstract class representing a gang of workers. 114 // You subclass this to supply an implementation of run_task(). 115 class AbstractWorkGang: public CHeapObj<mtInternal> { 116 // Here's the public interface to this class. 117 public: 118 // Constructor and destructor. 119 AbstractWorkGang(const char* name, bool are_GC_task_threads, 120 bool are_ConcurrentGC_threads); 121 ~AbstractWorkGang(); 122 // Run a task, returns when the task is done (or terminated). 123 virtual void run_task(AbstractGangTask* task) = 0; 124 // Stop and terminate all workers. 125 virtual void stop(); 126 // Return true if more workers should be applied to the task. needs_more_workers() const127 virtual bool needs_more_workers() const { return true; } 128 public: 129 // Debugging. 130 const char* name() const; 131 protected: 132 // Initialize only instance data. 133 const bool _are_GC_task_threads; 134 const bool _are_ConcurrentGC_threads; 135 // Printing support. 136 const char* _name; 137 // The monitor which protects these data, 138 // and notifies of changes in it. 139 Monitor* _monitor; 140 // The count of the number of workers in the gang. 141 uint _total_workers; 142 // Whether the workers should terminate. 143 bool _terminate; 144 // The array of worker threads for this gang. 145 // This is only needed for cleaning up. 146 GangWorker** _gang_workers; 147 // The task for this gang. 148 AbstractGangTask* _task; 149 // A sequence number for the current task. 150 int _sequence_number; 151 // The number of started workers. 152 uint _started_workers; 153 // The number of finished workers. 154 uint _finished_workers; 155 public: 156 // Accessors for fields monitor() const157 Monitor* monitor() const { 158 return _monitor; 159 } total_workers() const160 uint total_workers() const { 161 return _total_workers; 162 } active_workers() const163 virtual uint active_workers() const { 164 return _total_workers; 165 } terminate() const166 bool terminate() const { 167 return _terminate; 168 } gang_workers() const169 GangWorker** gang_workers() const { 170 return _gang_workers; 171 } task() const172 AbstractGangTask* task() const { 173 return _task; 174 } sequence_number() const175 int sequence_number() const { 176 return _sequence_number; 177 } started_workers() const178 uint started_workers() const { 179 return _started_workers; 180 } finished_workers() const181 uint finished_workers() const { 182 return _finished_workers; 183 } are_GC_task_threads() const184 bool are_GC_task_threads() const { 185 return _are_GC_task_threads; 186 } are_ConcurrentGC_threads() const187 bool are_ConcurrentGC_threads() const { 188 return _are_ConcurrentGC_threads; 189 } 190 // Predicates. is_idle() const191 bool is_idle() const { 192 return (task() == NULL); 193 } 194 // Return the Ith gang worker. 195 GangWorker* gang_worker(uint i) const; 196 197 void threads_do(ThreadClosure* tc) const; 198 199 // Printing 200 void print_worker_threads_on(outputStream *st) const; print_worker_threads() const201 void print_worker_threads() const { 202 print_worker_threads_on(tty); 203 } 204 205 protected: 206 friend class GangWorker; 207 friend class YieldingFlexibleGangWorker; 208 // Note activation and deactivation of workers. 209 // These methods should only be called with the mutex held. 210 void internal_worker_poll(WorkData* data) const; 211 void internal_note_start(); 212 void internal_note_finish(); 213 }; 214 215 class WorkData: public StackObj { 216 // This would be a struct, but I want accessor methods. 217 private: 218 bool _terminate; 219 AbstractGangTask* _task; 220 int _sequence_number; 221 public: 222 // Constructor and destructor WorkData()223 WorkData() { 224 _terminate = false; 225 _task = NULL; 226 _sequence_number = 0; 227 } ~WorkData()228 ~WorkData() { 229 } 230 // Accessors and modifiers terminate() const231 bool terminate() const { return _terminate; } set_terminate(bool value)232 void set_terminate(bool value) { _terminate = value; } task() const233 AbstractGangTask* task() const { return _task; } set_task(AbstractGangTask * value)234 void set_task(AbstractGangTask* value) { _task = value; } sequence_number() const235 int sequence_number() const { return _sequence_number; } set_sequence_number(int value)236 void set_sequence_number(int value) { _sequence_number = value; } 237 yf_task() const238 YieldingFlexibleGangTask* yf_task() const { 239 return (YieldingFlexibleGangTask*)_task; 240 } 241 }; 242 243 // Class WorkGang: 244 class WorkGang: public AbstractWorkGang { 245 public: 246 // Constructor 247 WorkGang(const char* name, uint workers, 248 bool are_GC_task_threads, bool are_ConcurrentGC_threads); 249 // Run a task, returns when the task is done (or terminated). 250 virtual void run_task(AbstractGangTask* task); 251 void run_task(AbstractGangTask* task, uint no_of_parallel_workers); 252 // Allocate a worker and return a pointer to it. 253 virtual GangWorker* allocate_worker(uint which); 254 // Initialize workers in the gang. Return true if initialization 255 // succeeded. The type of the worker can be overridden in a derived 256 // class with the appropriate implementation of allocate_worker(). 257 bool initialize_workers(); 258 }; 259 260 // Class GangWorker: 261 // Several instances of this class run in parallel as workers for a gang. 262 class GangWorker: public WorkerThread { 263 public: 264 // Constructors and destructor. 265 GangWorker(AbstractWorkGang* gang, uint id); 266 267 // The only real method: run a task for the gang. 268 virtual void run(); 269 // Predicate for Thread 270 virtual bool is_GC_task_thread() const; 271 virtual bool is_ConcurrentGC_thread() const; 272 // Printing 273 void print_on(outputStream* st) const; print() const274 virtual void print() const { print_on(tty); } 275 protected: 276 AbstractWorkGang* _gang; 277 278 virtual void initialize(); 279 virtual void loop(); 280 281 public: gang() const282 AbstractWorkGang* gang() const { return _gang; } 283 }; 284 285 // Dynamic number of worker threads 286 // 287 // This type of work gang is used to run different numbers of 288 // worker threads at different times. The 289 // number of workers run for a task is "_active_workers" 290 // instead of "_total_workers" in a WorkGang. The method 291 // "needs_more_workers()" returns true until "_active_workers" 292 // have been started and returns false afterwards. The 293 // implementation of "needs_more_workers()" in WorkGang always 294 // returns true so that all workers are started. The method 295 // "loop()" in GangWorker was modified to ask "needs_more_workers()" 296 // in its loop to decide if it should start working on a task. 297 // A worker in "loop()" waits for notification on the WorkGang 298 // monitor and execution of each worker as it checks for work 299 // is serialized via the same monitor. The "needs_more_workers()" 300 // call is serialized and additionally the calculation for the 301 // "part" (effectively the worker id for executing the task) is 302 // serialized to give each worker a unique "part". Workers that 303 // are not needed for this tasks (i.e., "_active_workers" have 304 // been started before it, continue to wait for work. 305 306 class FlexibleWorkGang: public WorkGang { 307 // The currently active workers in this gang. 308 // This is a number that is dynamically adjusted 309 // and checked in the run_task() method at each invocation. 310 // As described above _active_workers determines the number 311 // of threads started on a task. It must also be used to 312 // determine completion. 313 314 protected: 315 uint _active_workers; 316 public: 317 // Constructor and destructor. 318 // Initialize active_workers to a minimum value. Setting it to 319 // the parameter "workers" will initialize it to a maximum 320 // value which is not desirable. FlexibleWorkGang(const char * name,uint workers,bool are_GC_task_threads,bool are_ConcurrentGC_threads)321 FlexibleWorkGang(const char* name, uint workers, 322 bool are_GC_task_threads, 323 bool are_ConcurrentGC_threads) : 324 WorkGang(name, workers, are_GC_task_threads, are_ConcurrentGC_threads), 325 _active_workers(UseDynamicNumberOfGCThreads ? 1U : ParallelGCThreads) {} 326 // Accessors for fields active_workers() const327 virtual uint active_workers() const { return _active_workers; } set_active_workers(uint v)328 void set_active_workers(uint v) { 329 assert(v <= _total_workers, 330 "Trying to set more workers active than there are"); 331 _active_workers = MIN2(v, _total_workers); 332 assert(v != 0, "Trying to set active workers to 0"); 333 _active_workers = MAX2(1U, _active_workers); 334 assert(UseDynamicNumberOfGCThreads || _active_workers == _total_workers, 335 "Unless dynamic should use total workers"); 336 } 337 virtual void run_task(AbstractGangTask* task); needs_more_workers() const338 virtual bool needs_more_workers() const { 339 return _started_workers < _active_workers; 340 } 341 }; 342 343 // Work gangs in garbage collectors: 2009-06-10 344 // 345 // SharedHeap - work gang for stop-the-world parallel collection. 346 // Used by 347 // ParNewGeneration 348 // CMSParRemarkTask 349 // CMSRefProcTaskExecutor 350 // G1CollectedHeap 351 // G1ParFinalCountTask 352 // ConcurrentMark 353 // CMSCollector 354 355 // A class that acts as a synchronisation barrier. Workers enter 356 // the barrier and must wait until all other workers have entered 357 // before any of them may leave. 358 359 class WorkGangBarrierSync : public StackObj { 360 protected: 361 Monitor _monitor; 362 uint _n_workers; 363 uint _n_completed; 364 bool _should_reset; 365 bool _aborted; 366 monitor()367 Monitor* monitor() { return &_monitor; } n_workers()368 uint n_workers() { return _n_workers; } n_completed()369 uint n_completed() { return _n_completed; } should_reset()370 bool should_reset() { return _should_reset; } aborted()371 bool aborted() { return _aborted; } 372 zero_completed()373 void zero_completed() { _n_completed = 0; } inc_completed()374 void inc_completed() { _n_completed++; } set_aborted()375 void set_aborted() { _aborted = true; } set_should_reset(bool v)376 void set_should_reset(bool v) { _should_reset = v; } 377 378 public: 379 WorkGangBarrierSync(); 380 WorkGangBarrierSync(uint n_workers, const char* name); 381 382 // Set the number of workers that will use the barrier. 383 // Must be called before any of the workers start running. 384 void set_n_workers(uint n_workers); 385 386 // Enter the barrier. A worker that enters the barrier will 387 // not be allowed to leave until all other threads have 388 // also entered the barrier or the barrier is aborted. 389 // Returns false if the barrier was aborted. 390 bool enter(); 391 392 // Aborts the barrier and wakes up any threads waiting for 393 // the barrier to complete. The barrier will remain in the 394 // aborted state until the next call to set_n_workers(). 395 void abort(); 396 }; 397 398 // A class to manage claiming of subtasks within a group of tasks. The 399 // subtasks will be identified by integer indices, usually elements of an 400 // enumeration type. 401 402 class SubTasksDone: public CHeapObj<mtInternal> { 403 uint* _tasks; 404 uint _n_tasks; 405 // _n_threads is used to determine when a sub task is done. 406 // It does not control how many threads will execute the subtask 407 // but must be initialized to the number that do execute the task 408 // in order to correctly decide when the subtask is done (all the 409 // threads working on the task have finished). 410 uint _n_threads; 411 uint _threads_completed; 412 #ifdef ASSERT 413 volatile uint _claimed; 414 #endif 415 416 // Set all tasks to unclaimed. 417 void clear(); 418 419 public: 420 // Initializes "this" to a state in which there are "n" tasks to be 421 // processed, none of the which are originally claimed. The number of 422 // threads doing the tasks is initialized 1. 423 SubTasksDone(uint n); 424 425 // True iff the object is in a valid state. 426 bool valid(); 427 428 // Get/set the number of parallel threads doing the tasks to "t". Can only 429 // be called before tasks start or after they are complete. n_threads()430 uint n_threads() { return _n_threads; } 431 void set_n_threads(uint t); 432 433 // Returns "false" if the task "t" is unclaimed, and ensures that task is 434 // claimed. The task "t" is required to be within the range of "this". 435 bool is_task_claimed(uint t); 436 437 // The calling thread asserts that it has attempted to claim all the 438 // tasks that it will try to claim. Every thread in the parallel task 439 // must execute this. (When the last thread does so, the task array is 440 // cleared.) 441 void all_tasks_completed(); 442 443 // Destructor. 444 ~SubTasksDone(); 445 }; 446 447 // As above, but for sequential tasks, i.e. instead of claiming 448 // sub-tasks from a set (possibly an enumeration), claim sub-tasks 449 // in sequential order. This is ideal for claiming dynamically 450 // partitioned tasks (like striding in the parallel remembered 451 // set scanning). Note that unlike the above class this is 452 // a stack object - is there any reason for it not to be? 453 454 class SequentialSubTasksDone : public StackObj { 455 protected: 456 uint _n_tasks; // Total number of tasks available. 457 uint _n_claimed; // Number of tasks claimed. 458 // _n_threads is used to determine when a sub task is done. 459 // See comments on SubTasksDone::_n_threads 460 uint _n_threads; // Total number of parallel threads. 461 uint _n_completed; // Number of completed threads. 462 463 void clear(); 464 465 public: SequentialSubTasksDone()466 SequentialSubTasksDone() { 467 clear(); 468 } ~SequentialSubTasksDone()469 ~SequentialSubTasksDone() {} 470 471 // True iff the object is in a valid state. 472 bool valid(); 473 474 // number of tasks n_tasks() const475 uint n_tasks() const { return _n_tasks; } 476 477 // Get/set the number of parallel threads doing the tasks to t. 478 // Should be called before the task starts but it is safe 479 // to call this once a task is running provided that all 480 // threads agree on the number of threads. n_threads()481 uint n_threads() { return _n_threads; } set_n_threads(uint t)482 void set_n_threads(uint t) { _n_threads = t; } 483 484 // Set the number of tasks to be claimed to t. As above, 485 // should be called before the tasks start but it is safe 486 // to call this once a task is running provided all threads 487 // agree on the number of tasks. set_n_tasks(uint t)488 void set_n_tasks(uint t) { _n_tasks = t; } 489 490 // Returns false if the next task in the sequence is unclaimed, 491 // and ensures that it is claimed. Will set t to be the index 492 // of the claimed task in the sequence. Will return true if 493 // the task cannot be claimed and there are none left to claim. 494 bool is_task_claimed(uint& t); 495 496 // The calling thread asserts that it has attempted to claim 497 // all the tasks it possibly can in the sequence. Every thread 498 // claiming tasks must promise call this. Returns true if this 499 // is the last thread to complete so that the thread can perform 500 // cleanup if necessary. 501 bool all_tasks_completed(); 502 }; 503 504 // Represents a set of free small integer ids. 505 class FreeIdSet : public CHeapObj<mtInternal> { 506 enum { 507 end_of_list = -1, 508 claimed = -2 509 }; 510 511 int _sz; 512 Monitor* _mon; 513 514 int* _ids; 515 int _hd; 516 int _waiters; 517 int _claimed; 518 519 static bool _safepoint; 520 typedef FreeIdSet* FreeIdSetPtr; 521 static const int NSets = 10; 522 static FreeIdSetPtr _sets[NSets]; 523 static bool _stat_init; 524 int _index; 525 526 public: 527 FreeIdSet(int sz, Monitor* mon); 528 ~FreeIdSet(); 529 530 static void set_safepoint(bool b); 531 532 // Attempt to claim the given id permanently. Returns "true" iff 533 // successful. 534 bool claim_perm_id(int i); 535 536 // Returns an unclaimed parallel id (waiting for one to be released if 537 // necessary). Returns "-1" if a GC wakes up a wait for an id. 538 int claim_par_id(); 539 540 void release_par_id(int id); 541 }; 542 543 #endif // SHARE_VM_UTILITIES_WORKGROUP_HPP 544