proxygen
AtomicLinkedListTest.cpp File Reference
#include <algorithm>
#include <thread>
#include <folly/AtomicLinkedList.h>
#include <folly/portability/GTest.h>

Go to the source code of this file.

Classes

class  TestIntrusiveObject
 
class  TestObject
 

Functions

 TEST (AtomicIntrusiveLinkedList, Basic)
 
 TEST (AtomicIntrusiveLinkedList, ReverseSweep)
 
 TEST (AtomicIntrusiveLinkedList, Move)
 
 TEST (AtomicIntrusiveLinkedList, Stress)
 
 TEST (AtomicLinkedList, Basic)
 

Function Documentation

TEST ( AtomicIntrusiveLinkedList  ,
Basic   
)

Definition at line 40 of file AtomicLinkedListTest.cpp.

References a, b, c, folly::AtomicIntrusiveLinkedList< T, HookMember >::empty(), EXPECT_EQ, EXPECT_FALSE, EXPECT_TRUE, TestIntrusiveObject::id(), folly::AtomicIntrusiveLinkedList< T, HookMember >::insertHead(), bm::list, folly::gen::move, and folly::AtomicIntrusiveLinkedList< T, HookMember >::sweep().

40  {
41  TestIntrusiveObject a(1), b(2), c(3);
42 
44 
45  EXPECT_TRUE(list.empty());
46 
47  {
48  EXPECT_TRUE(list.insertHead(&a));
49  EXPECT_FALSE(list.insertHead(&b));
50 
51  EXPECT_FALSE(list.empty());
52 
53  size_t id = 0;
54  list.sweep([&](TestIntrusiveObject* obj) mutable {
55  ++id;
56  EXPECT_EQ(id, obj->id());
57  });
58 
59  EXPECT_TRUE(list.empty());
60  }
61 
62  // Try re-inserting the same item (b) and a new item (c)
63  {
64  EXPECT_TRUE(list.insertHead(&b));
65  EXPECT_FALSE(list.insertHead(&c));
66 
67  EXPECT_FALSE(list.empty());
68 
69  size_t id = 1;
70  list.sweep([&](TestIntrusiveObject* obj) mutable {
71  ++id;
72  EXPECT_EQ(id, obj->id());
73  });
74 
75  EXPECT_TRUE(list.empty());
76  }
77 
78  TestIntrusiveObject::List movedList = std::move(list);
79 }
char b
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
Encoder::MutableCompressedList list
char a
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
char c
TEST ( AtomicIntrusiveLinkedList  ,
ReverseSweep   
)

Definition at line 81 of file AtomicLinkedListTest.cpp.

References a, b, c, folly::AtomicIntrusiveLinkedList< T, HookMember >::empty(), EXPECT_EQ, EXPECT_FALSE, EXPECT_TRUE, TestIntrusiveObject::id(), folly::AtomicIntrusiveLinkedList< T, HookMember >::insertHead(), bm::list, and folly::AtomicIntrusiveLinkedList< T, HookMember >::reverseSweep().

81  {
82  TestIntrusiveObject a(1), b(2), c(3);
84  list.insertHead(&a);
85  list.insertHead(&b);
86  list.insertHead(&c);
87  size_t next_expected_id = 3;
88  list.reverseSweep([&](TestIntrusiveObject* obj) {
89  auto const expected = next_expected_id--;
90  EXPECT_EQ(expected, obj->id());
91  });
92  EXPECT_TRUE(list.empty());
93  // Test that we can still insert
94  list.insertHead(&a);
95  EXPECT_FALSE(list.empty());
96  list.reverseSweep([](TestIntrusiveObject*) {});
97 }
char b
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
Encoder::MutableCompressedList list
char a
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
char c
TEST ( AtomicIntrusiveLinkedList  ,
Move   
)

Definition at line 99 of file AtomicLinkedListTest.cpp.

References a, b, folly::AtomicIntrusiveLinkedList< T, HookMember >::empty(), EXPECT_EQ, EXPECT_FALSE, EXPECT_TRUE, TestIntrusiveObject::id(), folly::AtomicIntrusiveLinkedList< T, HookMember >::insertHead(), and folly::gen::move.

99  {
100  TestIntrusiveObject a(1), b(2);
101 
103 
104  EXPECT_TRUE(list1.insertHead(&a));
105  EXPECT_FALSE(list1.insertHead(&b));
106 
107  EXPECT_FALSE(list1.empty());
108 
109  TestIntrusiveObject::List list2(std::move(list1));
110 
111  EXPECT_TRUE(list1.empty());
112  EXPECT_FALSE(list2.empty());
113 
115 
116  EXPECT_TRUE(list3.empty());
117 
118  list3 = std::move(list2);
119 
120  EXPECT_TRUE(list2.empty());
121  EXPECT_FALSE(list3.empty());
122 
123  size_t id = 0;
124  list3.sweep([&](TestIntrusiveObject* obj) mutable {
125  ++id;
126  EXPECT_EQ(id, obj->id());
127  });
128 }
char b
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
char a
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
TEST ( AtomicIntrusiveLinkedList  ,
Stress   
)

Definition at line 130 of file AtomicLinkedListTest.cpp.

References current, EXPECT_EQ, i, TestIntrusiveObject::id(), folly::AtomicIntrusiveLinkedList< T, HookMember >::insertHead(), kNumThreads, bm::list, folly::AtomicIntrusiveLinkedList< T, HookMember >::sweep(), and threads.

130  {
131  static constexpr size_t kNumThreads = 32;
132  static constexpr size_t kNumElements = 100000;
133 
134  std::vector<TestIntrusiveObject> elements;
135  for (size_t i = 0; i < kNumThreads * kNumElements; ++i) {
136  elements.emplace_back(i);
137  }
138 
140 
141  std::vector<std::thread> threads;
142  for (size_t threadId = 0; threadId < kNumThreads; ++threadId) {
143  threads.emplace_back([threadId, &list, &elements] {
144  for (size_t id = 0; id < kNumElements; ++id) {
145  list.insertHead(&elements[threadId + kNumThreads * id]);
146  }
147  });
148  }
149 
150  std::vector<size_t> ids;
151  TestIntrusiveObject* prev{nullptr};
152 
153  while (ids.size() < kNumThreads * kNumElements) {
154  list.sweep([&](TestIntrusiveObject* current) {
155  ids.push_back(current->id());
156 
157  if (prev && prev->id() % kNumThreads == current->id() % kNumThreads) {
158  EXPECT_EQ(prev->id() + kNumThreads, current->id());
159  }
160 
161  prev = current;
162  });
163  }
164 
165  std::sort(ids.begin(), ids.end());
166 
167  for (size_t i = 0; i < kNumThreads * kNumElements; ++i) {
168  EXPECT_EQ(i, ids[i]);
169  }
170 
171  for (auto& thread : threads) {
172  thread.join();
173  }
174 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
static size_t const kNumThreads
std::vector< std::thread::id > threads
int current
Encoder::MutableCompressedList list
TEST ( AtomicLinkedList  ,
Basic   
)

Definition at line 190 of file AtomicLinkedListTest.cpp.

References counter, EXPECT_EQ, EXPECT_TRUE, TestIntrusiveObject::id(), bm::list, and ptr.

190  {
191  constexpr size_t kNumElements = 10;
192 
194  List list;
195 
196  std::shared_ptr<void> ptr = std::make_shared<int>(42);
197 
198  for (size_t id = 0; id < kNumElements; ++id) {
199  list.insertHead({id, ptr});
200  }
201 
202  size_t counter = 0;
203 
204  list.sweep([&](TestObject object) {
205  EXPECT_EQ(counter, object.id());
206 
207  EXPECT_EQ(1 + kNumElements - counter, ptr.use_count());
208 
209  ++counter;
210  });
211 
212  EXPECT_TRUE(ptr.unique());
213 }
void * ptr
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
Encoder::MutableCompressedList list
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
std::atomic< int > counter