Index: doc/theses/thierry_delisle_PhD/code/relaxed_list.hpp
===================================================================
--- doc/theses/thierry_delisle_PhD/code/relaxed_list.hpp	(revision 1b143ded4ae1e7c2af89dc3d277840dae5225d9a)
+++ doc/theses/thierry_delisle_PhD/code/relaxed_list.hpp	(revision 9da5a50e6ddff0e029fb63b11d9539f8432afa31)
@@ -80,4 +80,5 @@
 		size_t success = 0;
 		size_t mask_attempt = 0;
+		size_t mask_reset = 0;
 	} pop;
 };
@@ -143,11 +144,20 @@
 			// Actually push it
 			if(lists[i].push(node)) {
-				numNonEmpty++;
-				size_t qword = i >> 6ull;
-				size_t bit   = i & 63ull;
-				assertf((list_mask[qword] & (1ul << bit)) == 0, "Before set %zu:%zu (%u), %zx & %zx", qword, bit, i, list_mask[qword].load(), (1ul << bit));
-				__attribute__((unused)) bool ret = bts(list_mask[qword], bit);
-				assert(!ret);
-				assertf((list_mask[qword] & (1ul << bit)) != 0, "After set %zu:%zu (%u), %zx & %zx", qword, bit, i, list_mask[qword].load(), (1ul << bit));
+				#if defined(DISCOVER_BITMASK)
+					size_t qword = i >> 6ull;
+					size_t bit   = i & 63ull;
+					assert(qword == 0);
+					bts(tls.mask, bit);
+				#elif !defined(NO_BITMASK)
+					numNonEmpty++;
+					size_t qword = i >> 6ull;
+					size_t bit   = i & 63ull;
+					assertf((list_mask[qword] & (1ul << bit)) == 0, "Before set %zu:%zu (%u), %zx & %zx", qword, bit, i, list_mask[qword].load(), (1ul << bit));
+					__attribute__((unused)) bool ret = bts(list_mask[qword], bit);
+					assert(!ret);
+					assertf((list_mask[qword] & (1ul << bit)) != 0, "After set %zu:%zu (%u), %zx & %zx", qword, bit, i, list_mask[qword].load(), (1ul << bit));
+				#else
+					numNonEmpty++;
+				#endif
 			}
 			assert(numNonEmpty <= (int)numLists);
@@ -166,26 +176,42 @@
 
 	__attribute__((noinline, hot)) node_t * pop() {
-		#if !defined(NO_BITMASK)
-			// for(int r = 0; r < 10 && numNonEmpty != 0; r++) {
-			// 	// Pick two lists at random
-			// 	unsigned i = tls.rng.next() % numLists;
-			// 	unsigned j = tls.rng.next() % numLists;
-
-			// 	if(auto node = try_pop(i, j)) return node;
-			// }
+		#if defined(DISCOVER_BITMASK)
+			assert(numLists <= 64);
+			while(true) {
+				tls.pick.pop.mask_attempt++;
+				unsigned i, j;
+				{
+					// Pick two lists at random
+					unsigned num = ((numLists - 1) >> 6) + 1;
+
+					// Pick first list totally randomly
+					i = tls.rng.next() % numLists;
+
+					// Pick the other according to the bitmask
+					unsigned r = tls.rng.next();
+
+					size_t mask = tls.mask.load(std::memory_order_relaxed);
+					if(mask == 0) {
+						tls.pick.pop.mask_reset++;
+						mask = (1U << numLists) - 1;
+					}
+
+					unsigned b = rand_bit(r, mask);
+
+					assertf(b < 64, "%zu %u", mask, b);
+
+					j = b;
+
+					assert(j < numLists);
+				}
+
+				if(auto node = try_pop(i, j)) return node;
+			}
+		#elif !defined(NO_BITMASK)
 			int nnempty;
 			while(0 != (nnempty = numNonEmpty)) {
 				tls.pick.pop.mask_attempt++;
 				unsigned i, j;
-				// if( numLists < 4 || (numLists / nnempty) < 4 ) {
-				// 	// Pick two lists at random
-				// 	i = tls.rng.next() % numLists;
-				// 	j = tls.rng.next() % numLists;
-				// } else
 				{
-					#ifndef NO_STATS
-						// tls.pick.push.mask_attempt++;
-					#endif
-
 					// Pick two lists at random
 					unsigned num = ((numLists - 1) >> 6) + 1;
@@ -236,4 +262,9 @@
 		#endif
 
+		#if defined(DISCOVER_BITMASK)
+			if(lists[i].ts() > 0) bts(tls.mask, i); else btr(tls.mask, i);
+			if(lists[j].ts() > 0) bts(tls.mask, j); else btr(tls.mask, j);
+		#endif
+
 		// Pick the bet list
 		int w = i;
@@ -264,11 +295,20 @@
 
 		if(emptied) {
-			numNonEmpty--;
-			size_t qword = w >> 6ull;
-			size_t bit   = w & 63ull;
-			assert((list_mask[qword] & (1ul << bit)) != 0);
-			__attribute__((unused)) bool ret = btr(list_mask[qword], bit);
-			assert(ret);
-			assert((list_mask[qword] & (1ul << bit)) == 0);
+			#if defined(DISCOVER_BITMASK)
+				size_t qword = w >> 6ull;
+				size_t bit   = w & 63ull;
+				assert(qword == 0);
+				__attribute__((unused)) bool ret = btr(tls.mask, bit);
+			#elif !defined(NO_BITMASK)
+				numNonEmpty--;
+				size_t qword = w >> 6ull;
+				size_t bit   = w & 63ull;
+				assert((list_mask[qword] & (1ul << bit)) != 0);
+				__attribute__((unused)) bool ret = btr(list_mask[qword], bit);
+				assert(ret);
+				assert((list_mask[qword] & (1ul << bit)) == 0);
+			#else
+				numNonEmpty--;
+			#endif
 		}
 
@@ -417,4 +457,5 @@
 		pick_stat  pick;
 		empty_stat empty;
+		__attribute__((aligned(64))) std::atomic_size_t mask = { 0 };
 	} tls;
 
@@ -444,4 +485,5 @@
 		global_stats.pick.pop .success += tls.pick.pop.success;
 		global_stats.pick.pop .mask_attempt += tls.pick.pop.mask_attempt;
+		global_stats.pick.pop .mask_reset += tls.pick.pop.mask_reset;
 
 		global_stats.qstat.push.value += tls.empty.push.value;
@@ -462,4 +504,5 @@
 				std::atomic_size_t success = { 0 };
 				std::atomic_size_t mask_attempt = { 0 };
+				std::atomic_size_t mask_reset = { 0 };
 			} pop;
 		} pick;
@@ -504,8 +547,10 @@
 		double pop_sur  = (100.0 * double(global.pick.pop .success) / global.pick.pop .attempt);
 		double mpop_sur = (100.0 * double(global.pick.pop .success) / global.pick.pop .mask_attempt);
+		double rpop_sur = (100.0 * double(global.pick.pop .mask_reset) / global.pick.pop .mask_attempt);
 
 		os << "Push   Pick % : " << push_sur << "(" << global.pick.push.success << " / " << global.pick.push.attempt << ")\n";
 		os << "Pop    Pick % : " << pop_sur  << "(" << global.pick.pop .success << " / " << global.pick.pop .attempt << ")\n";
 		os << "TryPop Pick % : " << mpop_sur << "(" << global.pick.pop .success << " / " << global.pick.pop .mask_attempt << ")\n";
+		os << "Pop M Reset % : " << rpop_sur << "(" << global.pick.pop .mask_reset << " / " << global.pick.pop .mask_attempt << ")\n";
 
 		double avgQ_push = double(global.qstat.push.value) / global.qstat.push.count;
