235 uint k2 = queue_num;
236 while (k2 == queue_num || k2 == k1) k2 = TaskQueueSetSuper::randomParkAndMiller(seed) % _n;
237 // Sample both and try the larger.
238 uint sz1 = _queues[k1]->size();
239 uint sz2 = _queues[k2]->size();
240 if (sz2 > sz1) return _queues[k2]->pop_global(t);
241 else return _queues[k1]->pop_global(t);
242 } else if (_n == 2) {
243 // Just try the other one.
244 uint k = (queue_num + 1) % 2;
245 return _queues[k]->pop_global(t);
246 } else {
247 assert(_n == 1, "can't be zero.");
248 return false;
249 }
250 }
251
252 template<class T, MEMFLAGS F> bool
253 GenericTaskQueueSet<T, F>::steal(uint queue_num, int* seed, E& t) {
254 for (uint i = 0; i < 2 * _n; i++) {
255 if (steal_best_of_2(queue_num, seed, t)) {
256 TASKQUEUE_STATS_ONLY(queue(queue_num)->stats.record_steal(true));
257 return true;
258 }
259 }
260 TASKQUEUE_STATS_ONLY(queue(queue_num)->stats.record_steal(false));
261 return false;
262 }
263
264 template <unsigned int N, MEMFLAGS F>
265 inline typename TaskQueueSuper<N, F>::Age TaskQueueSuper<N, F>::Age::cmpxchg(const Age new_age, const Age old_age) volatile {
266 return Atomic::cmpxchg(new_age._data, &_data, old_age._data);
267 }
268
269 template<class E, MEMFLAGS F, unsigned int N>
270 template<class Fn>
271 inline void GenericTaskQueue<E, F, N>::iterate(Fn fn) {
272 uint iters = size();
273 uint index = _bottom;
274 for (uint i = 0; i < iters; ++i) {
275 index = decrement_index(index);
276 fn(const_cast<E&>(_elems[index])); // cast away volatility
277 }
278 }
279
280
|
235 uint k2 = queue_num;
236 while (k2 == queue_num || k2 == k1) k2 = TaskQueueSetSuper::randomParkAndMiller(seed) % _n;
237 // Sample both and try the larger.
238 uint sz1 = _queues[k1]->size();
239 uint sz2 = _queues[k2]->size();
240 if (sz2 > sz1) return _queues[k2]->pop_global(t);
241 else return _queues[k1]->pop_global(t);
242 } else if (_n == 2) {
243 // Just try the other one.
244 uint k = (queue_num + 1) % 2;
245 return _queues[k]->pop_global(t);
246 } else {
247 assert(_n == 1, "can't be zero.");
248 return false;
249 }
250 }
251
252 template<class T, MEMFLAGS F> bool
253 GenericTaskQueueSet<T, F>::steal(uint queue_num, int* seed, E& t) {
254 for (uint i = 0; i < 2 * _n; i++) {
255 TASKQUEUE_STATS_ONLY(queue(queue_num)->stats.record_steal_attempt());
256 if (steal_best_of_2(queue_num, seed, t)) {
257 TASKQUEUE_STATS_ONLY(queue(queue_num)->stats.record_steal());
258 return true;
259 }
260 }
261 return false;
262 }
263
264 template <unsigned int N, MEMFLAGS F>
265 inline typename TaskQueueSuper<N, F>::Age TaskQueueSuper<N, F>::Age::cmpxchg(const Age new_age, const Age old_age) volatile {
266 return Atomic::cmpxchg(new_age._data, &_data, old_age._data);
267 }
268
269 template<class E, MEMFLAGS F, unsigned int N>
270 template<class Fn>
271 inline void GenericTaskQueue<E, F, N>::iterate(Fn fn) {
272 uint iters = size();
273 uint index = _bottom;
274 for (uint i = 0; i < iters; ++i) {
275 index = decrement_index(index);
276 fn(const_cast<E&>(_elems[index])); // cast away volatility
277 }
278 }
279
280
|