< prev index next >

src/hotspot/share/gc/shared/taskqueue.hpp

Print this page




 353 
 354   // Attempt to pop from the overflow stack; return true if anything was popped.
 355   inline bool pop_overflow(E& t);
 356 
 357   inline overflow_t* overflow_stack() { return &_overflow_stack; }
 358 
 359   inline bool taskqueue_empty() const { return taskqueue_t::is_empty(); }
 360   inline bool overflow_empty()  const { return _overflow_stack.is_empty(); }
 361   inline bool is_empty()        const {
 362     return taskqueue_empty() && overflow_empty();
 363   }
 364 
 365 private:
 366   overflow_t _overflow_stack;
 367 };
 368 
 369 class TaskQueueSetSuper {
 370 public:
 371   // Returns "true" if some TaskQueue in the set contains a task.
 372   virtual bool peek() = 0;


 373 };
 374 
 375 template <MEMFLAGS F> class TaskQueueSetSuperImpl: public CHeapObj<F>, public TaskQueueSetSuper {
 376 };
 377 
 378 template<class T, MEMFLAGS F>
 379 class GenericTaskQueueSet: public TaskQueueSetSuperImpl<F> {
 380 public:
 381   typedef typename T::element_type E;
 382 
 383 private:
 384   uint _n;
 385   T** _queues;
 386 
 387   bool steal_best_of_2(uint queue_num, E& t);
 388 
 389 public:
 390   GenericTaskQueueSet(uint n);
 391   ~GenericTaskQueueSet();
 392 
 393   void register_queue(uint i, T* q);
 394 
 395   T* queue(uint n);
 396 
 397   // Try to steal a task from some other queue than queue_num. It may perform several attempts at doing so.
 398   // Returns if stealing succeeds, and sets "t" to the stolen task.
 399   bool steal(uint queue_num, E& t);
 400 
 401   bool peek();

 402 
 403   uint size() const { return _n; }
 404 };
 405 
 406 template<class T, MEMFLAGS F> void
 407 GenericTaskQueueSet<T, F>::register_queue(uint i, T* q) {
 408   assert(i < _n, "index out of range.");
 409   _queues[i] = q;
 410 }
 411 
 412 template<class T, MEMFLAGS F> T*
 413 GenericTaskQueueSet<T, F>::queue(uint i) {
 414   return _queues[i];
 415 }
 416 
 417 template<class T, MEMFLAGS F>
 418 bool GenericTaskQueueSet<T, F>::peek() {
 419   // Try all the queues.
 420   for (uint j = 0; j < _n; j++) {
 421     if (_queues[j]->peek())
 422       return true;
 423   }
 424   return false;
 425 }
 426 









 427 // When to terminate from the termination protocol.
 428 class TerminatorTerminator: public CHeapObj<mtInternal> {
 429 public:
 430   virtual bool should_exit_termination() = 0;
 431 };
 432 
 433 // A class to aid in the termination of a set of parallel tasks using
 434 // TaskQueueSet's for work stealing.
 435 
 436 #undef TRACESPINNING
 437 
 438 class ParallelTaskTerminator: public StackObj {
 439 private:
 440   uint _n_threads;
 441   TaskQueueSetSuper* _queue_set;
 442   volatile uint _offered_termination;
 443 
 444 #ifdef TRACESPINNING
 445   static uint _total_yields;
 446   static uint _total_spins;
 447   static uint _total_peeks;
 448 #endif
 449 
 450   bool peek_in_queue_set();
 451 protected:
 452   virtual void yield();
 453   void sleep(uint millis);
 454 
 455 public:
 456 
 457   // "n_threads" is the number of threads to be terminated.  "queue_set" is a
 458   // queue sets of work queues of other threads.
 459   ParallelTaskTerminator(uint n_threads, TaskQueueSetSuper* queue_set);




 353 
 354   // Attempt to pop from the overflow stack; return true if anything was popped.
 355   inline bool pop_overflow(E& t);
 356 
 357   inline overflow_t* overflow_stack() { return &_overflow_stack; }
 358 
 359   inline bool taskqueue_empty() const { return taskqueue_t::is_empty(); }
 360   inline bool overflow_empty()  const { return _overflow_stack.is_empty(); }
 361   inline bool is_empty()        const {
 362     return taskqueue_empty() && overflow_empty();
 363   }
 364 
 365 private:
 366   overflow_t _overflow_stack;
 367 };
 368 
 369 class TaskQueueSetSuper {
 370 public:
 371   // Returns "true" if some TaskQueue in the set contains a task.
 372   virtual bool peek() = 0;
 373   // Tasks in queue
 374   virtual uint tasks() const = 0;
 375 };
 376 
 377 template <MEMFLAGS F> class TaskQueueSetSuperImpl: public CHeapObj<F>, public TaskQueueSetSuper {
 378 };
 379 
 380 template<class T, MEMFLAGS F>
 381 class GenericTaskQueueSet: public TaskQueueSetSuperImpl<F> {
 382 public:
 383   typedef typename T::element_type E;
 384 
 385 private:
 386   uint _n;
 387   T** _queues;
 388 
 389   bool steal_best_of_2(uint queue_num, E& t);
 390 
 391 public:
 392   GenericTaskQueueSet(uint n);
 393   ~GenericTaskQueueSet();
 394 
 395   void register_queue(uint i, T* q);
 396 
 397   T* queue(uint n);
 398 
 399   // Try to steal a task from some other queue than queue_num. It may perform several attempts at doing so.
 400   // Returns if stealing succeeds, and sets "t" to the stolen task.
 401   bool steal(uint queue_num, E& t);
 402 
 403   bool peek();
 404   uint tasks() const;
 405 
 406   uint size() const { return _n; }
 407 };
 408 
 409 template<class T, MEMFLAGS F> void
 410 GenericTaskQueueSet<T, F>::register_queue(uint i, T* q) {
 411   assert(i < _n, "index out of range.");
 412   _queues[i] = q;
 413 }
 414 
 415 template<class T, MEMFLAGS F> T*
 416 GenericTaskQueueSet<T, F>::queue(uint i) {
 417   return _queues[i];
 418 }
 419 
 420 template<class T, MEMFLAGS F>
 421 bool GenericTaskQueueSet<T, F>::peek() {
 422   // Try all the queues.
 423   for (uint j = 0; j < _n; j++) {
 424     if (_queues[j]->peek())
 425       return true;
 426   }
 427   return false;
 428 }
 429 
 430 template<class T, MEMFLAGS F>
 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);


< prev index next >