1.1 --- a/src/share/vm/utilities/taskqueue.hpp Wed Jun 04 13:51:09 2008 -0700 1.2 +++ b/src/share/vm/utilities/taskqueue.hpp Thu Jun 05 15:57:56 2008 -0700 1.3 @@ -120,6 +120,11 @@ 1.4 return dirty_size(_bottom, get_top()); 1.5 } 1.6 1.7 + void set_empty() { 1.8 + _bottom = 0; 1.9 + _age = Age(); 1.10 + } 1.11 + 1.12 // Maximum number of elements allowed in the queue. This is two less 1.13 // than the actual queue size, for somewhat complicated reasons. 1.14 juint max_elems() { return n() - 2; } 1.15 @@ -155,6 +160,9 @@ 1.16 // Delete any resource associated with the queue. 1.17 ~GenericTaskQueue(); 1.18 1.19 + // apply the closure to all elements in the task queue 1.20 + void oops_do(OopClosure* f); 1.21 + 1.22 private: 1.23 // Element array. 1.24 volatile E* _elems; 1.25 @@ -172,6 +180,24 @@ 1.26 } 1.27 1.28 template<class E> 1.29 +void GenericTaskQueue<E>::oops_do(OopClosure* f) { 1.30 + // tty->print_cr("START OopTaskQueue::oops_do"); 1.31 + int iters = size(); 1.32 + juint index = _bottom; 1.33 + for (int i = 0; i < iters; ++i) { 1.34 + index = decrement_index(index); 1.35 + // tty->print_cr(" doing entry %d," INTPTR_T " -> " INTPTR_T, 1.36 + // index, &_elems[index], _elems[index]); 1.37 + E* t = (E*)&_elems[index]; // cast away volatility 1.38 + oop* p = (oop*)t; 1.39 + assert((*t)->is_oop_or_null(), "Not an oop or null"); 1.40 + f->do_oop(p); 1.41 + } 1.42 + // tty->print_cr("END OopTaskQueue::oops_do"); 1.43 +} 1.44 + 1.45 + 1.46 +template<class E> 1.47 bool GenericTaskQueue<E>::push_slow(E t, juint dirty_n_elems) { 1.48 if (dirty_n_elems == n() - 1) { 1.49 // Actually means 0, so do the push. 1.50 @@ -383,6 +409,12 @@ 1.51 return false; 1.52 } 1.53 1.54 +// When to terminate from the termination protocol. 1.55 +class TerminatorTerminator: public CHeapObj { 1.56 +public: 1.57 + virtual bool should_exit_termination() = 0; 1.58 +}; 1.59 + 1.60 // A class to aid in the termination of a set of parallel tasks using 1.61 // TaskQueueSet's for work stealing. 1.62 1.63 @@ -407,7 +439,14 @@ 1.64 // else is. If returns "true", all threads are terminated. If returns 1.65 // "false", available work has been observed in one of the task queues, 1.66 // so the global task is not complete. 1.67 - bool offer_termination(); 1.68 + bool offer_termination() { 1.69 + return offer_termination(NULL); 1.70 + } 1.71 + 1.72 + // As above, but it also terminates of the should_exit_termination() 1.73 + // method of the terminator parameter returns true. If terminator is 1.74 + // NULL, then it is ignored. 1.75 + bool offer_termination(TerminatorTerminator* terminator); 1.76 1.77 // Reset the terminator, so that it may be reused again. 1.78 // The caller is responsible for ensuring that this is done