src/share/vm/utilities/taskqueue.hpp

changeset 777
37f87013dfd8
parent 548
ba764ed4b6f2
child 791
1ee8caae33af
     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

mercurial