proxygen
UnboundedQueueTest.cpp File Reference
#include <folly/concurrency/UnboundedQueue.h>
#include <folly/MPMCQueue.h>
#include <folly/ProducerConsumerQueue.h>
#include <folly/portability/GTest.h>
#include <glog/logging.h>
#include <atomic>
#include <thread>

Go to the source code of this file.

Classes

class  MPMC< T >
 
class  PCQ< T >
 
struct  IntArray< M >
 

Typedefs

template<typename T , bool MayBlock>
using USPSC = folly::USPSCQueue< T, MayBlock >
 
template<typename T , bool MayBlock>
using UMPSC = folly::UMPSCQueue< T, MayBlock >
 
template<typename T , bool MayBlock>
using USPMC = folly::USPMCQueue< T, MayBlock >
 
template<typename T , bool MayBlock>
using UMPMC = folly::UMPMCQueue< T, MayBlock >
 
template<typename T , bool ignore>
using FMPMC = MPMC< T >
 
template<typename T , bool ignore>
using FPCQ = PCQ< T >
 

Functions

 DEFINE_bool (bench, false,"run benchmark")
 
 DEFINE_int32 (reps, 10,"number of reps")
 
 DEFINE_int32 (ops, 1000000,"number of operations per rep")
 
 DEFINE_int64 (capacity, 256 *1024,"capacity")
 
template<template< typename, bool > class Q, bool MayBlock>
void basic_test ()
 
 TEST (UnboundedQueue, basic)
 
template<template< typename, bool > class Q, bool MayBlock>
void timeout_test ()
 
 TEST (UnboundedQueue, timeout)
 
template<template< typename, bool > class Q, bool MayBlock>
void peek_test ()
 
 TEST (UnboundedQueue, peek)
 
 TEST (UnboundedQueue, cleanup_on_destruction)
 
template<typename ProdFunc , typename ConsFunc , typename EndFunc >
uint64_t run_once (int nprod, int ncons, const ProdFunc &prodFn, const ConsFunc &consFn, const EndFunc &endFn)
 
template<bool SingleProducer, bool SingleConsumer, bool MayBlock>
void enq_deq_test (const int nprod, const int ncons)
 
 TEST (UnboundedQueue, enq_deq)
 
template<typename RepFunc >
uint64_t runBench (const std::string &name, int ops, const RepFunc &repFn)
 
template<template< typename, bool > class Q, typename T , int Op>
uint64_t bench (const int nprod, const int ncons, const std::string &name)
 
void dottedLine ()
 
template<typename T >
void type_benches (const int np, const int nc, const std::string &name)
 
void benches (const int np, const int nc)
 
 TEST (UnboundedQueue, bench)
 

Typedef Documentation

template<typename T , bool ignore>
using FMPMC = MPMC<T>

Definition at line 425 of file UnboundedQueueTest.cpp.

template<typename T , bool ignore>
using FPCQ = PCQ<T>

Definition at line 456 of file UnboundedQueueTest.cpp.

template<typename T , bool MayBlock>
using UMPMC = folly::UMPMCQueue<T, MayBlock>

Definition at line 42 of file UnboundedQueueTest.cpp.

template<typename T , bool MayBlock>
using UMPSC = folly::UMPSCQueue<T, MayBlock>

Definition at line 36 of file UnboundedQueueTest.cpp.

template<typename T , bool MayBlock>
using USPMC = folly::USPMCQueue<T, MayBlock>

Definition at line 39 of file UnboundedQueueTest.cpp.

template<typename T , bool MayBlock>
using USPSC = folly::USPSCQueue<T, MayBlock>

Definition at line 33 of file UnboundedQueueTest.cpp.

Function Documentation

template<template< typename, bool > class Q, bool MayBlock>
void basic_test ( )

Definition at line 45 of file UnboundedQueueTest.cpp.

References ASSERT_EQ, ASSERT_FALSE, and ASSERT_TRUE.

45  {
46  Q<int, MayBlock> q;
47  ASSERT_TRUE(q.empty());
48  ASSERT_EQ(q.size(), 0);
49  int v = -1;
50  ASSERT_FALSE(q.try_dequeue(v));
51 
52  q.enqueue(1);
53  ASSERT_FALSE(q.empty());
54  ASSERT_EQ(q.size(), 1);
55 
56  q.enqueue(2);
57  ASSERT_EQ(q.size(), 2);
58  ASSERT_FALSE(q.empty());
59 
60  ASSERT_TRUE(q.try_dequeue(v));
61  ASSERT_EQ(v, 1);
62  ASSERT_FALSE(q.empty());
63  ASSERT_EQ(q.size(), 1);
64 
65  ASSERT_TRUE(q.try_dequeue(v));
66  ASSERT_EQ(v, 2);
67  ASSERT_TRUE(q.empty());
68  ASSERT_EQ(q.size(), 0);
69 }
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
#define ASSERT_FALSE(condition)
Definition: gtest.h:1868
#define ASSERT_TRUE(condition)
Definition: gtest.h:1865
template<template< typename, bool > class Q, typename T , int Op>
uint64_t bench ( const int  nprod,
const int  ncons,
const std::string name 
)

Definition at line 349 of file UnboundedQueueTest.cpp.

References ASSERT_EQ, ASSERT_TRUE, i, ops, run_once(), runBench(), sum(), T, uint64_t, UNLIKELY, and v.

349  {
350  int ops = FLAGS_ops;
351  auto repFn = [&] {
352  Q<T, Op == 3 || Op == 4 || Op == 5> q;
353  std::atomic<uint64_t> sum(0);
354  auto prod = [&](int tid) {
355  for (int i = tid; i < ops; i += nprod) {
356  q.enqueue(i);
357  }
358  };
359  auto cons = [&](int tid) {
360  uint64_t mysum = 0;
361  for (int i = tid; i < ops; i += ncons) {
362  T v;
363  if (Op == 0 || Op == 3) {
364  while (UNLIKELY(!q.try_dequeue(v))) {
365  /* keep trying */;
366  }
367  } else if (Op == 1 || Op == 4) {
368  auto duration = std::chrono::microseconds(1000);
369  while (UNLIKELY(!q.try_dequeue_for(v, duration))) {
370  /* keep trying */;
371  }
372  } else {
373  ASSERT_TRUE(Op == 2 || Op == 5);
374  q.dequeue(v);
375  }
376  if (nprod == 1 && ncons == 1) {
377  DCHECK_EQ(int(v), i);
378  }
379  mysum += v;
380  }
381  sum.fetch_add(mysum);
382  };
383  auto endfn = [&] {
384  uint64_t expected = ops;
385  expected *= ops - 1;
386  expected /= 2;
387  ASSERT_EQ(sum.load(), expected);
388  };
389  return run_once(nprod, ncons, prod, cons, endfn);
390  };
391  return runBench(name, ops, repFn);
392 }
#define T(v)
Definition: http_parser.c:233
std::atomic< int64_t > sum(0)
auto v
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
uint64_t runBench(const std::string &name, int ops, const RepFunc &repFn)
const char * name
Definition: http_parser.c:437
uint64_t run_once(int nprod, int ncons, const ProdFunc &prodFn, const ConsFunc &consFn, const EndFunc &endFn)
const int ops
#define UNLIKELY(x)
Definition: Likely.h:48
#define ASSERT_TRUE(condition)
Definition: gtest.h:1865
void benches ( const int  np,
const int  nc 
)

Definition at line 526 of file UnboundedQueueTest.cpp.

Referenced by TEST().

526  {
527  std::cout << "====================== " << std::setw(2) << np << " prod"
528  << " " << std::setw(2) << nc << " cons"
529  << " ======================" << std::endl;
530  type_benches<uint32_t>(np, nc, "=== uint32_t ======");
531  // Benchmarks for other element sizes can be added as follows:
532  // type_benches<IntArray<4>>(np, nc, "=== IntArray<4> ===");
533 }
DEFINE_bool ( bench  ,
false  ,
"run benchmark  
)
DEFINE_int32 ( reps  ,
10  ,
"number of reps"   
)
DEFINE_int32 ( ops  ,
1000000  ,
"number of operations per rep"   
)
DEFINE_int64 ( capacity  ,
256 *  1024,
"capacity"   
)
void dottedLine ( )

Definition at line 472 of file UnboundedQueueTest.cpp.

Referenced by TEST(), and type_benches().

472  {
473  std::cout << ".............................................................."
474  << std::endl;
475 }
template<bool SingleProducer, bool SingleConsumer, bool MayBlock>
void enq_deq_test ( const int  nprod,
const int  ncons 
)

Definition at line 216 of file UnboundedQueueTest.cpp.

References ASSERT_EQ, folly::UnboundedQueue< T, SingleProducer, SingleConsumer, MayBlock, LgSegmentSize, LgAlign, Atom >::dequeue(), folly::UnboundedQueue< T, SingleProducer, SingleConsumer, MayBlock, LgSegmentSize, LgAlign, Atom >::enqueue(), i, ops, run_once(), sum(), folly::UnboundedQueue< T, SingleProducer, SingleConsumer, MayBlock, LgSegmentSize, LgAlign, Atom >::try_dequeue(), folly::UnboundedQueue< T, SingleProducer, SingleConsumer, MayBlock, LgSegmentSize, LgAlign, Atom >::try_dequeue_for(), folly::UnboundedQueue< T, SingleProducer, SingleConsumer, MayBlock, LgSegmentSize, LgAlign, Atom >::try_peek(), uint64_t, and v.

216  {
217  if (SingleProducer) {
218  ASSERT_EQ(nprod, 1);
219  }
220  if (SingleConsumer) {
221  ASSERT_EQ(ncons, 1);
222  }
223 
224  int ops = 1000;
226  std::atomic<uint64_t> sum(0);
227 
228  auto prod = [&](int tid) {
229  for (int i = tid; i < ops; i += nprod) {
230  q.enqueue(i);
231  }
232  };
233 
234  auto cons = [&](int tid) {
235  uint64_t mysum = 0;
236  for (int i = tid; i < ops; i += ncons) {
237  int v = -1;
238  int vpeek = -1;
239 
240  if (SingleConsumer) {
241  while (true) {
242  auto res = q.try_peek();
243  if (res) {
244  vpeek = *res;
245  break;
246  }
247  }
248  }
249  if ((i % 3) == 0) {
250  while (!q.try_dequeue(v)) {
251  /* keep trying */;
252  }
253  } else if ((i % 3) == 1) {
254  auto duration = std::chrono::milliseconds(1);
255  while (!q.try_dequeue_for(v, duration)) {
256  /* keep trying */;
257  }
258  } else {
259  q.dequeue(v);
260  }
261  if (nprod == 1 && ncons == 1) {
262  ASSERT_EQ(v, i);
263  }
264  if (SingleConsumer) {
265  ASSERT_EQ(v, vpeek);
266  }
267  mysum += v;
268  }
269  sum.fetch_add(mysum);
270  };
271 
272  auto endfn = [&] {
273  uint64_t expected = ops;
274  expected *= ops - 1;
275  expected /= 2;
276  ASSERT_EQ(sum.load(), expected);
277  };
278  run_once(nprod, ncons, prod, cons, endfn);
279 }
FOLLY_ALWAYS_INLINE const T * try_peek() noexcept
std::atomic< int64_t > sum(0)
auto v
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
FOLLY_ALWAYS_INLINE bool try_dequeue_for(T &item, const std::chrono::duration< Rep, Period > &duration) noexcept
uint64_t run_once(int nprod, int ncons, const ProdFunc &prodFn, const ConsFunc &consFn, const EndFunc &endFn)
const int ops
FOLLY_ALWAYS_INLINE void dequeue(T &item) noexcept
FOLLY_ALWAYS_INLINE void enqueue(const T &arg)
FOLLY_ALWAYS_INLINE bool try_dequeue(T &item) noexcept
template<template< typename, bool > class Q, bool MayBlock>
void peek_test ( )

Definition at line 107 of file UnboundedQueueTest.cpp.

References ASSERT_EQ, ASSERT_FALSE, ASSERT_TRUE, i, and v.

107  {
108  Q<int, MayBlock> q;
109  auto res = q.try_peek();
110  ASSERT_FALSE(res);
111  for (int i = 0; i < 1000; ++i) {
112  q.enqueue(i);
113  }
114  for (int i = 0; i < 700; ++i) {
115  int v;
116  q.dequeue(v);
117  }
118  res = q.try_peek();
119  ASSERT_TRUE(res);
120  ASSERT_EQ(*res, 700);
121 }
auto v
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
#define ASSERT_FALSE(condition)
Definition: gtest.h:1868
#define ASSERT_TRUE(condition)
Definition: gtest.h:1865
template<typename ProdFunc , typename ConsFunc , typename EndFunc >
uint64_t run_once ( int  nprod,
int  ncons,
const ProdFunc &  prodFn,
const ConsFunc &  consFn,
const EndFunc &  endFn 
)
inline

Definition at line 158 of file UnboundedQueueTest.cpp.

References count, i, now(), and start.

Referenced by bench(), and enq_deq_test().

163  {
164  std::atomic<bool> start{false};
165  std::atomic<int> ready{0};
166 
167  /* producers */
168  std::vector<std::thread> prodThr(nprod);
169  for (int tid = 0; tid < nprod; ++tid) {
170  prodThr[tid] = std::thread([&, tid] {
171  ++ready;
172  while (!start.load()) {
173  /* spin */;
174  }
175  prodFn(tid);
176  });
177  }
178 
179  /* consumers */
180  std::vector<std::thread> consThr(ncons);
181  for (int tid = 0; tid < ncons; ++tid) {
182  consThr[tid] = std::thread([&, tid] {
183  ++ready;
184  while (!start.load()) {
185  /* spin */;
186  }
187  consFn(tid);
188  });
189  }
190 
191  /* wait for all producers and consumers to be ready */
192  while (ready.load() < (nprod + ncons)) {
193  /* spin */;
194  }
195 
196  /* begin time measurement */
197  auto tbegin = std::chrono::steady_clock::now();
198  start.store(true);
199 
200  /* wait for completion */
201  for (int i = 0; i < nprod; ++i) {
202  prodThr[i].join();
203  }
204  for (int i = 0; i < ncons; ++i) {
205  consThr[i].join();
206  }
207 
208  /* end time measurement */
209  auto tend = std::chrono::steady_clock::now();
210  endFn();
211  return std::chrono::duration_cast<std::chrono::nanoseconds>(tend - tbegin)
212  .count();
213 }
std::chrono::steady_clock::time_point now()
auto start
int * count
template<typename RepFunc >
uint64_t runBench ( const std::string name,
int  ops,
const RepFunc &  repFn 
)

Definition at line 317 of file UnboundedQueueTest.cpp.

References max, min, name, string, sum(), T, uint64_t, and folly::unit.

Referenced by bench().

317  {
318  int reps = FLAGS_reps;
319  uint64_t min = UINTMAX_MAX;
320  uint64_t max = 0;
321  uint64_t sum = 0;
322 
323  repFn(); // sometimes first run is outlier
324  for (int r = 0; r < reps; ++r) {
325  uint64_t dur = repFn();
326  sum += dur;
327  min = std::min(min, dur);
328  max = std::max(max, dur);
329  // if each rep takes too long run at least 3 reps
330  const uint64_t minute = 60000000000UL;
331  if (sum > minute && r >= 2) {
332  reps = r + 1;
333  break;
334  }
335  }
336 
337  const std::string unit = " ns";
338  uint64_t avg = sum / reps;
339  uint64_t res = min;
340  std::cout << name;
341  std::cout << " " << std::setw(4) << max / ops << unit;
342  std::cout << " " << std::setw(4) << avg / ops << unit;
343  std::cout << " " << std::setw(4) << res / ops << unit;
344  std::cout << std::endl;
345  return res;
346 }
std::atomic< int64_t > sum(0)
LogLevel max
Definition: LogLevel.cpp:31
const char * name
Definition: http_parser.c:437
LogLevel min
Definition: LogLevel.cpp:30
constexpr Unit unit
Definition: Unit.h:45
const int ops
const char * string
Definition: Conv.cpp:212
TEST ( UnboundedQueue  ,
basic   
)

Definition at line 71 of file UnboundedQueueTest.cpp.

71  {
72  basic_test<USPSC, false>();
73  basic_test<UMPSC, false>();
74  basic_test<USPMC, false>();
75  basic_test<UMPMC, false>();
76  basic_test<USPSC, true>();
77  basic_test<UMPSC, true>();
78  basic_test<USPMC, true>();
79  basic_test<UMPMC, true>();
80 }
TEST ( UnboundedQueue  ,
timeout   
)

Definition at line 95 of file UnboundedQueueTest.cpp.

95  {
96  timeout_test<USPSC, false>();
97  timeout_test<UMPSC, false>();
98  timeout_test<USPMC, false>();
99  timeout_test<UMPMC, false>();
100  timeout_test<USPSC, true>();
101  timeout_test<UMPSC, true>();
102  timeout_test<USPMC, true>();
103  timeout_test<UMPMC, true>();
104 }
TEST ( UnboundedQueue  ,
peek   
)

Definition at line 123 of file UnboundedQueueTest.cpp.

123  {
124  peek_test<USPSC, false>();
125  peek_test<UMPSC, false>();
126  peek_test<USPSC, true>();
127  peek_test<UMPSC, true>();
128 }
TEST ( UnboundedQueue  ,
cleanup_on_destruction   
)

Definition at line 130 of file UnboundedQueueTest.cpp.

References count, folly::UnboundedQueue< T, SingleProducer, SingleConsumer, MayBlock, LgSegmentSize, LgAlign, Atom >::enqueue(), folly::exchange(), EXPECT_EQ, testing::gmock_matchers_test::foo, i, folly::gen::move, and folly::pushmi::__adl::noexcept().

130  {
131  struct Foo {
132  int* p_{nullptr};
133  explicit Foo(int* p) : p_(p) {}
134  Foo(Foo&& o) noexcept : p_(std::exchange(o.p_, nullptr)) {}
135  ~Foo() {
136  if (p_) {
137  ++(*p_);
138  }
139  }
140  Foo& operator=(Foo&& o) noexcept {
141  p_ = std::exchange(o.p_, nullptr);
142  return *this;
143  }
144  };
145  int count = 0;
146  int num = 3;
147  {
149  for (int i = 0; i < num; ++i) {
150  Foo foo(&count);
151  q.enqueue(std::move(foo));
152  }
153  }
154  EXPECT_EQ(count, num);
155 }
Foo(std::atomic< int > &d)
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
STL namespace.
requires E e noexcept(noexcept(s.error(std::move(e))))
int * count
T exchange(T &obj, U &&new_value)
Definition: Utility.h:120
FOLLY_ALWAYS_INLINE void enqueue(const T &arg)
TEST ( UnboundedQueue  ,
enq_deq   
)

Definition at line 281 of file UnboundedQueueTest.cpp.

281  {
282  /* SPSC */
283  enq_deq_test<true, true, false>(1, 1);
284  enq_deq_test<true, true, true>(1, 1);
285  /* MPSC */
286  enq_deq_test<false, true, false>(1, 1);
287  enq_deq_test<false, true, true>(1, 1);
288  enq_deq_test<false, true, false>(2, 1);
289  enq_deq_test<false, true, true>(2, 1);
290  enq_deq_test<false, true, false>(10, 1);
291  enq_deq_test<false, true, true>(10, 1);
292  /* SPMC */
293  enq_deq_test<true, false, false>(1, 1);
294  enq_deq_test<true, false, true>(1, 1);
295  enq_deq_test<true, false, false>(1, 2);
296  enq_deq_test<true, false, true>(1, 2);
297  enq_deq_test<true, false, false>(1, 10);
298  enq_deq_test<true, false, true>(1, 10);
299  /* MPMC */
300  enq_deq_test<false, false, false>(1, 1);
301  enq_deq_test<false, false, true>(1, 1);
302  enq_deq_test<false, false, false>(2, 1);
303  enq_deq_test<false, false, true>(2, 1);
304  enq_deq_test<false, false, false>(10, 1);
305  enq_deq_test<false, false, true>(10, 1);
306  enq_deq_test<false, false, false>(1, 2);
307  enq_deq_test<false, false, true>(1, 2);
308  enq_deq_test<false, false, false>(1, 10);
309  enq_deq_test<false, false, true>(1, 10);
310  enq_deq_test<false, false, false>(2, 2);
311  enq_deq_test<false, false, true>(2, 2);
312  enq_deq_test<false, false, false>(10, 10);
313  enq_deq_test<false, false, true>(10, 10);
314 }
TEST ( UnboundedQueue  ,
bench   
)

Definition at line 535 of file UnboundedQueueTest.cpp.

References benches(), and dottedLine().

535  {
536  if (!FLAGS_bench) {
537  return;
538  }
539  std::cout << "=============================================================="
540  << std::endl;
541  std::cout << std::setw(2) << FLAGS_reps << " reps of " << std::setw(8)
542  << FLAGS_ops << " handoffs\n";
543  dottedLine();
544  std::cout << "$ numactl -N 1 $dir/unbounded_queue_test --bench\n";
545  dottedLine();
546  std::cout << "Using capacity " << FLAGS_capacity
547  << " for folly::ProducerConsumerQueue and\n"
548  << "folly::MPMCQueue\n";
549  std::cout << "=============================================================="
550  << std::endl;
551  std::cout << "Test name Max time Avg time Min time"
552  << std::endl;
553 
554  for (int nc : {1, 2, 4, 8, 16, 32}) {
555  int np = 1;
556  benches(np, nc);
557  }
558 
559  for (int np : {1, 2, 4, 8, 16, 32}) {
560  int nc = 1;
561  benches(np, nc);
562  }
563 
564  for (int np : {2, 4, 8, 16, 32}) {
565  for (int nc : {2, 4, 8, 16, 32}) {
566  benches(np, nc);
567  }
568  }
569 }
void benches(const int np, const int nc)
void dottedLine()
template<template< typename, bool > class Q, bool MayBlock>
void timeout_test ( )

Definition at line 83 of file UnboundedQueueTest.cpp.

References ASSERT_EQ, ASSERT_FALSE, ASSERT_TRUE, now(), and v.

83  {
84  Q<int, MayBlock> q;
85  int v;
86  ASSERT_FALSE(q.try_dequeue_until(
87  v, std::chrono::steady_clock::now() + std::chrono::microseconds(1)));
88  ASSERT_FALSE(q.try_dequeue_for(v, std::chrono::microseconds(1)));
89  q.enqueue(10);
90  ASSERT_TRUE(q.try_dequeue_until(
91  v, std::chrono::steady_clock::now() + std::chrono::microseconds(1)));
92  ASSERT_EQ(v, 10);
93 }
auto v
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
std::chrono::steady_clock::time_point now()
#define ASSERT_FALSE(condition)
Definition: gtest.h:1868
#define ASSERT_TRUE(condition)
Definition: gtest.h:1865
template<typename T >
void type_benches ( const int  np,
const int  nc,
const std::string name 
)

Definition at line 478 of file UnboundedQueueTest.cpp.

References dottedLine().

478  {
479  std::cout << name
480  << "===========================================" << std::endl;
481  if (np == 1 && nc == 1) {
482  bench<USPSC, T, 0>(1, 1, "Unbounded SPSC try spin only ");
483  bench<USPSC, T, 1>(1, 1, "Unbounded SPSC timed spin only ");
484  bench<USPSC, T, 2>(1, 1, "Unbounded SPSC wait spin only ");
485  bench<USPSC, T, 3>(1, 1, "Unbounded SPSC try may block ");
486  bench<USPSC, T, 4>(1, 1, "Unbounded SPSC timed may block ");
487  bench<USPSC, T, 5>(1, 1, "Unbounded SPSC wait may block ");
488  dottedLine();
489  }
490  if (nc == 1) {
491  bench<UMPSC, T, 0>(np, 1, "Unbounded MPSC try spin only ");
492  bench<UMPSC, T, 1>(np, 1, "Unbounded MPSC timed spin only ");
493  bench<UMPSC, T, 2>(np, 1, "Unbounded MPSC wait spin only ");
494  bench<UMPSC, T, 3>(np, 1, "Unbounded MPSC try may block ");
495  bench<UMPSC, T, 4>(np, 1, "Unbounded MPSC timed may block ");
496  bench<UMPSC, T, 5>(np, 1, "Unbounded MPSC wait may block ");
497  dottedLine();
498  }
499  if (np == 1) {
500  bench<USPMC, T, 0>(1, nc, "Unbounded SPMC try spin only ");
501  bench<USPMC, T, 1>(1, nc, "Unbounded SPMC timed spin only ");
502  bench<USPMC, T, 2>(1, nc, "Unbounded SPMC wait spin only ");
503  bench<USPMC, T, 3>(1, nc, "Unbounded SPMC try may block ");
504  bench<USPMC, T, 4>(1, nc, "Unbounded SPMC timed may block ");
505  bench<USPMC, T, 5>(1, nc, "Unbounded SPMC wait may block ");
506  dottedLine();
507  }
508  bench<UMPMC, T, 0>(np, nc, "Unbounded MPMC try spin only ");
509  bench<UMPMC, T, 1>(np, nc, "Unbounded MPMC timed spin only ");
510  bench<UMPMC, T, 2>(np, nc, "Unbounded MPMC wait spin only ");
511  bench<UMPMC, T, 3>(np, nc, "Unbounded MPMC try may block ");
512  bench<UMPMC, T, 4>(np, nc, "Unbounded MPMC timed may block ");
513  bench<UMPMC, T, 5>(np, nc, "Unbounded MPMC wait may block ");
514  dottedLine();
515  if (np == 1 && nc == 1) {
516  bench<FPCQ, T, 0>(1, 1, "folly::PCQ read ");
517  dottedLine();
518  }
519  bench<FMPMC, T, 3>(np, nc, "folly::MPMC read ");
520  bench<FMPMC, T, 4>(np, nc, "folly::MPMC tryReadUntil ");
521  bench<FMPMC, T, 5>(np, nc, "folly::MPMC blockingRead ");
522  std::cout << "=============================================================="
523  << std::endl;
524 }
const char * name
Definition: http_parser.c:437
void dottedLine()