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 }; |
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. |