diff options
Diffstat (limited to 'protocols/Telegram/tdlib/td/tdutils/test/MpmcWaiter.cpp')
-rw-r--r-- | protocols/Telegram/tdlib/td/tdutils/test/MpmcWaiter.cpp | 60 |
1 files changed, 43 insertions, 17 deletions
diff --git a/protocols/Telegram/tdlib/td/tdutils/test/MpmcWaiter.cpp b/protocols/Telegram/tdlib/td/tdutils/test/MpmcWaiter.cpp index e27e217713..4ac882dcaf 100644 --- a/protocols/Telegram/tdlib/td/tdutils/test/MpmcWaiter.cpp +++ b/protocols/Telegram/tdlib/td/tdutils/test/MpmcWaiter.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -13,21 +13,22 @@ #include <atomic> #if !TD_THREAD_UNSUPPORTED -TEST(MpmcWaiter, stress_one_one) { +template <class W> +static void test_waiter_stress_one_one() { td::Stage run; td::Stage check; std::vector<td::thread> threads; - std::atomic<size_t> value; + std::atomic<size_t> value{0}; size_t write_cnt = 10; - std::unique_ptr<td::MpmcWaiter> waiter; + td::unique_ptr<W> waiter; size_t threads_n = 2; for (size_t i = 0; i < threads_n; i++) { threads.push_back(td::thread([&, id = static_cast<td::uint32>(i)] { for (td::uint64 round = 1; round < 100000; round++) { if (id == 0) { value = 0; - waiter = std::make_unique<td::MpmcWaiter>(); + waiter = td::make_unique<W>(); write_cnt = td::Random::fast(1, 10); } run.wait(round * threads_n); @@ -37,17 +38,19 @@ TEST(MpmcWaiter, stress_one_one) { waiter->notify(); } } else { - int yields = 0; + typename W::Slot slot; + W::init_slot(slot, id); for (size_t i = 1; i <= write_cnt; i++) { while (true) { auto x = value.load(std::memory_order_relaxed); if (x >= i) { break; } - yields = waiter->wait(yields, id); + waiter->wait(slot); } - yields = waiter->stop_wait(yields, id); + waiter->stop_wait(slot); } + waiter->stop_wait(slot); } check.wait(round * threads_n); } @@ -57,19 +60,29 @@ TEST(MpmcWaiter, stress_one_one) { thread.join(); } } -TEST(MpmcWaiter, stress) { + +TEST(MpmcEagerWaiter, stress_one_one) { + test_waiter_stress_one_one<td::MpmcEagerWaiter>(); +} + +TEST(MpmcSleepyWaiter, stress_one_one) { + test_waiter_stress_one_one<td::MpmcSleepyWaiter>(); +} + +template <class W> +static void test_waiter_stress() { td::Stage run; td::Stage check; std::vector<td::thread> threads; size_t write_n; size_t read_n; - std::atomic<size_t> write_pos; - std::atomic<size_t> read_pos; + std::atomic<size_t> write_pos{0}; + std::atomic<size_t> read_pos{0}; size_t end_pos; size_t write_cnt; size_t threads_n = 20; - std::unique_ptr<td::MpmcWaiter> waiter; + td::unique_ptr<W> waiter; for (size_t i = 0; i < threads_n; i++) { threads.push_back(td::thread([&, id = static_cast<td::uint32>(i)] { for (td::uint64 round = 1; round < 1000; round++) { @@ -80,7 +93,7 @@ TEST(MpmcWaiter, stress) { end_pos = write_n * write_cnt; write_pos = 0; read_pos = 0; - waiter = std::make_unique<td::MpmcWaiter>(); + waiter = td::make_unique<W>(); } run.wait(round * threads_n); if (id <= write_n) { @@ -92,21 +105,26 @@ TEST(MpmcWaiter, stress) { waiter->notify(); } } else if (id > 10 && id - 10 <= read_n) { - int yields = 0; + typename W::Slot slot; + W::init_slot(slot, id); while (true) { auto x = read_pos.load(std::memory_order_relaxed); if (x == end_pos) { + waiter->stop_wait(slot); break; } if (x == write_pos.load(std::memory_order_relaxed)) { - yields = waiter->wait(yields, id); + waiter->wait(slot); continue; } - yields = waiter->stop_wait(yields, id); + waiter->stop_wait(slot); read_pos.compare_exchange_strong(x, x + 1, std::memory_order_relaxed); } } check.wait(round * threads_n); + if (id == 0) { + waiter->close(); + } } })); } @@ -114,4 +132,12 @@ TEST(MpmcWaiter, stress) { thread.join(); } } -#endif // !TD_THREAD_UNSUPPORTED + +TEST(MpmcEagerWaiter, stress_multi) { + test_waiter_stress<td::MpmcEagerWaiter>(); +} + +TEST(MpmcSleepyWaiter, stress_multi) { + test_waiter_stress<td::MpmcSleepyWaiter>(); +} +#endif |