Uses cmake to build folly test drivers
[folly.git] / folly / stress-test / stress-parallel-folly-sync.cpp
diff --git a/folly/stress-test/stress-parallel-folly-sync.cpp b/folly/stress-test/stress-parallel-folly-sync.cpp
new file mode 100644 (file)
index 0000000..775252c
--- /dev/null
@@ -0,0 +1,157 @@
+#include <folly/SmallLocks.h>
+#include <folly/RWSpinLock.h>
+#include <folly/SharedMutex.h>
+#include <folly/synchronization/Rcu.h>
+
+#include <gtest/gtest.h>
+
+#include <memory>
+
+namespace {
+
+// MicroLock
+const size_t kMicroLockPassCount = 2000000000;
+typedef folly::MicroLock MicroLock;
+
+// MicroSpinLock
+const size_t kMicroSpinLockPassCount = 1500000000;
+typedef folly::MicroSpinLock MicroSpinLock;
+
+// PicoSpinLock
+const size_t kPicoSpinLockPassCount = 2700000000;
+typedef folly::PicoSpinLock<size_t> PicoSpinLock;
+
+// SharedMutex
+const size_t kSharedMutexPassCount = 5000000;
+typedef folly::SharedMutexReadPriority SharedMutexReadPriority;
+typedef folly::SharedMutexWritePriority SharedMutexWritePriority;
+
+// RWSpinLock
+const size_t kRWSpinLockPassCount = 5000000;
+typedef folly::RWSpinLock RWSpinLock;
+
+// RWTicketSpinLock
+const size_t kRWTicketSpinLockPassCount = 5000000;
+typedef folly::RWTicketSpinLock32 RWTicketSpinLock32;
+typedef folly::RWTicketSpinLock64 RWTicketSpinLock64;
+
+// RCU
+const size_t kRcuSyncPassCount = 180000;
+const size_t kRcuNoSyncPassCount = 3500000;
+// Represent the RCU-protected data.
+struct RcuFoo {
+  size_t f1;
+  size_t f2;
+};
+
+}
+
+void run_rcu_sync(size_t pass_count) {
+  for (int write_percentage = 1; write_percentage <= 5; write_percentage += 1) {
+    for (size_t count = 0; count < pass_count; count++) {
+      for (int i = 0; i < 100; ++i) {
+        if (i < write_percentage) {
+          RcuFoo* f = new RcuFoo();
+          folly::rcu_retire(f);
+          folly::synchronize_rcu();
+        } else {
+          folly::rcu_reader g;
+        }
+      }
+    }
+  }
+}
+
+void run_rcu_no_sync(size_t pass_count) {
+  for (int write_percentage = 1; write_percentage <= 5; write_percentage += 1) {
+    for (size_t count = 0; count < pass_count; count++) {
+      for (int i = 0; i < 100; ++i) {
+        if (i < write_percentage) {
+          RcuFoo* f = new RcuFoo();
+          folly::rcu_retire(f);
+        } else {
+          folly::rcu_reader g;
+        }
+      }
+    }
+  }
+}
+
+template <typename Lock>
+void run_rw_lock(size_t pass_count) {
+  std::unique_ptr<Lock> l(new Lock());
+  for (int write_percentage = 5; write_percentage < 20; write_percentage += 5) {
+    for (size_t count = 0; count < pass_count; count++) {
+      for (int i = 0; i < 100; ++i) {
+        if (i < write_percentage) {
+          l->lock();
+          l->unlock();
+        } else {
+          l->lock_shared();
+          l->unlock_shared();
+        }
+      }
+    }
+  }
+}
+
+template <typename Lock>
+void run_small_lock(size_t pass_count) {
+  std::unique_ptr<Lock> l(new Lock());
+  l->init();
+  for (size_t count = 0; count < pass_count; count++) {
+    l->lock();
+    l->unlock();
+  }
+}
+
+class FollySyncTest: public ::testing::Test {
+
+};
+
+TEST_F(FollySyncTest, FollyRCU_Sync) {
+  run_rcu_sync(kRcuSyncPassCount);
+}
+
+TEST_F(FollySyncTest, FollyRCU_NoSync) {
+  run_rcu_no_sync(kRcuNoSyncPassCount);
+}
+
+TEST_F(FollySyncTest, FollyRWTicketSpinLock_32) {
+  run_rw_lock<RWTicketSpinLock32>(kRWTicketSpinLockPassCount);
+}
+
+TEST_F(FollySyncTest, FollyRWTicketSpinLock_64) {
+  run_rw_lock<RWTicketSpinLock64>(kRWTicketSpinLockPassCount);
+}
+
+TEST_F(FollySyncTest, FollyRWSpinLock) {
+  run_rw_lock<RWSpinLock>(kRWSpinLockPassCount);
+}
+
+TEST_F(FollySyncTest, FollySharedMutex_ReadPriority) {
+  run_rw_lock<SharedMutexReadPriority>(kSharedMutexPassCount);
+}
+
+TEST_F(FollySyncTest, FollySharedMutex_WritePriority) {
+  run_rw_lock<SharedMutexWritePriority>(kSharedMutexPassCount);
+}
+
+TEST_F(FollySyncTest, FollyMicroSpinLock) {
+  run_small_lock<MicroSpinLock>(kMicroSpinLockPassCount);
+}
+
+TEST_F(FollySyncTest, FollyPicoSpinLock) {
+  run_small_lock<PicoSpinLock>(kPicoSpinLockPassCount);
+}
+
+TEST_F(FollySyncTest, FollyMicroLock) {
+  run_small_lock<MicroLock>(kMicroLockPassCount);
+}
+
+int main(int argc, char** argv) {
+  // Init Google test
+  ::testing::InitGoogleTest(&argc, argv);
+  int result = RUN_ALL_TESTS();
+  return result;
+}