src/share/vm/utilities/taskqueue.hpp

changeset 1993
b2a00dd3117c
parent 1907
c18cbe5936b8
child 2020
a93a9eda13f7
     1.1 --- a/src/share/vm/utilities/taskqueue.hpp	Wed Jun 30 11:52:10 2010 -0400
     1.2 +++ b/src/share/vm/utilities/taskqueue.hpp	Thu Jul 01 21:40:45 2010 -0700
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -109,8 +109,9 @@
    1.11  public:
    1.12    TaskQueueSuper() : _bottom(0), _age() {}
    1.13  
    1.14 -  // Return true if the TaskQueue contains any tasks.
    1.15 -  bool peek() { return _bottom != _age.top(); }
    1.16 +  // Return true if the TaskQueue contains/does not contain any tasks.
    1.17 +  bool peek()     const { return _bottom != _age.top(); }
    1.18 +  bool is_empty() const { return size() == 0; }
    1.19  
    1.20    // Return an estimate of the number of elements in the queue.
    1.21    // The "careful" version admits the possibility of pop_local/pop_global
    1.22 @@ -165,18 +166,16 @@
    1.23  
    1.24    void initialize();
    1.25  
    1.26 -  // Push the task "t" on the queue.  Returns "false" iff the queue is
    1.27 -  // full.
    1.28 +  // Push the task "t" on the queue.  Returns "false" iff the queue is full.
    1.29    inline bool push(E t);
    1.30  
    1.31 -  // If succeeds in claiming a task (from the 'local' end, that is, the
    1.32 -  // most recently pushed task), returns "true" and sets "t" to that task.
    1.33 -  // Otherwise, the queue is empty and returns false.
    1.34 +  // Attempts to claim a task from the "local" end of the queue (the most
    1.35 +  // recently pushed).  If successful, returns true and sets t to the task;
    1.36 +  // otherwise, returns false (the queue is empty).
    1.37    inline bool pop_local(E& t);
    1.38  
    1.39 -  // If succeeds in claiming a task (from the 'global' end, that is, the
    1.40 -  // least recently pushed task), returns "true" and sets "t" to that task.
    1.41 -  // Otherwise, the queue is empty and returns false.
    1.42 +  // Like pop_local(), but uses the "global" end of the queue (the least
    1.43 +  // recently pushed).
    1.44    bool pop_global(E& t);
    1.45  
    1.46    // Delete any resource associated with the queue.
    1.47 @@ -198,7 +197,6 @@
    1.48  template<class E, unsigned int N>
    1.49  void GenericTaskQueue<E, N>::initialize() {
    1.50    _elems = NEW_C_HEAP_ARRAY(E, N);
    1.51 -  guarantee(_elems != NULL, "Allocation failed.");
    1.52  }
    1.53  
    1.54  template<class E, unsigned int N>
    1.55 @@ -289,7 +287,87 @@
    1.56    FREE_C_HEAP_ARRAY(E, _elems);
    1.57  }
    1.58  
    1.59 -// Inherits the typedef of "Task" from above.
    1.60 +// OverflowTaskQueue is a TaskQueue that also includes an overflow stack for
    1.61 +// elements that do not fit in the TaskQueue.
    1.62 +//
    1.63 +// Three methods from super classes are overridden:
    1.64 +//
    1.65 +// initialize() - initialize the super classes and create the overflow stack
    1.66 +// push() - push onto the task queue or, if that fails, onto the overflow stack
    1.67 +// is_empty() - return true if both the TaskQueue and overflow stack are empty
    1.68 +//
    1.69 +// Note that size() is not overridden--it returns the number of elements in the
    1.70 +// TaskQueue, and does not include the size of the overflow stack.  This
    1.71 +// simplifies replacement of GenericTaskQueues with OverflowTaskQueues.
    1.72 +template<class E, unsigned int N = TASKQUEUE_SIZE>
    1.73 +class OverflowTaskQueue: public GenericTaskQueue<E, N>
    1.74 +{
    1.75 +public:
    1.76 +  typedef GrowableArray<E>       overflow_t;
    1.77 +  typedef GenericTaskQueue<E, N> taskqueue_t;
    1.78 +
    1.79 +  OverflowTaskQueue();
    1.80 +  ~OverflowTaskQueue();
    1.81 +  void initialize();
    1.82 +
    1.83 +  inline overflow_t* overflow_stack() const { return _overflow_stack; }
    1.84 +
    1.85 +  // Push task t onto the queue or onto the overflow stack.  Return true.
    1.86 +  inline bool push(E t);
    1.87 +
    1.88 +  // Attempt to pop from the overflow stack; return true if anything was popped.
    1.89 +  inline bool pop_overflow(E& t);
    1.90 +
    1.91 +  inline bool taskqueue_empty() const { return taskqueue_t::is_empty(); }
    1.92 +  inline bool overflow_empty()  const { return overflow_stack()->is_empty(); }
    1.93 +  inline bool is_empty()        const {
    1.94 +    return taskqueue_empty() && overflow_empty();
    1.95 +  }
    1.96 +
    1.97 +private:
    1.98 +  overflow_t* _overflow_stack;
    1.99 +};
   1.100 +
   1.101 +template <class E, unsigned int N>
   1.102 +OverflowTaskQueue<E, N>::OverflowTaskQueue()
   1.103 +{
   1.104 +  _overflow_stack = NULL;
   1.105 +}
   1.106 +
   1.107 +template <class E, unsigned int N>
   1.108 +OverflowTaskQueue<E, N>::~OverflowTaskQueue()
   1.109 +{
   1.110 +  if (_overflow_stack != NULL) {
   1.111 +    delete _overflow_stack;
   1.112 +    _overflow_stack = NULL;
   1.113 +  }
   1.114 +}
   1.115 +
   1.116 +template <class E, unsigned int N>
   1.117 +void OverflowTaskQueue<E, N>::initialize()
   1.118 +{
   1.119 +  taskqueue_t::initialize();
   1.120 +  assert(_overflow_stack == NULL, "memory leak");
   1.121 +  _overflow_stack = new (ResourceObj::C_HEAP) GrowableArray<E>(10, true);
   1.122 +}
   1.123 +
   1.124 +template <class E, unsigned int N>
   1.125 +bool OverflowTaskQueue<E, N>::push(E t)
   1.126 +{
   1.127 +  if (!taskqueue_t::push(t)) {
   1.128 +    overflow_stack()->push(t);
   1.129 +  }
   1.130 +  return true;
   1.131 +}
   1.132 +
   1.133 +template <class E, unsigned int N>
   1.134 +bool OverflowTaskQueue<E, N>::pop_overflow(E& t)
   1.135 +{
   1.136 +  if (overflow_empty()) return false;
   1.137 +  t = overflow_stack()->pop();
   1.138 +  return true;
   1.139 +}
   1.140 +
   1.141  class TaskQueueSetSuper: public CHeapObj {
   1.142  protected:
   1.143    static int randomParkAndMiller(int* seed0);
   1.144 @@ -323,11 +401,11 @@
   1.145  
   1.146    T* queue(uint n);
   1.147  
   1.148 -  // The thread with queue number "queue_num" (and whose random number seed
   1.149 -  // is at "seed") is trying to steal a task from some other queue.  (It
   1.150 -  // may try several queues, according to some configuration parameter.)
   1.151 -  // If some steal succeeds, returns "true" and sets "t" the stolen task,
   1.152 -  // otherwise returns false.
   1.153 +  // The thread with queue number "queue_num" (and whose random number seed is
   1.154 +  // at "seed") is trying to steal a task from some other queue.  (It may try
   1.155 +  // several queues, according to some configuration parameter.)  If some steal
   1.156 +  // succeeds, returns "true" and sets "t" to the stolen task, otherwise returns
   1.157 +  // false.
   1.158    bool steal(uint queue_num, int* seed, E& t);
   1.159  
   1.160    bool peek();
   1.161 @@ -507,7 +585,7 @@
   1.162    uint localBot = _bottom;
   1.163    // This value cannot be N-1.  That can only occur as a result of
   1.164    // the assignment to bottom in this method.  If it does, this method
   1.165 -  // resets the size( to 0 before the next call (which is sequential,
   1.166 +  // resets the size to 0 before the next call (which is sequential,
   1.167    // since this is pop_local.)
   1.168    uint dirty_n_elems = dirty_size(localBot, _age.top());
   1.169    assert(dirty_n_elems != N - 1, "Shouldn't be possible...");
   1.170 @@ -533,8 +611,7 @@
   1.171    }
   1.172  }
   1.173  
   1.174 -typedef oop Task;
   1.175 -typedef GenericTaskQueue<Task>            OopTaskQueue;
   1.176 +typedef GenericTaskQueue<oop>             OopTaskQueue;
   1.177  typedef GenericTaskQueueSet<OopTaskQueue> OopTaskQueueSet;
   1.178  
   1.179  #ifdef _MSC_VER
   1.180 @@ -615,35 +692,8 @@
   1.181  #pragma warning(pop)
   1.182  #endif
   1.183  
   1.184 -typedef GenericTaskQueue<StarTask>            OopStarTaskQueue;
   1.185 +typedef OverflowTaskQueue<StarTask>           OopStarTaskQueue;
   1.186  typedef GenericTaskQueueSet<OopStarTaskQueue> OopStarTaskQueueSet;
   1.187  
   1.188 -typedef size_t RegionTask;  // index for region
   1.189 -typedef GenericTaskQueue<RegionTask>         RegionTaskQueue;
   1.190 -typedef GenericTaskQueueSet<RegionTaskQueue> RegionTaskQueueSet;
   1.191 -
   1.192 -class RegionTaskQueueWithOverflow: public CHeapObj {
   1.193 - protected:
   1.194 -  RegionTaskQueue              _region_queue;
   1.195 -  GrowableArray<RegionTask>*   _overflow_stack;
   1.196 -
   1.197 - public:
   1.198 -  RegionTaskQueueWithOverflow() : _overflow_stack(NULL) {}
   1.199 -  // Initialize both stealable queue and overflow
   1.200 -  void initialize();
   1.201 -  // Save first to stealable queue and then to overflow
   1.202 -  void save(RegionTask t);
   1.203 -  // Retrieve first from overflow and then from stealable queue
   1.204 -  bool retrieve(RegionTask& region_index);
   1.205 -  // Retrieve from stealable queue
   1.206 -  bool retrieve_from_stealable_queue(RegionTask& region_index);
   1.207 -  // Retrieve from overflow
   1.208 -  bool retrieve_from_overflow(RegionTask& region_index);
   1.209 -  bool is_empty();
   1.210 -  bool stealable_is_empty();
   1.211 -  bool overflow_is_empty();
   1.212 -  uint stealable_size() { return _region_queue.size(); }
   1.213 -  RegionTaskQueue* task_queue() { return &_region_queue; }
   1.214 -};
   1.215 -
   1.216 -#define USE_RegionTaskQueueWithOverflow
   1.217 +typedef OverflowTaskQueue<size_t>             RegionTaskQueue;
   1.218 +typedef GenericTaskQueueSet<RegionTaskQueue>  RegionTaskQueueSet;

mercurial