10#include <QtConcurrentRun>
22 void CoroChannelTest::testSingleRecv ()
24 using namespace std::chrono_literals;
26 constexpr auto producersCount = 32;
27 constexpr auto repCount = 100;
28 constexpr auto sleepLength = 1ms;
30 Channel<int> ch {
this };
32 std::vector<std::thread> threads;
33 std::atomic_int expected;
34 for (
int i = 0; i < producersCount; ++i)
35 threads.emplace_back ([&, i]
37 for (int j = 0; j < repCount; ++j)
39 const auto val = j * producersCount + i;
41 expected.fetch_add (val, std::memory_order::relaxed);
42 std::this_thread::sleep_for (sleepLength);
46 auto mainThread = std::this_thread::get_id ();
50 while (
auto next =
co_await ch->Receive ())
54 auto thisThread = std::this_thread::get_id ();
55 QCOMPARE (thisThread, mainThread);
63 for (
auto& thread : threads)
69 QCOMPARE (result, expected);
72 void CoroChannelTest::testManyRecvs ()
74 using namespace std::chrono_literals;
76 constexpr auto producersCount = 32;
77 constexpr auto consumersCount = 8;
78 constexpr auto repCount = 100;
79 constexpr auto sleepLength = 1ms;
83 std::vector<std::thread> producers;
84 std::atomic_int expected;
85 for (
int i = 0; i < producersCount; ++i)
86 producers.emplace_back ([&, i]
88 for (int j = 0; j < repCount; ++j)
90 const auto val = j * producersCount + i;
92 expected.fetch_add (val, std::memory_order::relaxed);
93 std::this_thread::sleep_for (sleepLength);
98 std::vector<std::thread> consumers;
99 for (
int i = 0; i < consumersCount; ++i)
100 consumers.emplace_back ([&]
102 auto reader = [] (Channel<int> *ch) -> Task<int, ThreadSafetyExtension>
105 while (auto next = co_await ch->Receive ())
112 for (
auto& thread : producers)
117 for (
auto& thread : consumers)
120 QCOMPARE (sum, expected);
123 void CoroChannelTest::testSingleThreaded ()
125 constexpr auto iterations = 1000;
129 auto reader = [] (Channel<int> *ch) -> Task<int, ThreadSafetyExtension>
132 while (
auto next =
co_await ch->Receive ())
138 for (
int i = 0; i < iterations; ++i)
147 QCOMPARE (result, expected);
150 void CoroChannelTest::testSingleThreadedTimered ()
152 using namespace std::chrono_literals;
154 constexpr auto iterations = 100;
155 constexpr auto interval = 1ms;
159 auto reader = [] (Channel<int> *ch) -> Task<int, ThreadSafetyExtension>
162 while (
auto next =
co_await ch->Receive ())
170 timer.callOnTimeout ([&, i = 0]
mutable
174 if (++i == iterations)
180 timer.start (interval);
183 QCOMPARE (result, expected);
186 void CoroChannelTest::testMerge ()
188 using namespace std::chrono_literals;
190 constexpr auto numChannels = 100;
191 constexpr auto iterations = 100;
192 constexpr auto interval = 1ms;
194 QVector<Channel_ptr<int>> channels;
195 std::generate_n (std::back_inserter (channels), numChannels, [] {
return std::make_shared<Channel<int>> (); });
199 auto reader = [] (Channel<int> *ch) -> Task<int, ThreadSafetyExtension>
202 while (
auto next =
co_await ch->Receive ())
210 timer.callOnTimeout ([&, i = 0]
mutable
212 for (
int j = 0; j < numChannels; ++j)
214 auto value = i * numChannels + j;
216 channels [j]->Send (value);
218 if (++i == iterations)
221 for (
auto chan : channels)
225 timer.start (interval);
228 QCOMPARE (result, expected);
T GetTaskResult(Task< T, Extensions... > task)
Channel_ptr< T > MergeChannels(QVector< Channel_ptr< T > > channels)