236
237 void set_empty() {
238 _bottom = 0;
239 _age.set(0);
240 }
241
242 // Maximum number of elements allowed in the queue. This is two less
243 // than the actual queue size, for somewhat complicated reasons.
244 uint max_elems() const { return N - 2; }
245
246 // Total size of queue.
247 static const uint total_size() { return N; }
248
249 TASKQUEUE_STATS_ONLY(TaskQueueStats stats;)
250 };
251
252
253
254 template <class E, MEMFLAGS F, unsigned int N = TASKQUEUE_SIZE>
255 class GenericTaskQueue: public TaskQueueSuper<N, F> {
256 protected:
257 typedef typename TaskQueueSuper<N, F>::Age Age;
258 typedef typename TaskQueueSuper<N, F>::idx_t idx_t;
259
260 using TaskQueueSuper<N, F>::_bottom;
261 using TaskQueueSuper<N, F>::_age;
262 using TaskQueueSuper<N, F>::increment_index;
263 using TaskQueueSuper<N, F>::decrement_index;
264 using TaskQueueSuper<N, F>::dirty_size;
265
266 public:
267 using TaskQueueSuper<N, F>::max_elems;
268 using TaskQueueSuper<N, F>::size;
269
270 #if TASKQUEUE_STATS
271 using TaskQueueSuper<N, F>::stats;
272 #endif
273
274 private:
275 // Slow paths for push, pop_local. (pop_global has no fast path.)
297 bool pop_global(E& t);
298
299 // Delete any resource associated with the queue.
300 ~GenericTaskQueue();
301
302 // apply the closure to all elements in the task queue
303 void oops_do(OopClosure* f);
304
305 private:
306 // Element array.
307 volatile E* _elems;
308 };
309
310 template<class E, MEMFLAGS F, unsigned int N>
311 GenericTaskQueue<E, F, N>::GenericTaskQueue() {
312 assert(sizeof(Age) == sizeof(size_t), "Depends on this.");
313 }
314
315 template<class E, MEMFLAGS F, unsigned int N>
316 void GenericTaskQueue<E, F, N>::initialize() {
317 _elems = NEW_C_HEAP_ARRAY(E, N, F);
318 }
319
320 template<class E, MEMFLAGS F, unsigned int N>
321 void GenericTaskQueue<E, F, N>::oops_do(OopClosure* f) {
322 // tty->print_cr("START OopTaskQueue::oops_do");
323 uint iters = size();
324 uint index = _bottom;
325 for (uint i = 0; i < iters; ++i) {
326 index = decrement_index(index);
327 // tty->print_cr(" doing entry %d," INTPTR_T " -> " INTPTR_T,
328 // index, &_elems[index], _elems[index]);
329 E* t = (E*)&_elems[index]; // cast away volatility
330 oop* p = (oop*)t;
331 assert((*t)->is_oop_or_null(), "Not an oop or null");
332 f->do_oop(p);
333 }
334 // tty->print_cr("END OopTaskQueue::oops_do");
335 }
336
337 template<class E, MEMFLAGS F, unsigned int N>
|
236
237 void set_empty() {
238 _bottom = 0;
239 _age.set(0);
240 }
241
242 // Maximum number of elements allowed in the queue. This is two less
243 // than the actual queue size, for somewhat complicated reasons.
244 uint max_elems() const { return N - 2; }
245
246 // Total size of queue.
247 static const uint total_size() { return N; }
248
249 TASKQUEUE_STATS_ONLY(TaskQueueStats stats;)
250 };
251
252
253
254 template <class E, MEMFLAGS F, unsigned int N = TASKQUEUE_SIZE>
255 class GenericTaskQueue: public TaskQueueSuper<N, F> {
256 ArrayAllocator<E, F> _array_allocator;
257 protected:
258 typedef typename TaskQueueSuper<N, F>::Age Age;
259 typedef typename TaskQueueSuper<N, F>::idx_t idx_t;
260
261 using TaskQueueSuper<N, F>::_bottom;
262 using TaskQueueSuper<N, F>::_age;
263 using TaskQueueSuper<N, F>::increment_index;
264 using TaskQueueSuper<N, F>::decrement_index;
265 using TaskQueueSuper<N, F>::dirty_size;
266
267 public:
268 using TaskQueueSuper<N, F>::max_elems;
269 using TaskQueueSuper<N, F>::size;
270
271 #if TASKQUEUE_STATS
272 using TaskQueueSuper<N, F>::stats;
273 #endif
274
275 private:
276 // Slow paths for push, pop_local. (pop_global has no fast path.)
298 bool pop_global(E& t);
299
300 // Delete any resource associated with the queue.
301 ~GenericTaskQueue();
302
303 // apply the closure to all elements in the task queue
304 void oops_do(OopClosure* f);
305
306 private:
307 // Element array.
308 volatile E* _elems;
309 };
310
311 template<class E, MEMFLAGS F, unsigned int N>
312 GenericTaskQueue<E, F, N>::GenericTaskQueue() {
313 assert(sizeof(Age) == sizeof(size_t), "Depends on this.");
314 }
315
316 template<class E, MEMFLAGS F, unsigned int N>
317 void GenericTaskQueue<E, F, N>::initialize() {
318 _elems = _array_allocator.allocate(N);
319 }
320
321 template<class E, MEMFLAGS F, unsigned int N>
322 void GenericTaskQueue<E, F, N>::oops_do(OopClosure* f) {
323 // tty->print_cr("START OopTaskQueue::oops_do");
324 uint iters = size();
325 uint index = _bottom;
326 for (uint i = 0; i < iters; ++i) {
327 index = decrement_index(index);
328 // tty->print_cr(" doing entry %d," INTPTR_T " -> " INTPTR_T,
329 // index, &_elems[index], _elems[index]);
330 E* t = (E*)&_elems[index]; // cast away volatility
331 oop* p = (oop*)t;
332 assert((*t)->is_oop_or_null(), "Not an oop or null");
333 f->do_oop(p);
334 }
335 // tty->print_cr("END OopTaskQueue::oops_do");
336 }
337
338 template<class E, MEMFLAGS F, unsigned int N>
|