Fix data race in Futex<EmulatedFutexAtomic>
[folly.git] / folly / test / AtomicLinkedListTest.cpp
index b9435f75ca5d598ae6b446dca82ee1e884766f3c..303261ff06e92cf023d5a5b2f8e57fc7db8e1bf1 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.
  * limitations under the License.
  */
 
+#include <algorithm>
 #include <thread>
 
-#include <gtest/gtest.h>
-
 #include <folly/AtomicLinkedList.h>
+#include <folly/portability/GTest.h>
 
 class TestIntrusiveObject {
  public:
   explicit TestIntrusiveObject(size_t id__) : id_(id__) {}
-  size_t id() { return id_; }
+  size_t id() {
+    return id_;
+  }
 
  private:
   folly::AtomicIntrusiveLinkedListHook<TestIntrusiveObject> hook_;
   size_t id_;
 
  public:
-  using List = folly::AtomicIntrusiveLinkedList<TestIntrusiveObject,
-                                                &TestIntrusiveObject::hook_>;
+  using List = folly::AtomicIntrusiveLinkedList<
+      TestIntrusiveObject,
+      &TestIntrusiveObject::hook_>;
 };
 
 TEST(AtomicIntrusiveLinkedList, Basic) {
@@ -71,6 +74,23 @@ TEST(AtomicIntrusiveLinkedList, Basic) {
   TestIntrusiveObject::List movedList = std::move(list);
 }
 
+TEST(AtomicIntrusiveLinkedList, ReverseSweep) {
+  TestIntrusiveObject a(1), b(2), c(3);
+  TestIntrusiveObject::List list;
+  list.insertHead(&a);
+  list.insertHead(&b);
+  list.insertHead(&c);
+  size_t next_expected_id = 3;
+  list.reverseSweep([&](TestIntrusiveObject* obj) {
+    EXPECT_EQ(next_expected_id--, obj->id());
+  });
+  EXPECT_TRUE(list.empty());
+  // Test that we can still insert
+  list.insertHead(&a);
+  EXPECT_FALSE(list.empty());
+  list.reverseSweep([](TestIntrusiveObject*) {});
+}
+
 TEST(AtomicIntrusiveLinkedList, Move) {
   TestIntrusiveObject a(1), b(2);
 
@@ -124,7 +144,7 @@ TEST(AtomicIntrusiveLinkedList, Stress) {
   std::vector<size_t> ids;
   TestIntrusiveObject* prev{nullptr};
 
-  while (ids.size() < kNumThreads * kNumThreads) {
+  while (ids.size() < kNumThreads * kNumElements) {
     list.sweep([&](TestIntrusiveObject* current) {
       ids.push_back(current->id());
 
@@ -149,9 +169,12 @@ TEST(AtomicIntrusiveLinkedList, Stress) {
 
 class TestObject {
  public:
-  TestObject(size_t id__, std::shared_ptr<void> ptr) : id_(id__), ptr_(ptr) {}
+  TestObject(size_t id__, const std::shared_ptr<void>& ptr)
+      : id_(id__), ptr_(ptr) {}
 
-  size_t id() { return id_; }
+  size_t id() {
+    return id_;
+  }
 
  private:
   size_t id_;