431 uint GenericTaskQueueSet<T, F>::tasks() const { 432 uint n = 0; 433 for (uint j = 0; j < _n; j++) { 434 n += _queues[j]->size(); 435 } 436 return n; 437 } 438 439 // When to terminate from the termination protocol. 440 class TerminatorTerminator: public CHeapObj<mtInternal> { 441 public: 442 virtual bool should_exit_termination() = 0; 443 }; 444 445 // A class to aid in the termination of a set of parallel tasks using 446 // TaskQueueSet's for work stealing. 447 448 #undef TRACESPINNING 449 450 class ParallelTaskTerminator: public StackObj { 451 private: 452 uint _n_threads; 453 TaskQueueSetSuper* _queue_set; 454 volatile uint _offered_termination; 455 456 #ifdef TRACESPINNING 457 static uint _total_yields; 458 static uint _total_spins; 459 static uint _total_peeks; 460 #endif 461 462 bool peek_in_queue_set(); 463 protected: 464 virtual void yield(); 465 void sleep(uint millis); 466 467 public: 468 469 // "n_threads" is the number of threads to be terminated. "queue_set" is a 470 // queue sets of work queues of other threads. 471 ParallelTaskTerminator(uint n_threads, TaskQueueSetSuper* queue_set); 472 473 // The current thread has no work, and is ready to terminate if everyone 474 // else is. If returns "true", all threads are terminated. If returns 475 // "false", available work has been observed in one of the task queues, 476 // so the global task is not complete. 477 bool offer_termination() { 478 return offer_termination(NULL); 479 } 480 481 // As above, but it also terminates if the should_exit_termination() 482 // method of the terminator parameter returns true. If terminator is 483 // NULL, then it is ignored. 484 bool offer_termination(TerminatorTerminator* terminator); 485 486 // Reset the terminator, so that it may be reused again. 487 // The caller is responsible for ensuring that this is done 488 // in an MT-safe manner, once the previous round of use of 489 // the terminator is finished. 490 void reset_for_reuse(); 491 // Same as above but the number of parallel threads is set to the 492 // given number. 493 void reset_for_reuse(uint n_threads); 494 495 #ifdef TRACESPINNING 496 static uint total_yields() { return _total_yields; } 497 static uint total_spins() { return _total_spins; } 498 static uint total_peeks() { return _total_peeks; } 499 static void print_termination_counts(); 500 #endif 501 }; 502 503 typedef GenericTaskQueue<oop, mtGC> OopTaskQueue; 504 typedef GenericTaskQueueSet<OopTaskQueue, mtGC> OopTaskQueueSet; | 431 uint GenericTaskQueueSet<T, F>::tasks() const { 432 uint n = 0; 433 for (uint j = 0; j < _n; j++) { 434 n += _queues[j]->size(); 435 } 436 return n; 437 } 438 439 // When to terminate from the termination protocol. 440 class TerminatorTerminator: public CHeapObj<mtInternal> { 441 public: 442 virtual bool should_exit_termination() = 0; 443 }; 444 445 // A class to aid in the termination of a set of parallel tasks using 446 // TaskQueueSet's for work stealing. 447 448 #undef TRACESPINNING 449 450 class ParallelTaskTerminator: public StackObj { 451 protected: 452 uint _n_threads; 453 TaskQueueSetSuper* _queue_set; 454 volatile uint _offered_termination; 455 456 #ifdef TRACESPINNING 457 static uint _total_yields; 458 static uint _total_spins; 459 static uint _total_peeks; 460 #endif 461 462 bool peek_in_queue_set(); 463 protected: 464 virtual void yield(); 465 void sleep(uint millis); 466 467 public: 468 469 // "n_threads" is the number of threads to be terminated. "queue_set" is a 470 // queue sets of work queues of other threads. 471 ParallelTaskTerminator(uint n_threads, TaskQueueSetSuper* queue_set); 472 473 // The current thread has no work, and is ready to terminate if everyone 474 // else is. If returns "true", all threads are terminated. If returns 475 // "false", available work has been observed in one of the task queues, 476 // so the global task is not complete. 477 bool offer_termination() { 478 return offer_termination(NULL); 479 } 480 481 // As above, but it also terminates if the should_exit_termination() 482 // method of the terminator parameter returns true. If terminator is 483 // NULL, then it is ignored. 484 virtual bool offer_termination(TerminatorTerminator* terminator); 485 486 // Reset the terminator, so that it may be reused again. 487 // The caller is responsible for ensuring that this is done 488 // in an MT-safe manner, once the previous round of use of 489 // the terminator is finished. 490 void reset_for_reuse(); 491 // Same as above but the number of parallel threads is set to the 492 // given number. 493 void reset_for_reuse(uint n_threads); 494 495 #ifdef TRACESPINNING 496 static uint total_yields() { return _total_yields; } 497 static uint total_spins() { return _total_spins; } 498 static uint total_peeks() { return _total_peeks; } 499 static void print_termination_counts(); 500 #endif 501 }; 502 503 typedef GenericTaskQueue<oop, mtGC> OopTaskQueue; 504 typedef GenericTaskQueueSet<OopTaskQueue, mtGC> OopTaskQueueSet; |