|
|
|
@ -2,15 +2,15 @@
|
|
|
|
|
#include <util/threading.hpp>
|
|
|
|
|
|
|
|
|
|
#include <array>
|
|
|
|
|
#include <thread>
|
|
|
|
|
#include <functional>
|
|
|
|
|
#include <thread>
|
|
|
|
|
|
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
|
|
|
|
|
|
using namespace llarp;
|
|
|
|
|
using namespace llarp::thread;
|
|
|
|
|
|
|
|
|
|
using LockGuard = std::unique_lock< std::mutex >;
|
|
|
|
|
using LockGuard = absl::MutexLock;
|
|
|
|
|
|
|
|
|
|
class Element
|
|
|
|
|
{
|
|
|
|
@ -49,7 +49,7 @@ class Args
|
|
|
|
|
public:
|
|
|
|
|
std::condition_variable startCond;
|
|
|
|
|
std::condition_variable runCond;
|
|
|
|
|
std::mutex mutex;
|
|
|
|
|
absl::Mutex mutex;
|
|
|
|
|
|
|
|
|
|
ObjQueue queue;
|
|
|
|
|
|
|
|
|
@ -71,18 +71,29 @@ class Args
|
|
|
|
|
, endSignal(0)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
signal() const
|
|
|
|
|
{
|
|
|
|
|
return !!runSignal;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
using CondArgs = std::pair< Args*, size_t >;
|
|
|
|
|
bool
|
|
|
|
|
waitFunc(CondArgs* a)
|
|
|
|
|
{
|
|
|
|
|
return a->first->count != a->second;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
popFrontTester(Args& args)
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
LockGuard guard(args.mutex);
|
|
|
|
|
LockGuard guard(&args.mutex);
|
|
|
|
|
args.count++;
|
|
|
|
|
|
|
|
|
|
args.startCond.notify_one();
|
|
|
|
|
|
|
|
|
|
args.runCond.wait(guard, [&args]() { return !!args.runSignal; });
|
|
|
|
|
args.mutex.Await(absl::Condition(&args, &Args::signal));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(;;)
|
|
|
|
@ -99,12 +110,10 @@ void
|
|
|
|
|
pushBackTester(Args& args)
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
LockGuard guard(args.mutex);
|
|
|
|
|
LockGuard guard(&args.mutex);
|
|
|
|
|
args.count++;
|
|
|
|
|
|
|
|
|
|
args.startCond.notify_one();
|
|
|
|
|
|
|
|
|
|
args.runCond.wait(guard, [&args]() { return !!args.runSignal; });
|
|
|
|
|
args.mutex.Await(absl::Condition(&args, &Args::signal));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(size_t i = 0; i < args.iterations; ++i)
|
|
|
|
@ -274,18 +283,19 @@ TEST(TestQueue, singleProducerManyConsumer)
|
|
|
|
|
|
|
|
|
|
Args args{iterations};
|
|
|
|
|
|
|
|
|
|
LockGuard lock(args.mutex);
|
|
|
|
|
|
|
|
|
|
for(size_t i = 0; i < threads.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
threads[i] = std::thread(std::bind(&popFrontTester, std::ref(args)));
|
|
|
|
|
LockGuard lock(&args.mutex);
|
|
|
|
|
|
|
|
|
|
args.startCond.wait(lock, [&args, i]() { return args.count == (i + 1); });
|
|
|
|
|
}
|
|
|
|
|
for(size_t i = 0; i < threads.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
threads[i] = std::thread(std::bind(&popFrontTester, std::ref(args)));
|
|
|
|
|
|
|
|
|
|
args.runSignal++;
|
|
|
|
|
args.runCond.notify_all();
|
|
|
|
|
lock.unlock();
|
|
|
|
|
CondArgs cArgs(&args, i + 1);
|
|
|
|
|
args.mutex.Await(absl::Condition(&waitFunc, &cArgs));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
args.runSignal++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(size_t i = 0; i < iterations; ++i)
|
|
|
|
|
{
|
|
|
|
@ -316,27 +326,28 @@ TEST(TestQueue, manyProducerManyConsumer)
|
|
|
|
|
|
|
|
|
|
Args args{iterations};
|
|
|
|
|
|
|
|
|
|
LockGuard lock(args.mutex);
|
|
|
|
|
|
|
|
|
|
for(size_t i = 0; i < numThreads; ++i)
|
|
|
|
|
{
|
|
|
|
|
threads[i] = std::thread(std::bind(&popFrontTester, std::ref(args)));
|
|
|
|
|
LockGuard lock(&args.mutex);
|
|
|
|
|
|
|
|
|
|
args.startCond.wait(lock, [&]() { return args.count == (i + 1); });
|
|
|
|
|
}
|
|
|
|
|
for(size_t i = 0; i < numThreads; ++i)
|
|
|
|
|
{
|
|
|
|
|
threads[i] = std::thread(std::bind(&popFrontTester, std::ref(args)));
|
|
|
|
|
|
|
|
|
|
for(size_t i = 0; i < numThreads; ++i)
|
|
|
|
|
{
|
|
|
|
|
threads[i + numThreads] =
|
|
|
|
|
std::thread(std::bind(&pushBackTester, std::ref(args)));
|
|
|
|
|
CondArgs cArgs(&args, i + 1);
|
|
|
|
|
args.mutex.Await(absl::Condition(+waitFunc, &cArgs));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
args.startCond.wait(lock,
|
|
|
|
|
[&]() { return args.count == (numThreads + i + 1); });
|
|
|
|
|
}
|
|
|
|
|
for(size_t i = 0; i < numThreads; ++i)
|
|
|
|
|
{
|
|
|
|
|
threads[i + numThreads] =
|
|
|
|
|
std::thread(std::bind(&pushBackTester, std::ref(args)));
|
|
|
|
|
|
|
|
|
|
args.runSignal++;
|
|
|
|
|
args.runCond.notify_all();
|
|
|
|
|
lock.unlock();
|
|
|
|
|
CondArgs cArgs(&args, numThreads + i + 1);
|
|
|
|
|
args.mutex.Await(absl::Condition(+waitFunc, &cArgs));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
args.runSignal++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(auto& thread : threads)
|
|
|
|
|
{
|
|
|
|
|