< prev index next >
src/hotspot/share/gc/shared/taskqueue.inline.hpp
Print this page
@@ -35,18 +35,26 @@
template <class T, MEMFLAGS F>
inline GenericTaskQueueSet<T, F>::GenericTaskQueueSet(int n) : _n(n) {
typedef T* GenericTaskQueuePtr;
_queues = NEW_C_HEAP_ARRAY(GenericTaskQueuePtr, n, F);
+ assert(_n < INVALID_QUEUE_ID, "Sanity");
+
+ _last_stolen_queues = NEW_C_HEAP_ARRAY(uint, n, F);
+
+
for (int i = 0; i < n; i++) {
_queues[i] = NULL;
+ _last_stolen_queues[i] = INVALID_QUEUE_ID;
}
}
template <class T, MEMFLAGS F>
inline GenericTaskQueueSet<T, F>::~GenericTaskQueueSet() {
FREE_C_HEAP_ARRAY(T*, _queues);
+ FREE_C_HEAP_ARRAY(uint, _last_stolen_queues);
+
}
template<class E, MEMFLAGS F, unsigned int N>
inline void GenericTaskQueue<E, F, N>::initialize() {
_elems = ArrayAllocator<E>::allocate(N, F);
@@ -252,18 +260,26 @@
template<class T, MEMFLAGS F> bool
GenericTaskQueueSet<T, F>::steal_best_of_2(uint queue_num, int* seed, E& t) {
if (_n > 2) {
uint k1 = queue_num;
+ if (UseOptimizedBestOfTwo && _last_stolen_queues[queue_num] != INVALID_QUEUE_ID) {
+ k1 = _last_stolen_queues[queue_num];
+ }
while (k1 == queue_num) k1 = TaskQueueSetSuper::randomParkAndMiller(seed) % _n;
uint k2 = queue_num;
while (k2 == queue_num || k2 == k1) k2 = TaskQueueSetSuper::randomParkAndMiller(seed) % _n;
// Sample both and try the larger.
uint sz1 = _queues[k1]->size();
uint sz2 = _queues[k2]->size();
- if (sz2 > sz1) return _queues[k2]->pop_global(t);
- else return _queues[k1]->pop_global(t);
+ if (sz2 > sz1) {
+ _last_stolen_queues[queue_num] = k2;
+ return _queues[k2]->pop_global(t);
+ } else {
+ _last_stolen_queues[queue_num] = k1;
+ return _queues[k1]->pop_global(t);
+ }
} else if (_n == 2) {
// Just try the other one.
uint k = (queue_num + 1) % 2;
return _queues[k]->pop_global(t);
} else {
< prev index next >