proxygen
RefCountTest.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2015-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <thread>
17 
21 
22 namespace folly {
23 
24 template <typename RefCount>
25 void basicTest() {
26  constexpr size_t numIters = 100000;
27  constexpr size_t numThreads = 10;
28 
29  size_t got0 = 0;
30 
31  RefCount count;
32 
34 
35  std::vector<std::thread> ts;
36  folly::Baton<> threadBatons[numThreads];
37  for (size_t t = 0; t < numThreads; ++t) {
38  ts.emplace_back([&count, &b, &got0, t, &threadBatons] {
39  for (size_t i = 0; i < numIters; ++i) {
40  auto ret = ++count;
41 
42  EXPECT_TRUE(ret > 1);
43  if (i == 0) {
44  threadBatons[t].post();
45  }
46  }
47 
48  if (t == 0) {
49  b.post();
50  }
51 
52  for (size_t i = 0; i < numIters; ++i) {
53  auto ret = --count;
54 
55  if (ret == 0) {
56  ++got0;
57  EXPECT_EQ(numIters - 1, i);
58  }
59  }
60  });
61  }
62 
63  for (size_t t = 0; t < numThreads; ++t) {
64  threadBatons[t].wait();
65  }
66 
67  b.wait();
68 
69  count.useGlobal();
70  if (--count == 0) {
71  ++got0;
72  }
73 
74  for (auto& t : ts) {
75  t.join();
76  }
77 
78  EXPECT_EQ(1, got0);
79 
80  EXPECT_EQ(0, ++count);
81  EXPECT_EQ(0, ++count);
82 }
83 
84 template <typename RefCount>
85 void stressTest(size_t itersCount) {
86  for (size_t i = 0; i < itersCount; ++i) {
87  RefCount count;
89  int a{1};
90 
91  std::thread t1([&]() {
92  if (++count) {
93  {
94  std::lock_guard<std::mutex> lg(mutex);
95  EXPECT_EQ(1, a);
96  }
97  --count;
98  }
99  });
100 
101  std::thread t2([&]() {
102  count.useGlobal();
103  if (--count == 0) {
104  std::lock_guard<std::mutex> lg(mutex);
105  a = 0;
106  }
107  });
108 
109  t1.join();
110  t2.join();
111 
112  EXPECT_EQ(0, ++count);
113  }
114 }
115 
116 TEST(TLRefCount, Basic) {
117  basicTest<TLRefCount>();
118 }
119 
120 TEST(TLRefCount, Stress) {
121  // This is absurdly slow, so we can't
122  // do it that many times.
123  stressTest<TLRefCount>(500);
124 }
125 } // namespace folly
char b
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
FOLLY_ALWAYS_INLINE void wait(const WaitOptions &opt=wait_options()) noexcept
Definition: Baton.h:170
char a
void post() noexcept
Definition: Baton.h:123
void stressTest(size_t itersCount)
int * count
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
std::mutex mutex
void basicTest()
TEST(SequencedExecutor, CPUThreadPoolExecutor)