From f6af39419523d8287b0508303bc30f293401af71 Mon Sep 17 00:00:00 2001 From: mutouyun Date: Sun, 28 May 2023 13:54:29 +0800 Subject: [PATCH] add: basic mt ut for queue --- include/libimp/nameof.h | 3 +- test/concur/test_concur_queue.cpp | 78 ++++++++++++++++++++++++++++++- 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/include/libimp/nameof.h b/include/libimp/nameof.h index 0e1396d..dded0c3 100644 --- a/include/libimp/nameof.h +++ b/include/libimp/nameof.h @@ -11,6 +11,7 @@ #include #include "libimp/def.h" +#include "libimp/export.h" #include "libimp/span.h" LIBIMP_NAMESPACE_BEG_ @@ -22,7 +23,7 @@ LIBIMP_NAMESPACE_BEG_ * \param name the mangled name * \return std::string a human-readable demangled type name */ -std::string demangle(span name) noexcept; +LIBIMP_EXPORT std::string demangle(span name) noexcept; /** * \brief Returns an implementation defined string containing the name of the type. diff --git a/test/concur/test_concur_queue.cpp b/test/concur/test_concur_queue.cpp index 367f2dc..d01261a 100644 --- a/test/concur/test_concur_queue.cpp +++ b/test/concur/test_concur_queue.cpp @@ -1,8 +1,14 @@ +#include +#include +#include +#include + #include "gtest/gtest.h" #include "libconcur/queue.h" #include "libimp/log.h" +#include "libimp/nameof.h" using namespace concur; @@ -78,7 +84,77 @@ namespace { template void test_queue(std::size_t np, std::size_t nc) { LIBIMP_LOG_(); + log.info("\n\tStart with: [", imp::nameof(), " - ", imp::nameof(), "]\n\t\t", np, " producers, ", nc, " consumers..."); + struct Data { + std::uint64_t n; + std::uint64_t i; + }; + queue que; + + constexpr static std::uint32_t loop_size = 10'0000; + + std::atomic sum {0}; + std::atomic running {np}; + + auto prod_call = [&](std::size_t n) { + for (std::uint32_t i = 1; i <= loop_size; ++i) { + std::this_thread::yield(); + for (std::uint32_t k = 1; !que.push(Data{n, i}); ++k) { + std::this_thread::yield(); + if (k % (loop_size / 10) == 0) { + log.info("[", n, "] put count: ", i, ", retry: ", k); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + } + if (i % (loop_size / 10) == 0) { + log.info("[", n, "] put count: ", i); + } + } + --running; + }; + auto cons_call = [&] { + for (;;) { + std::this_thread::yield(); + Data v; + while (!que.pop(v)) { + if (running == 0) return; + std::this_thread::yield(); + } + sum += v.i; + } + }; + + std::vector prods(np); + for (std::size_t n = 0; n < np; ++n) prods[n] = std::thread(prod_call, n); + std::vector conss(nc); + for (auto &c : conss) c = std::thread(cons_call); + + for (auto &p : prods) p.join(); + for (auto &c : conss) c.join(); + + EXPECT_EQ(sum, np * (loop_size * std::uint64_t(loop_size + 1)) / 2); } -} // namespace \ No newline at end of file +} // namespace + +TEST(queue, multi_thread) { + using namespace concur; + + /// \brief 1-1 + test_queue(1, 1); + test_queue(1, 1); + test_queue(1, 1); + test_queue(1, 1); + + /// \brief 8-1 + test_queue(8, 1); + test_queue(8, 1); + + /// \brief 1-8 + test_queue(1, 8); + test_queue(1, 8); + + /// \brief 8-8 + test_queue(8, 8); +}