Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/media/doctor/gtest/TestMultiWriterQueue.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "MultiWriterQueue.h"
8
9
#include "DDTimeStamp.h"
10
#include "mozilla/Assertions.h"
11
#include "nsDeque.h"
12
#include "nsThreadUtils.h"
13
14
#include <gtest/gtest.h>
15
16
using mozilla::MultiWriterQueue;
17
using mozilla::MultiWriterQueueDefaultBufferSize;
18
using mozilla::MultiWriterQueueReaderLocking_Mutex;
19
using mozilla::MultiWriterQueueReaderLocking_None;
20
21
template<size_t BufferSize>
22
static void
23
TestMultiWriterQueueST(const int loops)
24
0
{
25
0
  using Q = MultiWriterQueue<int, BufferSize>;
26
0
  Q q;
27
0
28
0
  int pushes = 0;
29
0
  // Go through 2 cycles of pushes&pops, to exercize reusable buffers.
30
0
  for (int max = loops; max <= loops * 2; max *= 2) {
31
0
    // Push all numbers.
32
0
    for (int i = 1; i <= max; ++i) {
33
0
      bool newBuffer = q.Push(i);
34
0
      // A new buffer should be added at the last push of each buffer.
35
0
      EXPECT_EQ(++pushes % BufferSize == 0, newBuffer);
36
0
    }
37
0
38
0
    // Pop numbers, should be FIFO.
39
0
    int x = 0;
40
0
    q.PopAll([&](int& i) { EXPECT_EQ(++x, i); });
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueST<1ul>(int)::{lambda(int&)#1}::operator()(int&) const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueST<2ul>(int)::{lambda(int&)#1}::operator()(int&) const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueST<4ul>(int)::{lambda(int&)#1}::operator()(int&) const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueST<10ul>(int)::{lambda(int&)#1}::operator()(int&) const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueST<8192ul>(int)::{lambda(int&)#1}::operator()(int&) const
41
0
42
0
    // We should have got all numbers.
43
0
    EXPECT_EQ(max, x);
44
0
45
0
    // Nothing left.
46
0
    q.PopAll([&](int&) { EXPECT_TRUE(false); });
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueST<1ul>(int)::{lambda(int&)#2}::operator()(int&) const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueST<2ul>(int)::{lambda(int&)#2}::operator()(int&) const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueST<4ul>(int)::{lambda(int&)#2}::operator()(int&) const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueST<10ul>(int)::{lambda(int&)#2}::operator()(int&) const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueST<8192ul>(int)::{lambda(int&)#2}::operator()(int&) const
47
0
  }
48
0
}
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueST<1ul>(int)
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueST<2ul>(int)
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueST<4ul>(int)
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueST<10ul>(int)
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueST<8192ul>(int)
49
50
TEST(MultiWriterQueue, SingleThreaded)
51
0
{
52
0
  TestMultiWriterQueueST<1>(10);
53
0
  TestMultiWriterQueueST<2>(10);
54
0
  TestMultiWriterQueueST<4>(10);
55
0
56
0
  TestMultiWriterQueueST<10>(9);
57
0
  TestMultiWriterQueueST<10>(10);
58
0
  TestMultiWriterQueueST<10>(11);
59
0
  TestMultiWriterQueueST<10>(19);
60
0
  TestMultiWriterQueueST<10>(20);
61
0
  TestMultiWriterQueueST<10>(21);
62
0
  TestMultiWriterQueueST<10>(999);
63
0
  TestMultiWriterQueueST<10>(1000);
64
0
  TestMultiWriterQueueST<10>(1001);
65
0
66
0
  TestMultiWriterQueueST<8192>(8192 * 4 + 1);
67
0
}
68
69
template<typename Q>
70
static void
71
TestMultiWriterQueueMT(int aWriterThreads,
72
                       int aReaderThreads,
73
                       int aTotalLoops,
74
                       const char* aPrintPrefix)
75
0
{
76
0
  Q q;
77
0
78
0
  const int threads = aWriterThreads + aReaderThreads;
79
0
  const int loops = aTotalLoops / aWriterThreads;
80
0
81
0
  nsIThread** array = new nsIThread*[threads];
82
0
83
0
  mozilla::Atomic<int> pushThreadsCompleted{ 0 };
84
0
  int pops = 0;
85
0
86
0
  nsCOMPtr<nsIRunnable> popper = NS_NewRunnableFunction("MWQPopper", [&]() {
87
0
    // int popsBefore = pops;
88
0
    // int allocsBefore = q.AllocatedBuffersStats().mCount;
89
0
    q.PopAll([&pops](const int& i) { ++pops; });
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<mozilla::MultiWriterQueue<int, 10u, mozilla::MultiWriterQueueReaderLocking_None> >(int, int, int, char const*)::{lambda()#1}::operator()() const::{lambda(int const&)#1}::operator()(int const) const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<mozilla::MultiWriterQueue<int, 8192u, mozilla::MultiWriterQueueReaderLocking_None> >(int, int, int, char const*)::{lambda()#1}::operator()() const::{lambda(int const&)#1}::operator()(int const) const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<mozilla::MultiWriterQueue<int, 10u, mozilla::MultiWriterQueueReaderLocking_Mutex> >(int, int, int, char const*)::{lambda()#1}::operator()() const::{lambda(int const&)#1}::operator()(int const) const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<mozilla::MultiWriterQueue<int, 8192u, mozilla::MultiWriterQueueReaderLocking_Mutex> >(int, int, int, char const*)::{lambda()#1}::operator()() const::{lambda(int const&)#1}::operator()(int const) const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<DequeWrapperST>(int, int, int, char const*)::{lambda()#1}::operator()() const::{lambda(int const&)#1}::operator()(int const) const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<DequeWrapperAW>(int, int, int, char const*)::{lambda()#1}::operator()() const::{lambda(int const&)#1}::operator()(int const) const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<DequeWrapperMW>(int, int, int, char const*)::{lambda()#1}::operator()() const::{lambda(int const&)#1}::operator()(int const) const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<DequeWrapperMT>(int, int, int, char const*)::{lambda()#1}::operator()() const::{lambda(int const&)#1}::operator()(int const) const
90
0
    // if (pops != popsBefore ||
91
0
    //     q.AllocatedBuffersStats().mCount != allocsBefore) {
92
0
    //   printf("%s threads=1+%d loops/thread=%d pops=%d "
93
0
    //          "buffers: live=%d (w %d) reusable=%d (w %d) "
94
0
    //          "alloc=%d (w %d)\n",
95
0
    //          aPrintPrefix,
96
0
    //          aWriterThreads,
97
0
    //          loops,
98
0
    //          pops,
99
0
    //          q.LiveBuffersStats().mCount,
100
0
    //          q.LiveBuffersStats().mWatermark,
101
0
    //          q.ReusableBuffersStats().mCount,
102
0
    //          q.ReusableBuffersStats().mWatermark,
103
0
    //          q.AllocatedBuffersStats().mCount,
104
0
    //          q.AllocatedBuffersStats().mWatermark);
105
0
    // }
106
0
  });
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<mozilla::MultiWriterQueue<int, 10u, mozilla::MultiWriterQueueReaderLocking_None> >(int, int, int, char const*)::{lambda()#1}::operator()() const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<mozilla::MultiWriterQueue<int, 8192u, mozilla::MultiWriterQueueReaderLocking_None> >(int, int, int, char const*)::{lambda()#1}::operator()() const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<mozilla::MultiWriterQueue<int, 10u, mozilla::MultiWriterQueueReaderLocking_Mutex> >(int, int, int, char const*)::{lambda()#1}::operator()() const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<mozilla::MultiWriterQueue<int, 8192u, mozilla::MultiWriterQueueReaderLocking_Mutex> >(int, int, int, char const*)::{lambda()#1}::operator()() const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<DequeWrapperST>(int, int, int, char const*)::{lambda()#1}::operator()() const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<DequeWrapperAW>(int, int, int, char const*)::{lambda()#1}::operator()() const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<DequeWrapperMW>(int, int, int, char const*)::{lambda()#1}::operator()() const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<DequeWrapperMT>(int, int, int, char const*)::{lambda()#1}::operator()() const
107
0
  // Cycle through reader threads.
108
0
  mozilla::Atomic<size_t> readerThread{ 0 };
109
0
110
0
  double start = mozilla::ToSeconds(mozilla::DDNow());
111
0
112
0
  for (int k = 0; k < threads; k++) {
113
0
    // First `aReaderThreads` threads to pop, all others to push.
114
0
    if (k < aReaderThreads) {
115
0
      nsCOMPtr<nsIThread> t;
116
0
      nsresult rv = NS_NewNamedThread("MWQThread", getter_AddRefs(t));
117
0
      EXPECT_TRUE(NS_SUCCEEDED(rv));
118
0
      NS_ADDREF(array[k] = t);
119
0
    } else {
120
0
      nsCOMPtr<nsIThread> t;
121
0
      nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction("MWQPusher", [&, k]() {
122
0
        // Give a bit of breathing space to construct other threads.
123
0
        PR_Sleep(PR_MillisecondsToInterval(100));
124
0
125
0
        for (int i = 0; i < loops; ++i) {
126
0
          if (q.Push(k * threads + i) && aReaderThreads != 0) {
127
0
            // Run a popper task every time we push the last element of a
128
0
            // buffer.
129
0
            array[++readerThread % aReaderThreads]->Dispatch(
130
0
              popper, nsIThread::DISPATCH_NORMAL);
131
0
          }
132
0
        }
133
0
        ++pushThreadsCompleted;
134
0
      });
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<mozilla::MultiWriterQueue<int, 10u, mozilla::MultiWriterQueueReaderLocking_None> >(int, int, int, char const*)::{lambda()#2}::operator()() const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<mozilla::MultiWriterQueue<int, 8192u, mozilla::MultiWriterQueueReaderLocking_None> >(int, int, int, char const*)::{lambda()#2}::operator()() const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<mozilla::MultiWriterQueue<int, 10u, mozilla::MultiWriterQueueReaderLocking_Mutex> >(int, int, int, char const*)::{lambda()#2}::operator()() const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<mozilla::MultiWriterQueue<int, 8192u, mozilla::MultiWriterQueueReaderLocking_Mutex> >(int, int, int, char const*)::{lambda()#2}::operator()() const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<DequeWrapperST>(int, int, int, char const*)::{lambda()#2}::operator()() const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<DequeWrapperAW>(int, int, int, char const*)::{lambda()#2}::operator()() const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<DequeWrapperMW>(int, int, int, char const*)::{lambda()#2}::operator()() const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<DequeWrapperMT>(int, int, int, char const*)::{lambda()#2}::operator()() const
135
0
      nsresult rv = NS_NewNamedThread("MWQThread", getter_AddRefs(t), r);
136
0
      EXPECT_TRUE(NS_SUCCEEDED(rv));
137
0
      NS_ADDREF(array[k] = t);
138
0
    }
139
0
  }
140
0
141
0
  for (int k = threads - 1; k >= 0; k--) {
142
0
    array[k]->Shutdown();
143
0
    NS_RELEASE(array[k]);
144
0
  }
145
0
  delete[] array;
146
0
147
0
  // There may be a few more elements that haven't been read yet.
148
0
  q.PopAll([&pops](const int& i) { ++pops; });
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<mozilla::MultiWriterQueue<int, 10u, mozilla::MultiWriterQueueReaderLocking_None> >(int, int, int, char const*)::{lambda(int const&)#1}::operator()(int const&) const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<mozilla::MultiWriterQueue<int, 8192u, mozilla::MultiWriterQueueReaderLocking_None> >(int, int, int, char const*)::{lambda(int const&)#1}::operator()(int const&) const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<mozilla::MultiWriterQueue<int, 10u, mozilla::MultiWriterQueueReaderLocking_Mutex> >(int, int, int, char const*)::{lambda(int const&)#1}::operator()(int const&) const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<mozilla::MultiWriterQueue<int, 8192u, mozilla::MultiWriterQueueReaderLocking_Mutex> >(int, int, int, char const*)::{lambda(int const&)#1}::operator()(int const&) const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<DequeWrapperST>(int, int, int, char const*)::{lambda(int const&)#1}::operator()(int const&) const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<DequeWrapperAW>(int, int, int, char const*)::{lambda(int const&)#1}::operator()(int const&) const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<DequeWrapperMW>(int, int, int, char const*)::{lambda(int const&)#1}::operator()(int const&) const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<DequeWrapperMT>(int, int, int, char const*)::{lambda(int const&)#1}::operator()(int const&) const
149
0
  const int pushes = aWriterThreads * loops;
150
0
  EXPECT_EQ(pushes, pops);
151
0
  q.PopAll([](const int& i) { EXPECT_TRUE(false); });
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<mozilla::MultiWriterQueue<int, 10u, mozilla::MultiWriterQueueReaderLocking_None> >(int, int, int, char const*)::{lambda(int const&)#2}::operator()(int const&) const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<mozilla::MultiWriterQueue<int, 8192u, mozilla::MultiWriterQueueReaderLocking_None> >(int, int, int, char const*)::{lambda(int const&)#2}::operator()(int const&) const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<mozilla::MultiWriterQueue<int, 10u, mozilla::MultiWriterQueueReaderLocking_Mutex> >(int, int, int, char const*)::{lambda(int const&)#2}::operator()(int const&) const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<mozilla::MultiWriterQueue<int, 8192u, mozilla::MultiWriterQueueReaderLocking_Mutex> >(int, int, int, char const*)::{lambda(int const&)#2}::operator()(int const&) const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<DequeWrapperST>(int, int, int, char const*)::{lambda(int const&)#2}::operator()(int const&) const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<DequeWrapperAW>(int, int, int, char const*)::{lambda(int const&)#2}::operator()(int const&) const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<DequeWrapperMW>(int, int, int, char const*)::{lambda(int const&)#2}::operator()(int const&) const
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<DequeWrapperMT>(int, int, int, char const*)::{lambda(int const&)#2}::operator()(int const&) const
152
0
153
0
  double duration = mozilla::ToSeconds(mozilla::DDNow()) - start - 0.1;
154
0
  printf("%s threads=%dw+%dr loops/thread=%d pushes=pops=%d duration=%fs "
155
0
         "pushes/s=%f buffers: live=%d (w %d) reusable=%d (w %d) "
156
0
         "alloc=%d (w %d)\n",
157
0
         aPrintPrefix,
158
0
         aWriterThreads,
159
0
         aReaderThreads,
160
0
         loops,
161
0
         pushes,
162
0
         duration,
163
0
         pushes / duration,
164
0
         q.LiveBuffersStats().mCount,
165
0
         q.LiveBuffersStats().mWatermark,
166
0
         q.ReusableBuffersStats().mCount,
167
0
         q.ReusableBuffersStats().mWatermark,
168
0
         q.AllocatedBuffersStats().mCount,
169
0
         q.AllocatedBuffersStats().mWatermark);
170
0
}
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<mozilla::MultiWriterQueue<int, 10u, mozilla::MultiWriterQueueReaderLocking_None> >(int, int, int, char const*)
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<mozilla::MultiWriterQueue<int, 8192u, mozilla::MultiWriterQueueReaderLocking_None> >(int, int, int, char const*)
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<mozilla::MultiWriterQueue<int, 10u, mozilla::MultiWriterQueueReaderLocking_Mutex> >(int, int, int, char const*)
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<mozilla::MultiWriterQueue<int, 8192u, mozilla::MultiWriterQueueReaderLocking_Mutex> >(int, int, int, char const*)
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<DequeWrapperST>(int, int, int, char const*)
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<DequeWrapperAW>(int, int, int, char const*)
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<DequeWrapperMW>(int, int, int, char const*)
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void TestMultiWriterQueueMT<DequeWrapperMT>(int, int, int, char const*)
171
172
TEST(MultiWriterQueue, MultiWriterSingleReader)
173
0
{
174
0
  // Small BufferSize, to exercize the buffer management code.
175
0
  TestMultiWriterQueueMT<
176
0
    MultiWriterQueue<int, 10, MultiWriterQueueReaderLocking_None>>(
177
0
    1, 0, 2 * 1024 * 1024, "MultiWriterQueue<int, 10, Locking_None>");
178
0
  TestMultiWriterQueueMT<
179
0
    MultiWriterQueue<int, 10, MultiWriterQueueReaderLocking_None>>(
180
0
    1, 1, 2 * 1024 * 1024, "MultiWriterQueue<int, 10, Locking_None>");
181
0
  TestMultiWriterQueueMT<
182
0
    MultiWriterQueue<int, 10, MultiWriterQueueReaderLocking_None>>(
183
0
    2, 1, 2 * 1024 * 1024, "MultiWriterQueue<int, 10, Locking_None>");
184
0
  TestMultiWriterQueueMT<
185
0
    MultiWriterQueue<int, 10, MultiWriterQueueReaderLocking_None>>(
186
0
    3, 1, 2 * 1024 * 1024, "MultiWriterQueue<int, 10, Locking_None>");
187
0
  TestMultiWriterQueueMT<
188
0
    MultiWriterQueue<int, 10, MultiWriterQueueReaderLocking_None>>(
189
0
    4, 1, 2 * 1024 * 1024, "MultiWriterQueue<int, 10, Locking_None>");
190
0
  TestMultiWriterQueueMT<
191
0
    MultiWriterQueue<int, 10, MultiWriterQueueReaderLocking_None>>(
192
0
    5, 1, 2 * 1024 * 1024, "MultiWriterQueue<int, 10, Locking_None>");
193
0
  TestMultiWriterQueueMT<
194
0
    MultiWriterQueue<int, 10, MultiWriterQueueReaderLocking_None>>(
195
0
    6, 1, 2 * 1024 * 1024, "MultiWriterQueue<int, 10, Locking_None>");
196
0
  TestMultiWriterQueueMT<
197
0
    MultiWriterQueue<int, 10, MultiWriterQueueReaderLocking_None>>(
198
0
    7, 1, 2 * 1024 * 1024, "MultiWriterQueue<int, 10, Locking_None>");
199
0
  TestMultiWriterQueueMT<
200
0
    MultiWriterQueue<int, 10, MultiWriterQueueReaderLocking_None>>(
201
0
    8, 1, 2 * 1024 * 1024, "MultiWriterQueue<int, 10, Locking_None>");
202
0
  TestMultiWriterQueueMT<
203
0
    MultiWriterQueue<int, 10, MultiWriterQueueReaderLocking_None>>(
204
0
    9, 1, 2 * 1024 * 1024, "MultiWriterQueue<int, 10, Locking_None>");
205
0
  TestMultiWriterQueueMT<
206
0
    MultiWriterQueue<int, 10, MultiWriterQueueReaderLocking_None>>(
207
0
    10, 1, 2 * 1024 * 1024, "MultiWriterQueue<int, 10, Locking_None>");
208
0
  TestMultiWriterQueueMT<
209
0
    MultiWriterQueue<int, 10, MultiWriterQueueReaderLocking_None>>(
210
0
    16, 1, 2 * 1024 * 1024, "MultiWriterQueue<int, 10, Locking_None>");
211
0
  TestMultiWriterQueueMT<
212
0
    MultiWriterQueue<int, 10, MultiWriterQueueReaderLocking_None>>(
213
0
    32, 1, 2 * 1024 * 1024, "MultiWriterQueue<int, 10, Locking_None>");
214
0
  TestMultiWriterQueueMT<
215
0
    MultiWriterQueue<int, 10, MultiWriterQueueReaderLocking_None>>(
216
0
    64, 1, 2 * 1024 * 1024, "MultiWriterQueue<int, 10, Locking_None>");
217
0
218
0
  // A more real-life buffer size.
219
0
  TestMultiWriterQueueMT<MultiWriterQueue<int,
220
0
                                          MultiWriterQueueDefaultBufferSize,
221
0
                                          MultiWriterQueueReaderLocking_None>>(
222
0
    64,
223
0
    1,
224
0
    2 * 1024 * 1024,
225
0
    "MultiWriterQueue<int, DefaultBufferSize, Locking_None>");
226
0
227
0
  // DEBUG-mode thread-safety checks should make the following (multi-reader
228
0
  // with no locking) crash; uncomment to verify.
229
0
  // TestMultiWriterQueueMT<
230
0
  //   MultiWriterQueue<int, MultiWriterQueueDefaultBufferSize, MultiWriterQueueReaderLocking_None>>(64, 2, 2*1024*1024);
231
0
}
232
233
TEST(MultiWriterQueue, MultiWriterMultiReader)
234
0
{
235
0
  static_assert(
236
0
    mozilla::IsSame<
237
0
      MultiWriterQueue<int, 10>,
238
0
      MultiWriterQueue<int, 10, MultiWriterQueueReaderLocking_Mutex>>::value,
239
0
    "MultiWriterQueue reader locking should use Mutex by default");
240
0
241
0
  // Small BufferSize, to exercize the buffer management code.
242
0
  TestMultiWriterQueueMT<
243
0
    MultiWriterQueue<int, 10, MultiWriterQueueReaderLocking_Mutex>>(
244
0
    1, 2, 1024 * 1024, "MultiWriterQueue<int, 10, Locking_Mutex>");
245
0
  TestMultiWriterQueueMT<
246
0
    MultiWriterQueue<int, 10, MultiWriterQueueReaderLocking_Mutex>>(
247
0
    2, 2, 1024 * 1024, "MultiWriterQueue<int, 10, Locking_Mutex>");
248
0
  TestMultiWriterQueueMT<
249
0
    MultiWriterQueue<int, 10, MultiWriterQueueReaderLocking_Mutex>>(
250
0
    3, 2, 1024 * 1024, "MultiWriterQueue<int, 10, Locking_Mutex>");
251
0
  TestMultiWriterQueueMT<
252
0
    MultiWriterQueue<int, 10, MultiWriterQueueReaderLocking_Mutex>>(
253
0
    4, 2, 1024 * 1024, "MultiWriterQueue<int, 10, Locking_Mutex>");
254
0
  TestMultiWriterQueueMT<
255
0
    MultiWriterQueue<int, 10, MultiWriterQueueReaderLocking_Mutex>>(
256
0
    5, 2, 1024 * 1024, "MultiWriterQueue<int, 10, Locking_Mutex>");
257
0
  TestMultiWriterQueueMT<
258
0
    MultiWriterQueue<int, 10, MultiWriterQueueReaderLocking_Mutex>>(
259
0
    6, 2, 1024 * 1024, "MultiWriterQueue<int, 10, Locking_Mutex>");
260
0
  TestMultiWriterQueueMT<
261
0
    MultiWriterQueue<int, 10, MultiWriterQueueReaderLocking_Mutex>>(
262
0
    7, 2, 1024 * 1024, "MultiWriterQueue<int, 10, Locking_Mutex>");
263
0
  TestMultiWriterQueueMT<
264
0
    MultiWriterQueue<int, 10, MultiWriterQueueReaderLocking_Mutex>>(
265
0
    8, 2, 1024 * 1024, "MultiWriterQueue<int, 10, Locking_Mutex>");
266
0
  TestMultiWriterQueueMT<
267
0
    MultiWriterQueue<int, 10, MultiWriterQueueReaderLocking_Mutex>>(
268
0
    9, 2, 1024 * 1024, "MultiWriterQueue<int, 10, Locking_Mutex>");
269
0
  TestMultiWriterQueueMT<
270
0
    MultiWriterQueue<int, 10, MultiWriterQueueReaderLocking_Mutex>>(
271
0
    10, 4, 1024 * 1024, "MultiWriterQueue<int, 10, Locking_Mutex>");
272
0
  TestMultiWriterQueueMT<
273
0
    MultiWriterQueue<int, 10, MultiWriterQueueReaderLocking_Mutex>>(
274
0
    16, 8, 1024 * 1024, "MultiWriterQueue<int, 10, Locking_Mutex>");
275
0
  TestMultiWriterQueueMT<
276
0
    MultiWriterQueue<int, 10, MultiWriterQueueReaderLocking_Mutex>>(
277
0
    32, 16, 1024 * 1024, "MultiWriterQueue<int, 10, Locking_Mutex>");
278
0
  TestMultiWriterQueueMT<
279
0
    MultiWriterQueue<int, 10, MultiWriterQueueReaderLocking_Mutex>>(
280
0
    64, 32, 1024 * 1024, "MultiWriterQueue<int, 10, Locking_Mutex>");
281
0
282
0
  // A more real-life buffer size.
283
0
  TestMultiWriterQueueMT<MultiWriterQueue<int,
284
0
                                          MultiWriterQueueDefaultBufferSize,
285
0
                                          MultiWriterQueueReaderLocking_Mutex>>(
286
0
    64,
287
0
    32,
288
0
    1024 * 1024,
289
0
    "MultiWriterQueue<int, DefaultBufferSize, Locking_Mutex>");
290
0
}
291
292
// Single-threaded use only.
293
struct DequeWrapperST
294
{
295
  nsDeque mDQ;
296
297
  bool Push(int i)
298
0
  {
299
0
    mDQ.PushFront(reinterpret_cast<void*>(static_cast<uintptr_t>(i)));
300
0
    return true;
301
0
  }
302
  template<typename F>
303
  void PopAll(F&& aF)
304
0
  {
305
0
    while (mDQ.GetSize() != 0) {
306
0
      int i = static_cast<int>(reinterpret_cast<uintptr_t>(mDQ.Pop()));
307
0
      aF(i);
308
0
    }
309
0
  }
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void DequeWrapperST::PopAll<void TestMultiWriterQueueMT<DequeWrapperST>(int, int, int, char const*)::{lambda()#1}::operator()() const::{lambda(int const&)#1}>(void TestMultiWriterQueueMT<DequeWrapperST>(int, int, int, char const*)::{lambda()#1}::operator()() const::{lambda(int const&)#1}&&)
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void DequeWrapperST::PopAll<void TestMultiWriterQueueMT<DequeWrapperST>(int, int, int, char const*)::{lambda(int const&)#1}>(void TestMultiWriterQueueMT<DequeWrapperST>(int, int, int, char const*)::{lambda(int const&)#1}&&)
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void DequeWrapperST::PopAll<void TestMultiWriterQueueMT<DequeWrapperST>(int, int, int, char const*)::{lambda(int const&)#2}>(void TestMultiWriterQueueMT<DequeWrapperST>(int, int, int, char const*)::{lambda(int const&)#2}&&)
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void DequeWrapperST::PopAll<void TestMultiWriterQueueMT<DequeWrapperAW>(int, int, int, char const*)::{lambda()#1}::operator()() const::{lambda(int const&)#1}>(void TestMultiWriterQueueMT<DequeWrapperAW>(int, int, int, char const*)::{lambda()#1}::operator()() const::{lambda(int const&)#1}&&)
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void DequeWrapperST::PopAll<void TestMultiWriterQueueMT<DequeWrapperAW>(int, int, int, char const*)::{lambda(int const&)#1}>(void TestMultiWriterQueueMT<DequeWrapperAW>(int, int, int, char const*)::{lambda(int const&)#1}&&)
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void DequeWrapperST::PopAll<void TestMultiWriterQueueMT<DequeWrapperAW>(int, int, int, char const*)::{lambda(int const&)#2}>(void TestMultiWriterQueueMT<DequeWrapperAW>(int, int, int, char const*)::{lambda(int const&)#2}&&)
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void DequeWrapperST::PopAll<void TestMultiWriterQueueMT<DequeWrapperMW>(int, int, int, char const*)::{lambda()#1}::operator()() const::{lambda(int const&)#1}>(void TestMultiWriterQueueMT<DequeWrapperMW>(int, int, int, char const*)::{lambda()#1}::operator()() const::{lambda(int const&)#1}&&)
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void DequeWrapperST::PopAll<void TestMultiWriterQueueMT<DequeWrapperMW>(int, int, int, char const*)::{lambda(int const&)#1}>(void TestMultiWriterQueueMT<DequeWrapperMW>(int, int, int, char const*)::{lambda(int const&)#1}&&)
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void DequeWrapperST::PopAll<void TestMultiWriterQueueMT<DequeWrapperMW>(int, int, int, char const*)::{lambda(int const&)#2}>(void TestMultiWriterQueueMT<DequeWrapperMW>(int, int, int, char const*)::{lambda(int const&)#2}&&)
310
311
  struct CountAndWatermark
312
  {
313
    int mCount = 0;
314
    int mWatermark = 0;
315
  } mLiveBuffersStats, mReusableBuffersStats, mAllocatedBuffersStats;
316
317
0
  CountAndWatermark LiveBuffersStats() const { return mLiveBuffersStats; }
318
  CountAndWatermark ReusableBuffersStats() const
319
0
  {
320
0
    return mReusableBuffersStats;
321
0
  }
322
  CountAndWatermark AllocatedBuffersStats() const
323
0
  {
324
0
    return mAllocatedBuffersStats;
325
0
  }
326
};
327
328
// Multi-thread (atomic) writes allowed, make sure you don't pop unless writes can't happen.
329
struct DequeWrapperAW : DequeWrapperST
330
{
331
  mozilla::Atomic<bool> mWriting{ false };
332
333
  bool Push(int i)
334
0
  {
335
0
    while (!mWriting.compareExchange(false, true)) {
336
0
    }
337
0
    mDQ.PushFront(reinterpret_cast<void*>(static_cast<uintptr_t>(i)));
338
0
    mWriting = false;
339
0
    return true;
340
0
  }
341
};
342
343
// Multi-thread writes allowed, make sure you don't pop unless writes can't happen.
344
struct DequeWrapperMW : DequeWrapperST
345
{
346
  mozilla::Mutex mMutex;
347
348
  DequeWrapperMW()
349
    : mMutex("DequeWrapperMW/MT")
350
0
  {
351
0
  }
352
353
  bool Push(int i)
354
0
  {
355
0
    mozilla::MutexAutoLock lock(mMutex);
356
0
    mDQ.PushFront(reinterpret_cast<void*>(static_cast<uintptr_t>(i)));
357
0
    return true;
358
0
  }
359
};
360
361
// Multi-thread read&writes allowed.
362
struct DequeWrapperMT : DequeWrapperMW
363
{
364
  template<typename F>
365
  void PopAll(F&& aF)
366
0
  {
367
0
    while (mDQ.GetSize() != 0) {
368
0
      int i;
369
0
      {
370
0
        mozilla::MutexAutoLock lock(mMutex);
371
0
        i = static_cast<int>(reinterpret_cast<uintptr_t>(mDQ.Pop()));
372
0
      }
373
0
      aF(i);
374
0
    }
375
0
  }
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void DequeWrapperMT::PopAll<void TestMultiWriterQueueMT<DequeWrapperMT>(int, int, int, char const*)::{lambda()#1}::operator()() const::{lambda(int const&)#1}>(void TestMultiWriterQueueMT<DequeWrapperMT>(int, int, int, char const*)::{lambda()#1}::operator()() const::{lambda(int const&)#1}&&)
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void DequeWrapperMT::PopAll<void TestMultiWriterQueueMT<DequeWrapperMT>(int, int, int, char const*)::{lambda(int const&)#1}>(void TestMultiWriterQueueMT<DequeWrapperMT>(int, int, int, char const*)::{lambda(int const&)#1}&&)
Unexecuted instantiation: Unified_cpp_media_doctor_gtest0.cpp:void DequeWrapperMT::PopAll<void TestMultiWriterQueueMT<DequeWrapperMT>(int, int, int, char const*)::{lambda(int const&)#2}>(void TestMultiWriterQueueMT<DequeWrapperMT>(int, int, int, char const*)::{lambda(int const&)#2}&&)
376
};
377
378
TEST(MultiWriterQueue, nsDequeBenchmark)
379
0
{
380
0
  TestMultiWriterQueueMT<DequeWrapperST>(
381
0
    1, 0, 2 * 1024 * 1024, "DequeWrapperST ");
382
0
383
0
  TestMultiWriterQueueMT<DequeWrapperAW>(
384
0
    1, 0, 2 * 1024 * 1024, "DequeWrapperAW ");
385
0
  TestMultiWriterQueueMT<DequeWrapperMW>(
386
0
    1, 0, 2 * 1024 * 1024, "DequeWrapperMW ");
387
0
  TestMultiWriterQueueMT<DequeWrapperMT>(
388
0
    1, 0, 2 * 1024 * 1024, "DequeWrapperMT ");
389
0
  TestMultiWriterQueueMT<DequeWrapperMT>(
390
0
    1, 1, 2 * 1024 * 1024, "DequeWrapperMT ");
391
0
392
0
  TestMultiWriterQueueMT<DequeWrapperAW>(
393
0
    8, 0, 2 * 1024 * 1024, "DequeWrapperAW ");
394
0
  TestMultiWriterQueueMT<DequeWrapperMW>(
395
0
    8, 0, 2 * 1024 * 1024, "DequeWrapperMW ");
396
0
  TestMultiWriterQueueMT<DequeWrapperMT>(
397
0
    8, 0, 2 * 1024 * 1024, "DequeWrapperMT ");
398
0
  TestMultiWriterQueueMT<DequeWrapperMT>(
399
0
    8, 1, 2 * 1024 * 1024, "DequeWrapperMT ");
400
0
}