From bb67bd9ddc670a8697c6798bf98bdaf1ed801804 Mon Sep 17 00:00:00 2001 From: mutouyun Date: Wed, 5 Apr 2023 15:31:21 +0800 Subject: [PATCH] upd: [concur] context => header --- include/libconcur/concurrent.h | 98 +++++++++++++------------- test/concur/test_concur_concurrent.cpp | 88 +++++++++++------------ 2 files changed, 93 insertions(+), 93 deletions(-) diff --git a/include/libconcur/concurrent.h b/include/libconcur/concurrent.h index 10a9d88..cbc7169 100644 --- a/include/libconcur/concurrent.h +++ b/include/libconcur/concurrent.h @@ -44,26 +44,26 @@ class broadcast {}; /// \brief Determines whether type T can be implicitly converted to type U. template -using is_convertible = typename std::enable_if::value>::type; +using is_convertible = std::enable_if_t::value, bool>; -/// \brief Check whether the context type is valid. +/// \brief Check whether the elems header type is valid. template -using is_context = decltype(typename std::enable_if().valid()), bool>::value>::type(), - std::declval() % std::declval().circ_size); +using is_elems_header = decltype( + std::declval() % std::declval().circ_size, + std::enable_if_t().valid()), bool>::value, bool>{}); /** * \brief Calculate the corresponding queue position modulo the index value. * - * \tparam C a context type - * \param ctx a context object - * \param idx a context array index + * \tparam H a elems header type + * \param hdr a elems header object + * \param idx a elems array index * \return index_t - a corresponding queue position */ -template > -constexpr index_t trunc_index(C const &ctx, index_t idx) noexcept { +template = true> +constexpr index_t trunc_index(H const &hdr, index_t idx) noexcept { // `circ_size == 2^N` => `idx & (circ_size - 1)` - return ctx.valid() ? (idx % ctx.circ_size) : 0; + return hdr.valid() ? (idx % hdr.circ_size) : 0; } /// \brief Producer algorithm implementation. @@ -86,17 +86,17 @@ struct consumer; template <> struct producer { - struct context_impl { + struct header_impl { index_t w_idx {0}; ///< write index private: padding ___; }; - template , - typename = is_convertible> - static bool enqueue(::LIBIMP::span> elems, C &ctx, U &&src) noexcept { - auto w_idx = ctx.w_idx; - auto w_cur = trunc_index(ctx, w_idx); + template = true, + is_convertible = true> + static bool enqueue(::LIBIMP::span> elems, H &hdr, U &&src) noexcept { + auto w_idx = hdr.w_idx; + auto w_cur = trunc_index(hdr, w_idx); auto &elem = elems[w_cur]; auto f_ct = elem.get_flag(); // Verify index. @@ -105,7 +105,7 @@ struct producer { return false; // full } // Get a valid index and iterate backwards. - ctx.w_idx += 1; + hdr.w_idx += 1; // Set data & flag. elem.set_data(std::forward(src)); elem.set_flag(static_cast(~w_idx)); @@ -117,18 +117,18 @@ struct producer { template <> struct producer { - struct context_impl { + struct header_impl { std::atomic w_idx {0}; ///< write index private: padding ___; }; - template , - typename = is_convertible> - static bool enqueue(::LIBIMP::span> elems, C &ctx, U &&src) noexcept { - auto w_idx = ctx.w_idx.load(std::memory_order_acquire); + template = true, + is_convertible = true> + static bool enqueue(::LIBIMP::span> elems, H &hdr, U &&src) noexcept { + auto w_idx = hdr.w_idx.load(std::memory_order_acquire); for (;;) { - auto w_cur = trunc_index(ctx, w_idx); + auto w_cur = trunc_index(hdr, w_idx); auto &elem = elems[w_cur]; auto f_ct = elem.get_flag(); // Verify index. @@ -137,7 +137,7 @@ struct producer { return false; // full } // Get a valid index and iterate backwards. - if (!ctx.w_idx.compare_exchange_weak(w_idx, w_idx + 1, std::memory_order_acq_rel)) { + if (!hdr.w_idx.compare_exchange_weak(w_idx, w_idx + 1, std::memory_order_acq_rel)) { continue; } // Set data & flag. @@ -152,17 +152,17 @@ struct producer { template <> struct consumer { - struct context_impl { + struct header_impl { index_t r_idx {0}; ///< read index private: padding ___; }; - template , - typename = is_convertible> - static bool dequeue(::LIBIMP::span> elems, C &ctx, U &des) noexcept { - auto r_idx = ctx.r_idx; - auto r_cur = trunc_index(ctx, r_idx); + template = true, + is_convertible = true> + static bool dequeue(::LIBIMP::span> elems, H &hdr, U &des) noexcept { + auto r_idx = hdr.r_idx; + auto r_cur = trunc_index(hdr, r_idx); auto &elem = elems[r_cur]; auto f_ct = elem.get_flag(); // Verify index. @@ -170,7 +170,7 @@ struct consumer { return false; // empty } // Get a valid index and iterate backwards. - ctx.r_idx += 1; + hdr.r_idx += 1; // Get data & set flag. des = LIBCONCUR::get(elem); elem.set_flag(r_idx + static_cast(elems.size())/*avoid overflow*/); @@ -182,18 +182,18 @@ struct consumer { template <> struct consumer { - struct context_impl { + struct header_impl { std::atomic r_idx {0}; ///< read index private: padding ___; }; - template , - typename = is_convertible> - static bool dequeue(::LIBIMP::span> elems, C &ctx, U &des) noexcept { - auto r_idx = ctx.r_idx.load(std::memory_order_acquire); + template = true, + is_convertible = true> + static bool dequeue(::LIBIMP::span> elems, H &hdr, U &des) noexcept { + auto r_idx = hdr.r_idx.load(std::memory_order_acquire); for (;;) { - auto r_cur = trunc_index(ctx, r_idx); + auto r_cur = trunc_index(hdr, r_idx); auto &elem = elems[r_cur]; auto f_ct = elem.get_flag(); // Verify index. @@ -201,7 +201,7 @@ struct consumer { return false; // empty } // Get a valid index and iterate backwards. - if (!ctx.r_idx.compare_exchange_weak(r_idx, r_idx + 1, std::memory_order_acq_rel)) { + if (!hdr.r_idx.compare_exchange_weak(r_idx, r_idx + 1, std::memory_order_acq_rel)) { continue; } // Get data & set flag. @@ -227,7 +227,7 @@ struct producer { }; /// \brief Multi-read consumer model implementation. -// Single-read consumer model is not required. +/// Single-read consumer model is not required. template <> struct consumer { }; @@ -243,16 +243,16 @@ template struct prod_cons : producer , consumer { - /// \brief Mixing producer and consumer context definitions. - struct context : producer::context_impl - , consumer::context_impl { + /// \brief Mixing producer and consumer header definitions. + struct header : producer::header_impl + , consumer::header_impl { index_t const circ_size; - constexpr context(index_t cs) noexcept + constexpr header(index_t cs) noexcept : circ_size(cs) {} template - constexpr context(::LIBIMP::span> elems) noexcept + constexpr header(::LIBIMP::span> elems) noexcept : circ_size(static_cast(elems.size())) {} constexpr bool valid() const noexcept { diff --git a/test/concur/test_concur_concurrent.cpp b/test/concur/test_concur_concurrent.cpp index 6c43930..e32d7a8 100644 --- a/test/concur/test_concur_concurrent.cpp +++ b/test/concur/test_concur_concurrent.cpp @@ -23,7 +23,7 @@ TEST(concurrent, index_and_flag) { } TEST(concurrent, trunc_index) { - struct context { + struct header { concur::index_t circ_size; bool valid() const noexcept { @@ -32,60 +32,60 @@ TEST(concurrent, trunc_index) { }; /// @brief circ-size = 0 - EXPECT_EQ(concur::trunc_index(context{0}, 0), 0); - EXPECT_EQ(concur::trunc_index(context{0}, 1), 0); - EXPECT_EQ(concur::trunc_index(context{0}, 2), 0); - EXPECT_EQ(concur::trunc_index(context{0}, 16), 0); - EXPECT_EQ(concur::trunc_index(context{0}, 111), 0); - EXPECT_EQ(concur::trunc_index(context{0}, -1), 0); + EXPECT_EQ(concur::trunc_index(header{0}, 0), 0); + EXPECT_EQ(concur::trunc_index(header{0}, 1), 0); + EXPECT_EQ(concur::trunc_index(header{0}, 2), 0); + EXPECT_EQ(concur::trunc_index(header{0}, 16), 0); + EXPECT_EQ(concur::trunc_index(header{0}, 111), 0); + EXPECT_EQ(concur::trunc_index(header{0}, -1), 0); /// @brief circ-size = 1 - EXPECT_EQ(concur::trunc_index(context{1}, 0), 0); - EXPECT_EQ(concur::trunc_index(context{1}, 1), 0); - EXPECT_EQ(concur::trunc_index(context{1}, 2), 0); - EXPECT_EQ(concur::trunc_index(context{1}, 16), 0); - EXPECT_EQ(concur::trunc_index(context{1}, 111), 0); - EXPECT_EQ(concur::trunc_index(context{1}, -1), 0); + EXPECT_EQ(concur::trunc_index(header{1}, 0), 0); + EXPECT_EQ(concur::trunc_index(header{1}, 1), 0); + EXPECT_EQ(concur::trunc_index(header{1}, 2), 0); + EXPECT_EQ(concur::trunc_index(header{1}, 16), 0); + EXPECT_EQ(concur::trunc_index(header{1}, 111), 0); + EXPECT_EQ(concur::trunc_index(header{1}, -1), 0); /// @brief circ-size = 2 - EXPECT_EQ(concur::trunc_index(context{2}, 0), 0); - EXPECT_EQ(concur::trunc_index(context{2}, 1), 1); - EXPECT_EQ(concur::trunc_index(context{2}, 2), 0); - EXPECT_EQ(concur::trunc_index(context{2}, 16), 0); - EXPECT_EQ(concur::trunc_index(context{2}, 111), 1); - EXPECT_EQ(concur::trunc_index(context{2}, -1), 1); + EXPECT_EQ(concur::trunc_index(header{2}, 0), 0); + EXPECT_EQ(concur::trunc_index(header{2}, 1), 1); + EXPECT_EQ(concur::trunc_index(header{2}, 2), 0); + EXPECT_EQ(concur::trunc_index(header{2}, 16), 0); + EXPECT_EQ(concur::trunc_index(header{2}, 111), 1); + EXPECT_EQ(concur::trunc_index(header{2}, -1), 1); /// @brief circ-size = 10 - EXPECT_EQ(concur::trunc_index(context{10}, 0), 0); - EXPECT_EQ(concur::trunc_index(context{10}, 1), 0); - EXPECT_EQ(concur::trunc_index(context{10}, 2), 0); - EXPECT_EQ(concur::trunc_index(context{10}, 16), 0); - EXPECT_EQ(concur::trunc_index(context{10}, 111), 0); - EXPECT_EQ(concur::trunc_index(context{10}, -1), 0); + EXPECT_EQ(concur::trunc_index(header{10}, 0), 0); + EXPECT_EQ(concur::trunc_index(header{10}, 1), 0); + EXPECT_EQ(concur::trunc_index(header{10}, 2), 0); + EXPECT_EQ(concur::trunc_index(header{10}, 16), 0); + EXPECT_EQ(concur::trunc_index(header{10}, 111), 0); + EXPECT_EQ(concur::trunc_index(header{10}, -1), 0); /// @brief circ-size = 16 - EXPECT_EQ(concur::trunc_index(context{16}, 0), 0); - EXPECT_EQ(concur::trunc_index(context{16}, 1), 1); - EXPECT_EQ(concur::trunc_index(context{16}, 2), 2); - EXPECT_EQ(concur::trunc_index(context{16}, 16), 0); - EXPECT_EQ(concur::trunc_index(context{16}, 111), 15); - EXPECT_EQ(concur::trunc_index(context{16}, -1), 15); + EXPECT_EQ(concur::trunc_index(header{16}, 0), 0); + EXPECT_EQ(concur::trunc_index(header{16}, 1), 1); + EXPECT_EQ(concur::trunc_index(header{16}, 2), 2); + EXPECT_EQ(concur::trunc_index(header{16}, 16), 0); + EXPECT_EQ(concur::trunc_index(header{16}, 111), 15); + EXPECT_EQ(concur::trunc_index(header{16}, -1), 15); /// @brief circ-size = (index_t)-1 - EXPECT_EQ(concur::trunc_index(context{(concur::index_t)-1}, 0), 0); - EXPECT_EQ(concur::trunc_index(context{(concur::index_t)-1}, 1), 0); - EXPECT_EQ(concur::trunc_index(context{(concur::index_t)-1}, 2), 0); - EXPECT_EQ(concur::trunc_index(context{(concur::index_t)-1}, 16), 0); - EXPECT_EQ(concur::trunc_index(context{(concur::index_t)-1}, 111), 0); - EXPECT_EQ(concur::trunc_index(context{(concur::index_t)-1}, -1), 0); + EXPECT_EQ(concur::trunc_index(header{(concur::index_t)-1}, 0), 0); + EXPECT_EQ(concur::trunc_index(header{(concur::index_t)-1}, 1), 0); + EXPECT_EQ(concur::trunc_index(header{(concur::index_t)-1}, 2), 0); + EXPECT_EQ(concur::trunc_index(header{(concur::index_t)-1}, 16), 0); + EXPECT_EQ(concur::trunc_index(header{(concur::index_t)-1}, 111), 0); + EXPECT_EQ(concur::trunc_index(header{(concur::index_t)-1}, -1), 0); /// @brief circ-size = 2147483648 (2^31) - EXPECT_EQ(concur::trunc_index(context{2147483648u}, 0), 0); - EXPECT_EQ(concur::trunc_index(context{2147483648u}, 1), 1); - EXPECT_EQ(concur::trunc_index(context{2147483648u}, 2), 2); - EXPECT_EQ(concur::trunc_index(context{2147483648u}, 16), 16); - EXPECT_EQ(concur::trunc_index(context{2147483648u}, 111), 111); - EXPECT_EQ(concur::trunc_index(context{2147483648u}, -1), 2147483647); + EXPECT_EQ(concur::trunc_index(header{2147483648u}, 0), 0); + EXPECT_EQ(concur::trunc_index(header{2147483648u}, 1), 1); + EXPECT_EQ(concur::trunc_index(header{2147483648u}, 2), 2); + EXPECT_EQ(concur::trunc_index(header{2147483648u}, 16), 16); + EXPECT_EQ(concur::trunc_index(header{2147483648u}, 111), 111); + EXPECT_EQ(concur::trunc_index(header{2147483648u}, -1), 2147483647); } namespace { @@ -99,7 +99,7 @@ void test_concur(std::size_t np, std::size_t nc, std::size_t k) { concur::element circ[32] {}; PC pc; - typename PC::context ctx {imp::make_span(circ)}; + typename PC::header ctx {imp::make_span(circ)}; ASSERT_TRUE(ctx.valid()); std::atomic sum {0};