< 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 >