373 374 // Enter the barrier. A worker that enters the barrier will 375 // not be allowed to leave until all other threads have 376 // also entered the barrier or the barrier is aborted. 377 // Returns false if the barrier was aborted. 378 bool enter(); 379 380 // Aborts the barrier and wakes up any threads waiting for 381 // the barrier to complete. The barrier will remain in the 382 // aborted state until the next call to set_n_workers(). 383 void abort(); 384 }; 385 386 // A class to manage claiming of subtasks within a group of tasks. The 387 // subtasks will be identified by integer indices, usually elements of an 388 // enumeration type. 389 390 class SubTasksDone: public CHeapObj<mtInternal> { 391 uint* _tasks; 392 uint _n_tasks; 393 // _n_threads is used to determine when a sub task is done. 394 // It does not control how many threads will execute the subtask 395 // but must be initialized to the number that do execute the task 396 // in order to correctly decide when the subtask is done (all the 397 // threads working on the task have finished). 398 uint _n_threads; 399 uint _threads_completed; 400 #ifdef ASSERT 401 volatile uint _claimed; 402 #endif 403 404 // Set all tasks to unclaimed. 405 void clear(); 406 407 public: 408 // Initializes "this" to a state in which there are "n" tasks to be 409 // processed, none of the which are originally claimed. The number of 410 // threads doing the tasks is initialized 1. 411 SubTasksDone(uint n); 412 413 // True iff the object is in a valid state. 414 bool valid(); 415 416 // Get/set the number of parallel threads doing the tasks to "t". Can only 417 // be called before tasks start or after they are complete. 418 uint n_threads() { return _n_threads; } 419 void set_n_threads(uint t); 420 421 // Returns "false" if the task "t" is unclaimed, and ensures that task is 422 // claimed. The task "t" is required to be within the range of "this". 423 bool is_task_claimed(uint t); 424 425 // The calling thread asserts that it has attempted to claim all the 426 // tasks that it will try to claim. Every thread in the parallel task 427 // must execute this. (When the last thread does so, the task array is 428 // cleared.) 429 void all_tasks_completed(); 430 431 // Destructor. 432 ~SubTasksDone(); 433 }; 434 435 // As above, but for sequential tasks, i.e. instead of claiming 436 // sub-tasks from a set (possibly an enumeration), claim sub-tasks 437 // in sequential order. This is ideal for claiming dynamically 438 // partitioned tasks (like striding in the parallel remembered 439 // set scanning). Note that unlike the above class this is 440 // a stack object - is there any reason for it not to be? 441 442 class SequentialSubTasksDone : public StackObj { 443 protected: 444 uint _n_tasks; // Total number of tasks available. 445 uint _n_claimed; // Number of tasks claimed. 446 // _n_threads is used to determine when a sub task is done. 447 // See comments on SubTasksDone::_n_threads 448 uint _n_threads; // Total number of parallel threads. 449 uint _n_completed; // Number of completed threads. | 373 374 // Enter the barrier. A worker that enters the barrier will 375 // not be allowed to leave until all other threads have 376 // also entered the barrier or the barrier is aborted. 377 // Returns false if the barrier was aborted. 378 bool enter(); 379 380 // Aborts the barrier and wakes up any threads waiting for 381 // the barrier to complete. The barrier will remain in the 382 // aborted state until the next call to set_n_workers(). 383 void abort(); 384 }; 385 386 // A class to manage claiming of subtasks within a group of tasks. The 387 // subtasks will be identified by integer indices, usually elements of an 388 // enumeration type. 389 390 class SubTasksDone: public CHeapObj<mtInternal> { 391 uint* _tasks; 392 uint _n_tasks; 393 uint _threads_completed; 394 #ifdef ASSERT 395 volatile uint _claimed; 396 #endif 397 398 // Set all tasks to unclaimed. 399 void clear(); 400 401 public: 402 // Initializes "this" to a state in which there are "n" tasks to be 403 // processed, none of the which are originally claimed. The number of 404 // threads doing the tasks is initialized 1. 405 SubTasksDone(uint n); 406 407 // True iff the object is in a valid state. 408 bool valid(); 409 410 // Returns "false" if the task "t" is unclaimed, and ensures that task is 411 // claimed. The task "t" is required to be within the range of "this". 412 bool is_task_claimed(uint t); 413 414 // The calling thread asserts that it has attempted to claim all the 415 // tasks that it will try to claim. Every thread in the parallel task 416 // must execute this. (When the last thread does so, the task array is 417 // cleared.) 418 // 419 // n_threads - Number of threads executing the sub-tasks. 420 void all_tasks_completed(uint n_threads); 421 422 // Destructor. 423 ~SubTasksDone(); 424 }; 425 426 // As above, but for sequential tasks, i.e. instead of claiming 427 // sub-tasks from a set (possibly an enumeration), claim sub-tasks 428 // in sequential order. This is ideal for claiming dynamically 429 // partitioned tasks (like striding in the parallel remembered 430 // set scanning). Note that unlike the above class this is 431 // a stack object - is there any reason for it not to be? 432 433 class SequentialSubTasksDone : public StackObj { 434 protected: 435 uint _n_tasks; // Total number of tasks available. 436 uint _n_claimed; // Number of tasks claimed. 437 // _n_threads is used to determine when a sub task is done. 438 // See comments on SubTasksDone::_n_threads 439 uint _n_threads; // Total number of parallel threads. 440 uint _n_completed; // Number of completed threads. |