Sort #include lines
[folly.git] / folly / test / SmallLocksTest.cpp
index f33e023166a729281e61faf92cc381da85ea5778..1e71086f74f9bef4ed089cd74d4dc043ece3a881 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 Facebook, Inc.
+ * Copyright 2017 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 <folly/SmallLocks.h>
 
-#include <folly/Random.h>
+#include <pthread.h>
 
 #include <cassert>
+#include <condition_variable>
 #include <cstdio>
 #include <mutex>
-#include <condition_variable>
 #include <string>
-#include <vector>
-#include <pthread.h>
-#include <unistd.h>
-
 #include <thread>
+#include <vector>
 
-#include <gtest/gtest.h>
+#include <folly/Random.h>
+#include <folly/portability/Asm.h>
+#include <folly/portability/GTest.h>
+#include <folly/portability/Unistd.h>
 
 using folly::MSLGuard;
 using folly::MicroLock;
@@ -70,12 +70,12 @@ void splock_test() {
   const int max = 1000;
   auto rng = folly::ThreadLocalPRNG();
   for (int i = 0; i < max; i++) {
-    folly::asm_pause();
+    folly::asm_volatile_pause();
     MSLGuard g(v.lock);
 
     int first = v.ar[0];
-    for (size_t i = 1; i < sizeof v.ar / sizeof i; ++i) {
-      EXPECT_EQ(first, v.ar[i]);
+    for (size_t j = 1; j < sizeof v.ar / sizeof j; ++j) {
+      EXPECT_EQ(first, v.ar[j]);
     }
 
     int byte = folly::Random::rand32(rng);
@@ -90,8 +90,9 @@ template<class T> struct PslTest {
   PslTest() { lock.init(); }
 
   void doTest() {
-    T ourVal = rand() % (T(1) << (sizeof(T) * 8 - 1));
-    for (int i = 0; i < 10000; ++i) {
+    using UT = typename std::make_unsigned<T>::type;
+    T ourVal = rand() % T(UT(1) << (sizeof(UT) * 8 - 1));
+    for (int i = 0; i < 100; ++i) {
       std::lock_guard<PicoSpinLock<T>> guard(lock);
       lock.setData(ourVal);
       for (int n = 0; n < 10; ++n) {
@@ -179,7 +180,12 @@ TEST(SmallLocks, RegClobber) {
 }
 
 FOLLY_PACK_PUSH
+#if defined(__SANITIZE_ADDRESS__) && !defined(__clang__) && \
+    (defined(__GNUC__) || defined(__GNUG__))
+static_assert(sizeof(MicroLock) == 4, "Size check failed");
+#else
 static_assert(sizeof(MicroLock) == 1, "Size check failed");
+#endif
 FOLLY_PACK_POP
 
 namespace {
@@ -211,7 +217,7 @@ struct SimpleBarrier {
 };
 }
 
-static void runMicroLockTest() {
+TEST(SmallLocks, MicroLock) {
   volatile uint64_t counters[4] = {0, 0, 0, 0};
   std::vector<std::thread> threads;
   static const unsigned nrThreads = 20;
@@ -224,12 +230,9 @@ static void runMicroLockTest() {
   // affect bits outside the ones MicroLock is defined to affect.
   struct {
     uint8_t a;
-    volatile uint8_t b;
-    union {
-      MicroLock alock;
-      uint8_t c;
-    };
-    volatile uint8_t d;
+    std::atomic<uint8_t> b;
+    MicroLock alock;
+    std::atomic<uint8_t> d;
   } x;
 
   uint8_t origB = 'b';
@@ -237,7 +240,7 @@ static void runMicroLockTest() {
 
   x.a = 'a';
   x.b = origB;
-  x.c = 0;
+  x.alock.init();
   x.d = origD;
 
   // This thread touches other parts of the host word to show that
@@ -282,17 +285,16 @@ static void runMicroLockTest() {
 
   EXPECT_EQ(x.a, 'a');
   EXPECT_EQ(x.b, (uint8_t)(origB + iterPerThread / 2));
-  EXPECT_EQ(x.c, 0);
   EXPECT_EQ(x.d, (uint8_t)(origD + iterPerThread / 2));
   for (unsigned i = 0; i < 4; ++i) {
     EXPECT_EQ(counters[i], ((uint64_t)nrThreads * iterPerThread) / 4);
   }
 }
 
-TEST(SmallLocks, MicroLock) { runMicroLockTest(); }
 TEST(SmallLocks, MicroLockTryLock) {
   MicroLock lock;
   lock.init();
   EXPECT_TRUE(lock.try_lock());
   EXPECT_FALSE(lock.try_lock());
+  lock.unlock();
 }