src/share/vm/utilities/taskqueue.hpp

changeset 3900
d2a62e0f25eb
parent 3156
f08d439fab8c
child 4153
b9a9ed0f8eeb
     1.1 --- a/src/share/vm/utilities/taskqueue.hpp	Wed Jun 27 15:23:36 2012 +0200
     1.2 +++ b/src/share/vm/utilities/taskqueue.hpp	Thu Jun 28 17:03:16 2012 -0400
     1.3 @@ -132,8 +132,8 @@
     1.4  }
     1.5  #endif // TASKQUEUE_STATS
     1.6  
     1.7 -template <unsigned int N>
     1.8 -class TaskQueueSuper: public CHeapObj {
     1.9 +template <unsigned int N, MEMFLAGS F>
    1.10 +class TaskQueueSuper: public CHeapObj<F> {
    1.11  protected:
    1.12    // Internal type for indexing the queue; also used for the tag.
    1.13    typedef NOT_LP64(uint16_t) LP64_ONLY(uint32_t) idx_t;
    1.14 @@ -249,22 +249,27 @@
    1.15    TASKQUEUE_STATS_ONLY(TaskQueueStats stats;)
    1.16  };
    1.17  
    1.18 -template<class E, unsigned int N = TASKQUEUE_SIZE>
    1.19 -class GenericTaskQueue: public TaskQueueSuper<N> {
    1.20 +
    1.21 +
    1.22 +template <class E, MEMFLAGS F, unsigned int N = TASKQUEUE_SIZE>
    1.23 +class GenericTaskQueue: public TaskQueueSuper<N, F> {
    1.24  protected:
    1.25 -  typedef typename TaskQueueSuper<N>::Age Age;
    1.26 -  typedef typename TaskQueueSuper<N>::idx_t idx_t;
    1.27 +  typedef typename TaskQueueSuper<N, F>::Age Age;
    1.28 +  typedef typename TaskQueueSuper<N, F>::idx_t idx_t;
    1.29  
    1.30 -  using TaskQueueSuper<N>::_bottom;
    1.31 -  using TaskQueueSuper<N>::_age;
    1.32 -  using TaskQueueSuper<N>::increment_index;
    1.33 -  using TaskQueueSuper<N>::decrement_index;
    1.34 -  using TaskQueueSuper<N>::dirty_size;
    1.35 +  using TaskQueueSuper<N, F>::_bottom;
    1.36 +  using TaskQueueSuper<N, F>::_age;
    1.37 +  using TaskQueueSuper<N, F>::increment_index;
    1.38 +  using TaskQueueSuper<N, F>::decrement_index;
    1.39 +  using TaskQueueSuper<N, F>::dirty_size;
    1.40  
    1.41  public:
    1.42 -  using TaskQueueSuper<N>::max_elems;
    1.43 -  using TaskQueueSuper<N>::size;
    1.44 -  TASKQUEUE_STATS_ONLY(using TaskQueueSuper<N>::stats;)
    1.45 +  using TaskQueueSuper<N, F>::max_elems;
    1.46 +  using TaskQueueSuper<N, F>::size;
    1.47 +
    1.48 +#if  TASKQUEUE_STATS
    1.49 +  using TaskQueueSuper<N, F>::stats;
    1.50 +#endif
    1.51  
    1.52  private:
    1.53    // Slow paths for push, pop_local.  (pop_global has no fast path.)
    1.54 @@ -302,18 +307,18 @@
    1.55    volatile E* _elems;
    1.56  };
    1.57  
    1.58 -template<class E, unsigned int N>
    1.59 -GenericTaskQueue<E, N>::GenericTaskQueue() {
    1.60 +template<class E, MEMFLAGS F, unsigned int N>
    1.61 +GenericTaskQueue<E, F, N>::GenericTaskQueue() {
    1.62    assert(sizeof(Age) == sizeof(size_t), "Depends on this.");
    1.63  }
    1.64  
    1.65 -template<class E, unsigned int N>
    1.66 -void GenericTaskQueue<E, N>::initialize() {
    1.67 -  _elems = NEW_C_HEAP_ARRAY(E, N);
    1.68 +template<class E, MEMFLAGS F, unsigned int N>
    1.69 +void GenericTaskQueue<E, F, N>::initialize() {
    1.70 +  _elems = NEW_C_HEAP_ARRAY(E, N, F);
    1.71  }
    1.72  
    1.73 -template<class E, unsigned int N>
    1.74 -void GenericTaskQueue<E, N>::oops_do(OopClosure* f) {
    1.75 +template<class E, MEMFLAGS F, unsigned int N>
    1.76 +void GenericTaskQueue<E, F, N>::oops_do(OopClosure* f) {
    1.77    // tty->print_cr("START OopTaskQueue::oops_do");
    1.78    uint iters = size();
    1.79    uint index = _bottom;
    1.80 @@ -329,8 +334,8 @@
    1.81    // tty->print_cr("END OopTaskQueue::oops_do");
    1.82  }
    1.83  
    1.84 -template<class E, unsigned int N>
    1.85 -bool GenericTaskQueue<E, N>::push_slow(E t, uint dirty_n_elems) {
    1.86 +template<class E, MEMFLAGS F, unsigned int N>
    1.87 +bool GenericTaskQueue<E, F, N>::push_slow(E t, uint dirty_n_elems) {
    1.88    if (dirty_n_elems == N - 1) {
    1.89      // Actually means 0, so do the push.
    1.90      uint localBot = _bottom;
    1.91 @@ -349,8 +354,8 @@
    1.92  // whenever the queue goes empty which it will do here if this thread
    1.93  // gets the last task or in pop_global() if the queue wraps (top == 0
    1.94  // and pop_global() succeeds, see pop_global()).
    1.95 -template<class E, unsigned int N>
    1.96 -bool GenericTaskQueue<E, N>::pop_local_slow(uint localBot, Age oldAge) {
    1.97 +template<class E, MEMFLAGS F, unsigned int N>
    1.98 +bool GenericTaskQueue<E, F, N>::pop_local_slow(uint localBot, Age oldAge) {
    1.99    // This queue was observed to contain exactly one element; either this
   1.100    // thread will claim it, or a competing "pop_global".  In either case,
   1.101    // the queue will be logically empty afterwards.  Create a new Age value
   1.102 @@ -382,8 +387,8 @@
   1.103    return false;
   1.104  }
   1.105  
   1.106 -template<class E, unsigned int N>
   1.107 -bool GenericTaskQueue<E, N>::pop_global(E& t) {
   1.108 +template<class E, MEMFLAGS F, unsigned int N>
   1.109 +bool GenericTaskQueue<E, F, N>::pop_global(E& t) {
   1.110    Age oldAge = _age.get();
   1.111    uint localBot = _bottom;
   1.112    uint n_elems = size(localBot, oldAge.top());
   1.113 @@ -402,9 +407,9 @@
   1.114    return resAge == oldAge;
   1.115  }
   1.116  
   1.117 -template<class E, unsigned int N>
   1.118 -GenericTaskQueue<E, N>::~GenericTaskQueue() {
   1.119 -  FREE_C_HEAP_ARRAY(E, _elems);
   1.120 +template<class E, MEMFLAGS F, unsigned int N>
   1.121 +GenericTaskQueue<E, F, N>::~GenericTaskQueue() {
   1.122 +  FREE_C_HEAP_ARRAY(E, _elems, F);
   1.123  }
   1.124  
   1.125  // OverflowTaskQueue is a TaskQueue that also includes an overflow stack for
   1.126 @@ -418,12 +423,12 @@
   1.127  // Note that size() is not hidden--it returns the number of elements in the
   1.128  // TaskQueue, and does not include the size of the overflow stack.  This
   1.129  // simplifies replacement of GenericTaskQueues with OverflowTaskQueues.
   1.130 -template<class E, unsigned int N = TASKQUEUE_SIZE>
   1.131 -class OverflowTaskQueue: public GenericTaskQueue<E, N>
   1.132 +template<class E, MEMFLAGS F, unsigned int N = TASKQUEUE_SIZE>
   1.133 +class OverflowTaskQueue: public GenericTaskQueue<E, F, N>
   1.134  {
   1.135  public:
   1.136 -  typedef Stack<E>               overflow_t;
   1.137 -  typedef GenericTaskQueue<E, N> taskqueue_t;
   1.138 +  typedef Stack<E, F>               overflow_t;
   1.139 +  typedef GenericTaskQueue<E, F, N> taskqueue_t;
   1.140  
   1.141    TASKQUEUE_STATS_ONLY(using taskqueue_t::stats;)
   1.142  
   1.143 @@ -445,8 +450,8 @@
   1.144    overflow_t _overflow_stack;
   1.145  };
   1.146  
   1.147 -template <class E, unsigned int N>
   1.148 -bool OverflowTaskQueue<E, N>::push(E t)
   1.149 +template <class E, MEMFLAGS F, unsigned int N>
   1.150 +bool OverflowTaskQueue<E, F, N>::push(E t)
   1.151  {
   1.152    if (!taskqueue_t::push(t)) {
   1.153      overflow_stack()->push(t);
   1.154 @@ -455,15 +460,15 @@
   1.155    return true;
   1.156  }
   1.157  
   1.158 -template <class E, unsigned int N>
   1.159 -bool OverflowTaskQueue<E, N>::pop_overflow(E& t)
   1.160 +template <class E, MEMFLAGS F, unsigned int N>
   1.161 +bool OverflowTaskQueue<E, F, N>::pop_overflow(E& t)
   1.162  {
   1.163    if (overflow_empty()) return false;
   1.164    t = overflow_stack()->pop();
   1.165    return true;
   1.166  }
   1.167  
   1.168 -class TaskQueueSetSuper: public CHeapObj {
   1.169 +class TaskQueueSetSuper {
   1.170  protected:
   1.171    static int randomParkAndMiller(int* seed0);
   1.172  public:
   1.173 @@ -471,8 +476,11 @@
   1.174    virtual bool peek() = 0;
   1.175  };
   1.176  
   1.177 -template<class T>
   1.178 -class GenericTaskQueueSet: public TaskQueueSetSuper {
   1.179 +template <MEMFLAGS F> class TaskQueueSetSuperImpl: public CHeapObj<F>, public TaskQueueSetSuper {
   1.180 +};
   1.181 +
   1.182 +template<class T, MEMFLAGS F>
   1.183 +class GenericTaskQueueSet: public TaskQueueSetSuperImpl<F> {
   1.184  private:
   1.185    uint _n;
   1.186    T** _queues;
   1.187 @@ -482,7 +490,7 @@
   1.188  
   1.189    GenericTaskQueueSet(int n) : _n(n) {
   1.190      typedef T* GenericTaskQueuePtr;
   1.191 -    _queues = NEW_C_HEAP_ARRAY(GenericTaskQueuePtr, n);
   1.192 +    _queues = NEW_C_HEAP_ARRAY(GenericTaskQueuePtr, n, F);
   1.193      for (int i = 0; i < n; i++) {
   1.194        _queues[i] = NULL;
   1.195      }
   1.196 @@ -506,19 +514,19 @@
   1.197    bool peek();
   1.198  };
   1.199  
   1.200 -template<class T> void
   1.201 -GenericTaskQueueSet<T>::register_queue(uint i, T* q) {
   1.202 +template<class T, MEMFLAGS F> void
   1.203 +GenericTaskQueueSet<T, F>::register_queue(uint i, T* q) {
   1.204    assert(i < _n, "index out of range.");
   1.205    _queues[i] = q;
   1.206  }
   1.207  
   1.208 -template<class T> T*
   1.209 -GenericTaskQueueSet<T>::queue(uint i) {
   1.210 +template<class T, MEMFLAGS F> T*
   1.211 +GenericTaskQueueSet<T, F>::queue(uint i) {
   1.212    return _queues[i];
   1.213  }
   1.214  
   1.215 -template<class T> bool
   1.216 -GenericTaskQueueSet<T>::steal(uint queue_num, int* seed, E& t) {
   1.217 +template<class T, MEMFLAGS F> bool
   1.218 +GenericTaskQueueSet<T, F>::steal(uint queue_num, int* seed, E& t) {
   1.219    for (uint i = 0; i < 2 * _n; i++) {
   1.220      if (steal_best_of_2(queue_num, seed, t)) {
   1.221        TASKQUEUE_STATS_ONLY(queue(queue_num)->stats.record_steal(true));
   1.222 @@ -529,8 +537,8 @@
   1.223    return false;
   1.224  }
   1.225  
   1.226 -template<class T> bool
   1.227 -GenericTaskQueueSet<T>::steal_best_of_all(uint queue_num, int* seed, E& t) {
   1.228 +template<class T, MEMFLAGS F> bool
   1.229 +GenericTaskQueueSet<T, F>::steal_best_of_all(uint queue_num, int* seed, E& t) {
   1.230    if (_n > 2) {
   1.231      int best_k;
   1.232      uint best_sz = 0;
   1.233 @@ -553,11 +561,11 @@
   1.234    }
   1.235  }
   1.236  
   1.237 -template<class T> bool
   1.238 -GenericTaskQueueSet<T>::steal_1_random(uint queue_num, int* seed, E& t) {
   1.239 +template<class T, MEMFLAGS F> bool
   1.240 +GenericTaskQueueSet<T, F>::steal_1_random(uint queue_num, int* seed, E& t) {
   1.241    if (_n > 2) {
   1.242      uint k = queue_num;
   1.243 -    while (k == queue_num) k = randomParkAndMiller(seed) % _n;
   1.244 +    while (k == queue_num) k = TaskQueueSetSuper::randomParkAndMiller(seed) % _n;
   1.245      return _queues[2]->pop_global(t);
   1.246    } else if (_n == 2) {
   1.247      // Just try the other one.
   1.248 @@ -569,13 +577,13 @@
   1.249    }
   1.250  }
   1.251  
   1.252 -template<class T> bool
   1.253 -GenericTaskQueueSet<T>::steal_best_of_2(uint queue_num, int* seed, E& t) {
   1.254 +template<class T, MEMFLAGS F> bool
   1.255 +GenericTaskQueueSet<T, F>::steal_best_of_2(uint queue_num, int* seed, E& t) {
   1.256    if (_n > 2) {
   1.257      uint k1 = queue_num;
   1.258 -    while (k1 == queue_num) k1 = randomParkAndMiller(seed) % _n;
   1.259 +    while (k1 == queue_num) k1 = TaskQueueSetSuper::randomParkAndMiller(seed) % _n;
   1.260      uint k2 = queue_num;
   1.261 -    while (k2 == queue_num || k2 == k1) k2 = randomParkAndMiller(seed) % _n;
   1.262 +    while (k2 == queue_num || k2 == k1) k2 = TaskQueueSetSuper::randomParkAndMiller(seed) % _n;
   1.263      // Sample both and try the larger.
   1.264      uint sz1 = _queues[k1]->size();
   1.265      uint sz2 = _queues[k2]->size();
   1.266 @@ -591,8 +599,8 @@
   1.267    }
   1.268  }
   1.269  
   1.270 -template<class T>
   1.271 -bool GenericTaskQueueSet<T>::peek() {
   1.272 +template<class T, MEMFLAGS F>
   1.273 +bool GenericTaskQueueSet<T, F>::peek() {
   1.274    // Try all the queues.
   1.275    for (uint j = 0; j < _n; j++) {
   1.276      if (_queues[j]->peek())
   1.277 @@ -602,7 +610,7 @@
   1.278  }
   1.279  
   1.280  // When to terminate from the termination protocol.
   1.281 -class TerminatorTerminator: public CHeapObj {
   1.282 +class TerminatorTerminator: public CHeapObj<mtInternal> {
   1.283  public:
   1.284    virtual bool should_exit_termination() = 0;
   1.285  };
   1.286 @@ -665,8 +673,8 @@
   1.287  #endif
   1.288  };
   1.289  
   1.290 -template<class E, unsigned int N> inline bool
   1.291 -GenericTaskQueue<E, N>::push(E t) {
   1.292 +template<class E, MEMFLAGS F, unsigned int N> inline bool
   1.293 +GenericTaskQueue<E, F, N>::push(E t) {
   1.294    uint localBot = _bottom;
   1.295    assert((localBot >= 0) && (localBot < N), "_bottom out of range.");
   1.296    idx_t top = _age.top();
   1.297 @@ -683,8 +691,8 @@
   1.298    }
   1.299  }
   1.300  
   1.301 -template<class E, unsigned int N> inline bool
   1.302 -GenericTaskQueue<E, N>::pop_local(E& t) {
   1.303 +template<class E, MEMFLAGS F, unsigned int N> inline bool
   1.304 +GenericTaskQueue<E, F, N>::pop_local(E& t) {
   1.305    uint localBot = _bottom;
   1.306    // This value cannot be N-1.  That can only occur as a result of
   1.307    // the assignment to bottom in this method.  If it does, this method
   1.308 @@ -715,8 +723,8 @@
   1.309    }
   1.310  }
   1.311  
   1.312 -typedef GenericTaskQueue<oop>             OopTaskQueue;
   1.313 -typedef GenericTaskQueueSet<OopTaskQueue> OopTaskQueueSet;
   1.314 +typedef GenericTaskQueue<oop, mtGC>             OopTaskQueue;
   1.315 +typedef GenericTaskQueueSet<OopTaskQueue, mtGC> OopTaskQueueSet;
   1.316  
   1.317  #ifdef _MSC_VER
   1.318  #pragma warning(push)
   1.319 @@ -796,11 +804,11 @@
   1.320  #pragma warning(pop)
   1.321  #endif
   1.322  
   1.323 -typedef OverflowTaskQueue<StarTask>           OopStarTaskQueue;
   1.324 -typedef GenericTaskQueueSet<OopStarTaskQueue> OopStarTaskQueueSet;
   1.325 +typedef OverflowTaskQueue<StarTask, mtClass>           OopStarTaskQueue;
   1.326 +typedef GenericTaskQueueSet<OopStarTaskQueue, mtClass> OopStarTaskQueueSet;
   1.327  
   1.328 -typedef OverflowTaskQueue<size_t>             RegionTaskQueue;
   1.329 -typedef GenericTaskQueueSet<RegionTaskQueue>  RegionTaskQueueSet;
   1.330 +typedef OverflowTaskQueue<size_t, mtInternal>             RegionTaskQueue;
   1.331 +typedef GenericTaskQueueSet<RegionTaskQueue, mtClass>     RegionTaskQueueSet;
   1.332  
   1.333  
   1.334  #endif // SHARE_VM_UTILITIES_TASKQUEUE_HPP

mercurial