hotspot/src/share/vm/utilities/taskqueue.hpp
changeset 1374 4c24294029a9
parent 360 21d113ecbf6a
child 1388 3677f5f3d66b
equal deleted inserted replaced
615:570062d730b2 1374:4c24294029a9
   118 
   118 
   119   juint dirty_size() {
   119   juint dirty_size() {
   120     return dirty_size(_bottom, get_top());
   120     return dirty_size(_bottom, get_top());
   121   }
   121   }
   122 
   122 
       
   123   void set_empty() {
       
   124     _bottom = 0;
       
   125     _age = Age();
       
   126   }
       
   127 
   123   // Maximum number of elements allowed in the queue.  This is two less
   128   // Maximum number of elements allowed in the queue.  This is two less
   124   // than the actual queue size, for somewhat complicated reasons.
   129   // than the actual queue size, for somewhat complicated reasons.
   125   juint max_elems() { return n() - 2; }
   130   juint max_elems() { return n() - 2; }
   126 
   131 
   127 };
   132 };
   153   bool pop_global(E& t);
   158   bool pop_global(E& t);
   154 
   159 
   155   // Delete any resource associated with the queue.
   160   // Delete any resource associated with the queue.
   156   ~GenericTaskQueue();
   161   ~GenericTaskQueue();
   157 
   162 
       
   163   // apply the closure to all elements in the task queue
       
   164   void oops_do(OopClosure* f);
       
   165 
   158 private:
   166 private:
   159   // Element array.
   167   // Element array.
   160   volatile E* _elems;
   168   volatile E* _elems;
   161 };
   169 };
   162 
   170 
   168 template<class E>
   176 template<class E>
   169 void GenericTaskQueue<E>::initialize() {
   177 void GenericTaskQueue<E>::initialize() {
   170   _elems = NEW_C_HEAP_ARRAY(E, n());
   178   _elems = NEW_C_HEAP_ARRAY(E, n());
   171   guarantee(_elems != NULL, "Allocation failed.");
   179   guarantee(_elems != NULL, "Allocation failed.");
   172 }
   180 }
       
   181 
       
   182 template<class E>
       
   183 void GenericTaskQueue<E>::oops_do(OopClosure* f) {
       
   184   // tty->print_cr("START OopTaskQueue::oops_do");
       
   185   int iters = size();
       
   186   juint index = _bottom;
       
   187   for (int i = 0; i < iters; ++i) {
       
   188     index = decrement_index(index);
       
   189     // tty->print_cr("  doing entry %d," INTPTR_T " -> " INTPTR_T,
       
   190     //            index, &_elems[index], _elems[index]);
       
   191     E* t = (E*)&_elems[index];      // cast away volatility
       
   192     oop* p = (oop*)t;
       
   193     assert((*t)->is_oop_or_null(), "Not an oop or null");
       
   194     f->do_oop(p);
       
   195   }
       
   196   // tty->print_cr("END OopTaskQueue::oops_do");
       
   197 }
       
   198 
   173 
   199 
   174 template<class E>
   200 template<class E>
   175 bool GenericTaskQueue<E>::push_slow(E t, juint dirty_n_elems) {
   201 bool GenericTaskQueue<E>::push_slow(E t, juint dirty_n_elems) {
   176   if (dirty_n_elems == n() - 1) {
   202   if (dirty_n_elems == n() - 1) {
   177     // Actually means 0, so do the push.
   203     // Actually means 0, so do the push.
   381       return true;
   407       return true;
   382   }
   408   }
   383   return false;
   409   return false;
   384 }
   410 }
   385 
   411 
       
   412 // When to terminate from the termination protocol.
       
   413 class TerminatorTerminator: public CHeapObj {
       
   414 public:
       
   415   virtual bool should_exit_termination() = 0;
       
   416 };
       
   417 
   386 // A class to aid in the termination of a set of parallel tasks using
   418 // A class to aid in the termination of a set of parallel tasks using
   387 // TaskQueueSet's for work stealing.
   419 // TaskQueueSet's for work stealing.
   388 
   420 
   389 class ParallelTaskTerminator: public StackObj {
   421 class ParallelTaskTerminator: public StackObj {
   390 private:
   422 private:
   405 
   437 
   406   // The current thread has no work, and is ready to terminate if everyone
   438   // The current thread has no work, and is ready to terminate if everyone
   407   // else is.  If returns "true", all threads are terminated.  If returns
   439   // else is.  If returns "true", all threads are terminated.  If returns
   408   // "false", available work has been observed in one of the task queues,
   440   // "false", available work has been observed in one of the task queues,
   409   // so the global task is not complete.
   441   // so the global task is not complete.
   410   bool offer_termination();
   442   bool offer_termination() {
       
   443     return offer_termination(NULL);
       
   444   }
       
   445 
       
   446   // As above, but it also terminates of the should_exit_termination()
       
   447   // method of the terminator parameter returns true. If terminator is
       
   448   // NULL, then it is ignored.
       
   449   bool offer_termination(TerminatorTerminator* terminator);
   411 
   450 
   412   // Reset the terminator, so that it may be reused again.
   451   // Reset the terminator, so that it may be reused again.
   413   // The caller is responsible for ensuring that this is done
   452   // The caller is responsible for ensuring that this is done
   414   // in an MT-safe manner, once the previous round of use of
   453   // in an MT-safe manner, once the previous round of use of
   415   // the terminator is finished.
   454   // the terminator is finished.