proxygen
LifoSemTests.cpp File Reference

Go to the source code of this file.

Classes

class  LifoSemTest
 

Typedefs

typedef LifoSemImpl< DeterministicAtomicDLifoSem
 
typedef DeterministicSchedule DSched
 

Functions

 TEST (LifoSem, basic)
 
 TEST (LifoSem, multi)
 
 TEST_F (LifoSemTest, pingpong)
 
 TEST_F (LifoSemTest, mutex)
 
 TEST_F (LifoSemTest, no_blocking)
 
 TEST_F (LifoSemTest, one_way)
 
 TEST_F (LifoSemTest, shutdown_wait_order)
 
 TEST_F (LifoSemTest, shutdown_multi)
 
 TEST (LifoSem, multi_try_wait_simple)
 
 TEST_F (LifoSemTest, multi_try_wait)
 
 TEST_F (LifoSemTest, timeout)
 
 BENCHMARK (lifo_sem_pingpong, iters)
 
 BENCHMARK (lifo_sem_oneway, iters)
 
 BENCHMARK (single_thread_lifo_post, iters)
 
 BENCHMARK (single_thread_lifo_wait, iters)
 
 BENCHMARK (single_thread_lifo_postwait, iters)
 
 BENCHMARK (single_thread_lifo_trywait, iters)
 
 BENCHMARK (single_thread_posix_postwait, iters)
 
 BENCHMARK (single_thread_posix_trywait, iters)
 
static void contendedUse (uint32_t n, int posters, int waiters)
 
 BENCHMARK_DRAW_LINE ()
 
int main (int argc, char **argv)
 

Typedef Documentation

Definition at line 32 of file LifoSemTests.cpp.

Definition at line 33 of file LifoSemTests.cpp.

Function Documentation

BENCHMARK ( lifo_sem_pingpong  ,
iters   
)

Definition at line 313 of file LifoSemTests.cpp.

References a, b, i, folly::detail::LifoSemBase< Handoff, Atom >::post(), and folly::detail::LifoSemBase< Handoff, Atom >::wait().

313  {
314  LifoSem a;
315  LifoSem b;
316  auto thr = std::thread([&] {
317  for (size_t i = 0; i < iters; ++i) {
318  a.wait();
319  b.post();
320  }
321  });
322  for (size_t i = 0; i < iters; ++i) {
323  a.post();
324  b.wait();
325  }
326  thr.join();
327 }
char b
bool post()
Silently saturates if value is already 2^32-1.
Definition: LifoSem.h:361
char a
BENCHMARK ( lifo_sem_oneway  ,
iters   
)

Definition at line 329 of file LifoSemTests.cpp.

References a, i, folly::detail::LifoSemBase< Handoff, Atom >::post(), and folly::detail::LifoSemBase< Handoff, Atom >::wait().

329  {
330  LifoSem a;
331  auto thr = std::thread([&] {
332  for (size_t i = 0; i < iters; ++i) {
333  a.wait();
334  }
335  });
336  for (size_t i = 0; i < iters; ++i) {
337  a.post();
338  }
339  thr.join();
340 }
bool post()
Silently saturates if value is already 2^32-1.
Definition: LifoSem.h:361
char a
BENCHMARK ( single_thread_lifo_post  ,
iters   
)

Definition at line 342 of file LifoSemTests.cpp.

References folly::asm_volatile_memory(), and folly::detail::LifoSemBase< Handoff, Atom >::post().

342  {
343  LifoSem sem;
344  for (size_t n = 0; n < iters; ++n) {
345  sem.post();
347  }
348 }
bool post()
Silently saturates if value is already 2^32-1.
Definition: LifoSem.h:361
void asm_volatile_memory()
Definition: Asm.h:29
BENCHMARK ( single_thread_lifo_wait  ,
iters   
)

Definition at line 350 of file LifoSemTests.cpp.

References folly::asm_volatile_memory(), and folly::detail::LifoSemBase< Handoff, Atom >::wait().

350  {
351  LifoSem sem(iters);
352  for (size_t n = 0; n < iters; ++n) {
353  sem.wait();
355  }
356 }
void asm_volatile_memory()
Definition: Asm.h:29
BENCHMARK ( single_thread_lifo_postwait  ,
iters   
)

Definition at line 358 of file LifoSemTests.cpp.

References folly::asm_volatile_memory(), folly::detail::LifoSemBase< Handoff, Atom >::post(), and folly::detail::LifoSemBase< Handoff, Atom >::wait().

358  {
359  LifoSem sem;
360  for (size_t n = 0; n < iters; ++n) {
361  sem.post();
363  sem.wait();
365  }
366 }
bool post()
Silently saturates if value is already 2^32-1.
Definition: LifoSem.h:361
void asm_volatile_memory()
Definition: Asm.h:29
BENCHMARK ( single_thread_lifo_trywait  ,
iters   
)

Definition at line 368 of file LifoSemTests.cpp.

References folly::asm_volatile_memory(), EXPECT_FALSE, and folly::detail::LifoSemBase< Handoff, Atom >::tryWait().

368  {
369  LifoSem sem;
370  for (size_t n = 0; n < iters; ++n) {
371  EXPECT_FALSE(sem.tryWait());
373  }
374 }
bool tryWait()
Returns true iff value was decremented.
Definition: LifoSem.h:430
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
void asm_volatile_memory()
Definition: Asm.h:29
BENCHMARK ( single_thread_posix_postwait  ,
iters   
)

Definition at line 376 of file LifoSemTests.cpp.

References EXPECT_EQ.

376  {
377  sem_t sem;
378  EXPECT_EQ(sem_init(&sem, 0, 0), 0);
379  for (size_t n = 0; n < iters; ++n) {
380  EXPECT_EQ(sem_post(&sem), 0);
381  EXPECT_EQ(sem_wait(&sem), 0);
382  }
383  EXPECT_EQ(sem_destroy(&sem), 0);
384 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
BENCHMARK ( single_thread_posix_trywait  ,
iters   
)

Definition at line 386 of file LifoSemTests.cpp.

References EXPECT_EQ.

386  {
387  sem_t sem;
388  EXPECT_EQ(sem_init(&sem, 0, 0), 0);
389  for (size_t n = 0; n < iters; ++n) {
390  EXPECT_EQ(sem_trywait(&sem), -1);
391  }
392  EXPECT_EQ(sem_destroy(&sem), 0);
393 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
BENCHMARK_DRAW_LINE ( )
static void contendedUse ( uint32_t  n,
int  posters,
int  waiters 
)
static

Definition at line 395 of file LifoSemTests.cpp.

References folly::BENCHMARK_DRAW_LINE(), BENCHMARK_NAMED_PARAM, BENCHMARK_SUSPEND, i, folly::detail::LifoSemBase< BatonType, Atom >::post(), folly::pushmi::detail::t, threads, uint32_t, folly::detail::LifoSemBase< BatonType, Atom >::wait(), and folly::fibers::yield().

395  {
397 
398  std::vector<std::thread> threads;
399  std::atomic<bool> go(false);
400 
402  for (int t = 0; t < waiters; ++t) {
403  threads.emplace_back([=, &sem] {
404  for (uint32_t i = t; i < n; i += waiters) {
405  sem.wait();
406  }
407  });
408  }
409  for (int t = 0; t < posters; ++t) {
410  threads.emplace_back([=, &sem, &go] {
411  while (!go.load()) {
413  }
414  for (uint32_t i = t; i < n; i += posters) {
415  sem.post();
416  }
417  });
418  }
419  }
420 
421  go.store(true);
422  for (auto& thr : threads) {
423  thr.join();
424  }
425 }
#define BENCHMARK_SUSPEND
Definition: Benchmark.h:576
bool post()
Silently saturates if value is already 2^32-1.
Definition: LifoSem.h:361
std::vector< std::thread::id > threads
int main ( int  argc,
char **  argv 
)

Definition at line 465 of file LifoSemTests.cpp.

References argv, testing::InitGoogleTest(), RUN_ALL_TESTS(), and folly::runBenchmarksOnFlag().

465  {
467  gflags::ParseCommandLineFlags(&argc, &argv, true);
468  int rv = RUN_ALL_TESTS();
470  return rv;
471 }
int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_
Definition: gtest.h:2232
char ** argv
bool runBenchmarksOnFlag()
Definition: Benchmark.h:48
GTEST_API_ void InitGoogleTest(int *argc, char **argv)
Definition: gtest.cc:5370
TEST ( LifoSem  ,
basic   
)

Definition at line 44 of file LifoSemTests.cpp.

References EXPECT_FALSE, EXPECT_TRUE, folly::detail::LifoSemBase< Handoff, Atom >::post(), folly::detail::LifoSemBase< Handoff, Atom >::tryWait(), and folly::detail::LifoSemBase< Handoff, Atom >::wait().

44  {
45  LifoSem sem;
46  EXPECT_FALSE(sem.tryWait());
47  sem.post();
48  EXPECT_TRUE(sem.tryWait());
49  sem.post();
50  sem.wait();
51 }
bool post()
Silently saturates if value is already 2^32-1.
Definition: LifoSem.h:361
bool tryWait()
Returns true iff value was decremented.
Definition: LifoSem.h:430
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
TEST ( LifoSem  ,
multi   
)

Definition at line 53 of file LifoSemTests.cpp.

References b, i, folly::INFO, folly::detail::LifoSemBase< Handoff, Atom >::post(), threads, folly::detail::LifoSemBase< Handoff, Atom >::tryWait(), and folly::detail::LifoSemBase< Handoff, Atom >::wait().

53  {
54  LifoSem sem;
55 
56  const int opsPerThread = 10000;
57  std::thread threads[10];
58  std::atomic<int> blocks(0);
59 
60  for (auto& thr : threads) {
61  thr = std::thread([&] {
62  int b = 0;
63  for (int i = 0; i < opsPerThread; ++i) {
64  if (!sem.tryWait()) {
65  sem.wait();
66  ++b;
67  }
68  sem.post();
69  }
70  blocks += b;
71  });
72  }
73 
74  // start the flood
75  sem.post();
76 
77  for (auto& thr : threads) {
78  thr.join();
79  }
80 
81  LOG(INFO) << opsPerThread * sizeof(threads) / sizeof(threads[0])
82  << " post/wait pairs, " << blocks << " blocked";
83 }
char b
bool post()
Silently saturates if value is already 2^32-1.
Definition: LifoSem.h:361
std::vector< std::thread::id > threads
bool tryWait()
Returns true iff value was decremented.
Definition: LifoSem.h:430
TEST ( LifoSem  ,
multi_try_wait_simple   
)

Definition at line 222 of file LifoSemTests.cpp.

References ASSERT_EQ, folly::detail::LifoSemBase< Handoff, Atom >::post(), and folly::detail::LifoSemBase< Handoff, Atom >::tryWait().

222  {
223  LifoSem sem;
224  sem.post(5);
225  auto n = sem.tryWait(10); // this used to trigger an assert
226  ASSERT_EQ(5, n);
227 }
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
bool post()
Silently saturates if value is already 2^32-1.
Definition: LifoSem.h:361
bool tryWait()
Returns true iff value was decremented.
Definition: LifoSem.h:430
TEST_F ( LifoSemTest  ,
pingpong   
)

Definition at line 85 of file LifoSemTests.cpp.

References a, b, EXPECT_EQ, i, folly::test::DeterministicSchedule::join(), folly::detail::LifoSemBase< Handoff, Atom >::post(), folly::test::DeterministicSchedule::thread(), folly::test::DeterministicSchedule::uniform(), folly::detail::LifoSemBase< Handoff, Atom >::valueGuess(), and folly::detail::LifoSemBase< Handoff, Atom >::wait().

85  {
86  DSched sched(DSched::uniform(0));
87 
88  const int iters = 100;
89 
90  for (int pass = 0; pass < 10; ++pass) {
91  DLifoSem a;
92  DLifoSem b;
93 
94  auto thr = DSched::thread([&] {
95  for (int i = 0; i < iters; ++i) {
96  a.wait();
97  // main thread can't be running here
98  EXPECT_EQ(a.valueGuess(), 0);
99  EXPECT_EQ(b.valueGuess(), 0);
100  b.post();
101  }
102  });
103  for (int i = 0; i < iters; ++i) {
104  a.post();
105  b.wait();
106  // child thread can't be running here
107  EXPECT_EQ(a.valueGuess(), 0);
108  EXPECT_EQ(b.valueGuess(), 0);
109  }
110  DSched::join(thr);
111  }
112 }
char b
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
bool post()
Silently saturates if value is already 2^32-1.
Definition: LifoSem.h:361
static std::thread thread(Func &&func, Args &&...args)
static std::function< size_t(size_t)> uniform(uint64_t seed)
uint32_t valueGuess() const
Definition: LifoSem.h:528
char a
static void join(std::thread &child)
TEST_F ( LifoSemTest  ,
mutex   
)

Definition at line 114 of file LifoSemTests.cpp.

References a, i, folly::test::DeterministicSchedule::join(), folly::detail::LifoSemBase< Handoff, Atom >::post(), folly::test::DeterministicSchedule::thread(), folly::test::DeterministicSchedule::uniform(), and folly::detail::LifoSemBase< Handoff, Atom >::wait().

114  {
115  DSched sched(DSched::uniform(0));
116 
117  const int iters = 100;
118 
119  for (int pass = 0; pass < 10; ++pass) {
120  DLifoSem a;
121 
122  auto thr = DSched::thread([&] {
123  for (int i = 0; i < iters; ++i) {
124  a.wait();
125  a.post();
126  }
127  });
128  for (int i = 0; i < iters; ++i) {
129  a.post();
130  a.wait();
131  }
132  a.post();
133  DSched::join(thr);
134  a.wait();
135  }
136 }
bool post()
Silently saturates if value is already 2^32-1.
Definition: LifoSem.h:361
static std::thread thread(Func &&func, Args &&...args)
static std::function< size_t(size_t)> uniform(uint64_t seed)
char a
static void join(std::thread &child)
TEST_F ( LifoSemTest  ,
no_blocking   
)

Definition at line 138 of file LifoSemTests.cpp.

References a, i, folly::INFO, folly::test::DeterministicSchedule::join(), folly::detail::LifoSemBase< Handoff, Atom >::post(), folly::randomNumberSeed(), seed, folly::test::DeterministicSchedule::thread(), threads, folly::test::DeterministicSchedule::uniform(), and folly::detail::LifoSemBase< Handoff, Atom >::wait().

138  {
139  long seed = folly::randomNumberSeed() % 10000;
140  LOG(INFO) << "seed=" << seed;
141  DSched sched(DSched::uniform(seed));
142 
143  const int iters = 100;
144  const int numThreads = 2;
145  const int width = 10;
146 
147  for (int pass = 0; pass < 10; ++pass) {
148  DLifoSem a;
149 
150  std::vector<std::thread> threads;
151  while (threads.size() < numThreads) {
152  threads.emplace_back(DSched::thread([&] {
153  for (int i = 0; i < iters; ++i) {
154  a.post(width);
155  for (int w = 0; w < width; ++w) {
156  a.wait();
157  }
158  }
159  }));
160  }
161  for (auto& thr : threads) {
162  DSched::join(thr);
163  }
164  }
165 }
static const int seed
bool post()
Silently saturates if value is already 2^32-1.
Definition: LifoSem.h:361
static std::thread thread(Func &&func, Args &&...args)
std::vector< std::thread::id > threads
static std::function< size_t(size_t)> uniform(uint64_t seed)
char a
static void join(std::thread &child)
uint32_t randomNumberSeed()
Definition: Random.h:367
TEST_F ( LifoSemTest  ,
one_way   
)

Definition at line 167 of file LifoSemTests.cpp.

References a, i, folly::INFO, folly::test::DeterministicSchedule::join(), folly::detail::LifoSemBase< Handoff, Atom >::post(), folly::randomNumberSeed(), seed, folly::test::DeterministicSchedule::thread(), folly::test::DeterministicSchedule::uniformSubset(), and folly::detail::LifoSemBase< Handoff, Atom >::wait().

167  {
168  long seed = folly::randomNumberSeed() % 10000;
169  LOG(INFO) << "seed=" << seed;
170  DSched sched(DSched::uniformSubset(seed, 1, 6));
171 
172  const int iters = 1000;
173 
174  for (int pass = 0; pass < 10; ++pass) {
175  DLifoSem a;
176 
177  auto thr = DSched::thread([&] {
178  for (int i = 0; i < iters; ++i) {
179  a.wait();
180  }
181  });
182  for (int i = 0; i < iters; ++i) {
183  a.post();
184  }
185  DSched::join(thr);
186  }
187 }
static const int seed
bool post()
Silently saturates if value is already 2^32-1.
Definition: LifoSem.h:361
static std::thread thread(Func &&func, Args &&...args)
char a
static std::function< size_t(size_t)> uniformSubset(uint64_t seed, size_t n=2, size_t m=64)
static void join(std::thread &child)
uint32_t randomNumberSeed()
Definition: Random.h:367
TEST_F ( LifoSemTest  ,
shutdown_wait_order   
)

Definition at line 189 of file LifoSemTests.cpp.

References a, EXPECT_THROW, EXPECT_TRUE, folly::detail::LifoSemBase< Handoff, Atom >::isShutdown(), folly::detail::LifoSemBase< Handoff, Atom >::post(), folly::detail::LifoSemBase< Handoff, Atom >::shutdown(), and folly::detail::LifoSemBase< Handoff, Atom >::wait().

189  {
190  DLifoSem a;
191  a.shutdown();
192  a.post();
193  a.wait();
195  EXPECT_TRUE(a.isShutdown());
196 }
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
bool post()
Silently saturates if value is already 2^32-1.
Definition: LifoSem.h:361
bool isShutdown() const
Returns true iff shutdown() has been called.
Definition: LifoSem.h:389
char a
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
The exception thrown when wait()ing on an isShutdown() LifoSem.
Definition: LifoSem.h:97
TEST_F ( LifoSemTest  ,
shutdown_multi   
)

Definition at line 198 of file LifoSemTests.cpp.

References a, ADD_FAILURE, EXPECT_TRUE, folly::detail::LifoSemBase< Handoff, Atom >::isShutdown(), folly::test::DeterministicSchedule::join(), folly::detail::LifoSemBase< Handoff, Atom >::shutdown(), folly::test::DeterministicSchedule::thread(), threads, folly::test::DeterministicSchedule::uniform(), and folly::detail::LifoSemBase< Handoff, Atom >::wait().

198  {
199  DSched sched(DSched::uniform(0));
200 
201  for (int pass = 0; pass < 10; ++pass) {
202  DLifoSem a;
203  std::vector<std::thread> threads;
204  while (threads.size() < 20) {
205  threads.push_back(DSched::thread([&] {
206  try {
207  a.wait();
208  ADD_FAILURE();
209  } catch (ShutdownSemError&) {
210  // expected
211  EXPECT_TRUE(a.isShutdown());
212  }
213  }));
214  }
215  a.shutdown();
216  for (auto& thr : threads) {
217  DSched::join(thr);
218  }
219  }
220 }
static std::thread thread(Func &&func, Args &&...args)
std::vector< std::thread::id > threads
static std::function< size_t(size_t)> uniform(uint64_t seed)
bool isShutdown() const
Returns true iff shutdown() has been called.
Definition: LifoSem.h:389
char a
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
The exception thrown when wait()ing on an isShutdown() LifoSem.
Definition: LifoSem.h:97
static void join(std::thread &child)
#define ADD_FAILURE()
Definition: gtest.h:1808
TEST_F ( LifoSemTest  ,
multi_try_wait   
)

Definition at line 229 of file LifoSemTests.cpp.

References ASSERT_EQ, i, folly::INFO, folly::test::DeterministicSchedule::join(), folly::test::DeterministicAtomicImpl< T, Schedule, Atom >::load(), folly::detail::LifoSemBase< Handoff, Atom >::post(), folly::randomNumberSeed(), seed, stop(), folly::test::DeterministicAtomicImpl< T, Schedule, Atom >::store(), folly::test::DeterministicSchedule::thread(), folly::detail::LifoSemBase< Handoff, Atom >::tryWait(), and folly::test::DeterministicSchedule::uniform().

229  {
230  long seed = folly::randomNumberSeed() % 10000;
231  LOG(INFO) << "seed=" << seed;
232  DSched sched(DSched::uniform(seed));
233  DLifoSem sem;
234 
235  const int NPOSTS = 1000;
236 
237  auto producer = [&] {
238  for (int i = 0; i < NPOSTS; ++i) {
239  sem.post();
240  }
241  };
242 
243  DeterministicAtomic<bool> consumer_stop(false);
244  int consumed = 0;
245 
246  auto consumer = [&] {
247  bool stop;
248  do {
249  stop = consumer_stop.load();
250  int n;
251  do {
252  n = sem.tryWait(10);
253  consumed += n;
254  } while (n > 0);
255  } while (!stop);
256  };
257 
258  std::thread producer_thread(DSched::thread(producer));
259  std::thread consumer_thread(DSched::thread(consumer));
260  DSched::join(producer_thread);
261  consumer_stop.store(true);
262  DSched::join(consumer_thread);
263 
264  ASSERT_EQ(NPOSTS, consumed);
265 }
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
static const int seed
bool post()
Silently saturates if value is already 2^32-1.
Definition: LifoSem.h:361
static std::thread thread(Func &&func, Args &&...args)
static std::function< size_t(size_t)> uniform(uint64_t seed)
static void stop()
bool tryWait()
Returns true iff value was decremented.
Definition: LifoSem.h:430
static void join(std::thread &child)
uint32_t randomNumberSeed()
Definition: Random.h:367
TEST_F ( LifoSemTest  ,
timeout   
)

Definition at line 267 of file LifoSemTests.cpp.

References a, EXPECT_GT, EXPECT_TRUE, i, folly::INFO, folly::detail::LifoSemBase< Handoff, Atom >::isShutdown(), folly::test::DeterministicSchedule::join(), folly::detail::LifoSemBase< Handoff, Atom >::post(), folly::randomNumberSeed(), seed, folly::detail::LifoSemBase< Handoff, Atom >::shutdown(), folly::test::DeterministicSchedule::thread(), threads, folly::detail::LifoSemBase< Handoff, Atom >::try_wait_for(), and folly::test::DeterministicSchedule::uniform().

267  {
268  long seed = folly::randomNumberSeed() % 10000;
269  LOG(INFO) << "seed=" << seed;
270  DSched sched(DSched::uniform(seed));
271  DeterministicAtomic<uint32_t> handoffs{0};
272 
273  for (int pass = 0; pass < 10; ++pass) {
274  DLifoSem a;
275  std::vector<std::thread> threads;
276  while (threads.size() < 20) {
277  threads.push_back(DSched::thread([&] {
278  for (int i = 0; i < 10; i++) {
279  try {
280  if (a.try_wait_for(std::chrono::milliseconds(1))) {
281  handoffs--;
282  }
283  } catch (ShutdownSemError&) {
284  // expected
285  EXPECT_TRUE(a.isShutdown());
286  }
287  }
288  }));
289  }
290  std::vector<std::thread> threads2;
291  while (threads2.size() < 20) {
292  threads2.push_back(DSched::thread([&] {
293  for (int i = 0; i < 10; i++) {
294  a.post();
295  handoffs++;
296  }
297  }));
298  }
299  if (pass > 5) {
300  a.shutdown();
301  }
302  for (auto& thr : threads) {
303  DSched::join(thr);
304  }
305  for (auto& thr : threads2) {
306  DSched::join(thr);
307  }
308  // At least one timeout must occur.
309  EXPECT_GT(handoffs.load(), 0);
310  }
311 }
static const int seed
bool post()
Silently saturates if value is already 2^32-1.
Definition: LifoSem.h:361
static std::thread thread(Func &&func, Args &&...args)
std::vector< std::thread::id > threads
static std::function< size_t(size_t)> uniform(uint64_t seed)
bool isShutdown() const
Returns true iff shutdown() has been called.
Definition: LifoSem.h:389
char a
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
bool try_wait_for(const std::chrono::duration< Rep, Period > &timeout)
Definition: LifoSem.h:472
The exception thrown when wait()ing on an isShutdown() LifoSem.
Definition: LifoSem.h:97
static void join(std::thread &child)
uint32_t randomNumberSeed()
Definition: Random.h:367
#define EXPECT_GT(val1, val2)
Definition: gtest.h:1934