Fix copyright lines
[folly.git] / folly / experimental / test / RefCountTest.cpp
index b9ef475bbdda32c8c6a1f6c86dc9e6a453b07382..928556173043cefa27d4ec7bdea758d5b4bd6e3c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 Facebook, Inc.
+ * Copyright 2015-present Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  */
 #include <thread>
 
-#include <folly/Baton.h>
 #include <folly/experimental/RCURefCount.h>
 #include <folly/experimental/TLRefCount.h>
-
-#include <gtest/gtest.h>
+#include <folly/portability/GTest.h>
+#include <folly/synchronization/Baton.h>
 
 namespace folly {
 
@@ -37,29 +36,29 @@ void basicTest() {
   std::vector<std::thread> ts;
   folly::Baton<> threadBatons[numThreads];
   for (size_t t = 0; t < numThreads; ++t) {
-    ts.emplace_back([&count, &b, &got0, numIters, t, &threadBatons]() {
-        for (size_t i = 0; i < numIters; ++i) {
-          auto ret = ++count;
-
-          EXPECT_TRUE(ret > 1);
-          if (i == 0) {
-            threadBatons[t].post();
-          }
-        }
+    ts.emplace_back([&count, &b, &got0, t, &threadBatons] {
+      for (size_t i = 0; i < numIters; ++i) {
+        auto ret = ++count;
 
-        if (t == 0) {
-          b.post();
+        EXPECT_TRUE(ret > 1);
+        if (i == 0) {
+          threadBatons[t].post();
         }
+      }
+
+      if (t == 0) {
+        b.post();
+      }
 
-        for (size_t i = 0; i < numIters; ++i) {
-          auto ret = --count;
+      for (size_t i = 0; i < numIters; ++i) {
+        auto ret = --count;
 
-          if (ret == 0) {
-            ++got0;
-            EXPECT_EQ(numIters - 1, i);
-          }
+        if (ret == 0) {
+          ++got0;
+          EXPECT_EQ(numIters - 1, i);
         }
-      });
+      }
+    });
   }
 
   for (size_t t = 0; t < numThreads; ++t) {
@@ -83,6 +82,38 @@ void basicTest() {
   EXPECT_EQ(0, ++count);
 }
 
+template <typename RefCount>
+void stressTest(size_t itersCount) {
+  for (size_t i = 0; i < itersCount; ++i) {
+    RefCount count;
+    std::mutex mutex;
+    int a{1};
+
+    std::thread t1([&]() {
+      if (++count) {
+        {
+          std::lock_guard<std::mutex> lg(mutex);
+          EXPECT_EQ(1, a);
+        }
+        --count;
+      }
+    });
+
+    std::thread t2([&]() {
+      count.useGlobal();
+      if (--count == 0) {
+        std::lock_guard<std::mutex> lg(mutex);
+        a = 0;
+      }
+    });
+
+    t1.join();
+    t2.join();
+
+    EXPECT_EQ(0, ++count);
+  }
+}
+
 TEST(RCURefCount, Basic) {
   basicTest<RCURefCount>();
 }
@@ -91,4 +122,13 @@ TEST(TLRefCount, Basic) {
   basicTest<TLRefCount>();
 }
 
+TEST(RCURefCount, Stress) {
+  stressTest<RCURefCount>(100000);
+}
+
+TEST(TLRefCount, Stress) {
+  // This is absurdly slow, so we can't
+  // do it that many times.
+  stressTest<TLRefCount>(500);
 }
+} // namespace folly