From 839b3f3171cefdb81cd189217184975e5fdc70df Mon Sep 17 00:00:00 2001
From: Maged Michael <magedmichael@fb.com>
Date: Thu, 9 Mar 2017 11:21:50 -0800
Subject: [PATCH] Detect data race in IndexedMemPool

Summary: IndexedMemPool uses regular memory for the global and local next links. There is a data race as there can be concurrent reads and writes of such links. Added a test for data races.

Reviewed By: nbronson

Differential Revision: D4680286

fbshipit-source-id: 9ef3ed439b9df07d69afe570e516c146caa53a6c
---
 folly/test/IndexedMemPoolTest.cpp | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/folly/test/IndexedMemPoolTest.cpp b/folly/test/IndexedMemPoolTest.cpp
index 69e83124..1e807d43 100644
--- a/folly/test/IndexedMemPoolTest.cpp
+++ b/folly/test/IndexedMemPoolTest.cpp
@@ -216,3 +216,29 @@ TEST(IndexedMemPool, late_recycle) {
   }
   EXPECT_EQ(NonTrivialStruct::count, 0);
 }
+
+TEST(IndexedMemPool, no_data_races) {
+  const int count = 1000;
+  const uint32_t poolSize = 100;
+  const int nthreads = 10;
+
+  using Pool = IndexedMemPool<int, 8, 8>;
+  Pool pool(poolSize);
+
+  std::vector<std::thread> thr(nthreads);
+  for (auto i = 0; i < nthreads; ++i) {
+    thr[i] = std::thread([&]() {
+      for (auto j = 0; j < count; ++j) {
+        uint32_t idx = pool.allocIndex();
+        EXPECT_NE(idx, 0u);
+        EXPECT_LE(
+            idx, poolSize + (pool.NumLocalLists - 1) * pool.LocalListLimit);
+        pool[idx] = j;
+        pool.recycleIndex(idx);
+      }
+    });
+  }
+  for (auto& t : thr) {
+    t.join();
+  }
+}
-- 
2.34.1