/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
using mozilla::MultiWriterQueue; using mozilla::MultiWriterQueueDefaultBufferSize; using mozilla::MultiWriterQueueReaderLocking_Mutex; using mozilla::MultiWriterQueueReaderLocking_None;
int pushes = 0; // Go through 2 cycles of pushes&pops, to exercize reusable buffers. for (int max = loops; max <= loops * 2; max *= 2) { // Push all numbers. for (int i = 1; i <= max; ++i) { bool newBuffer = q.Push(i); // A new buffer should be added at the last push of each buffer.
EXPECT_EQ(++pushes % BufferSize == 0, newBuffer);
}
// Pop numbers, should be FIFO. int x = 0;
q.PopAll([&](int& i) { EXPECT_EQ(++x, i); });
// We should have got all numbers.
EXPECT_EQ(max, x);
for (int k = 0; k < threads; k++) { // First `aReaderThreads` threads to pop, all others to push. if (k < aReaderThreads) {
nsCOMPtr<nsIThread> t;
nsresult rv = NS_NewNamedThread("MWQThread", getter_AddRefs(t));
EXPECT_NS_SUCCEEDED(rv);
NS_ADDREF(array[k] = t);
} else {
nsCOMPtr<nsIThread> t;
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction("MWQPusher", [&, k]() { // Give a bit of breathing space to construct other threads.
PR_Sleep(PR_MillisecondsToInterval(100));
for (int i = 0; i < loops; ++i) { if (q.Push(k * threads + i) && aReaderThreads != 0) { // Run a popper task every time we push the last element of a // buffer.
array[++readerThread % aReaderThreads]->Dispatch(
popper, nsIThread::DISPATCH_NORMAL);
}
}
++pushThreadsCompleted;
});
nsresult rv = NS_NewNamedThread("MWQThread", getter_AddRefs(t), r);
EXPECT_NS_SUCCEEDED(rv);
NS_ADDREF(array[k] = t);
}
}
for (int k = threads - 1; k >= 0; k--) {
array[k]->Shutdown();
NS_RELEASE(array[k]);
} delete[] array;
// There may be a few more elements that haven't been read yet.
q.PopAll([&pops](constint& i) { ++pops; }); constint pushes = aWriterThreads * loops;
EXPECT_EQ(pushes, pops);
q.PopAll([](constint& i) { EXPECT_TRUE(false); });
// A more real-life buffer size.
TestMultiWriterQueueMT<
MultiWriterQueue<int, MultiWriterQueueDefaultBufferSize,
MultiWriterQueueReaderLocking_None>>( 64, 1, 2 * 1024 * 1024, "MultiWriterQueue<int, DefaultBufferSize, Locking_None>");
// DEBUG-mode thread-safety checks should make the following (multi-reader // with no locking) crash; uncomment to verify. // TestMultiWriterQueueMT< // MultiWriterQueue<int, MultiWriterQueueDefaultBufferSize, // MultiWriterQueueReaderLocking_None>>(64, 2, 2*1024*1024);
} #endif
// skip test on windows10-aarch64 due to unexpected test timeout at // MultiWriterMultiReade, bug 1526001 #if !defined(_M_ARM64)
TEST(MultiWriterQueue, MultiWriterMultiReader)
{
static_assert(
std::is_same_v<
MultiWriterQueue<int, 10>,
MultiWriterQueue<int, 10, MultiWriterQueueReaderLocking_Mutex>>, "MultiWriterQueue reader locking should use Mutex by default");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.