From 4cf60b99d6d33b469486c095cedf9b53c29c9e9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Kardos?= Date: Mon, 3 Jun 2024 12:35:45 +0200 Subject: [PATCH] export dll symbols --- include/asyncpp/testing/interleaver.hpp | 10 +++++----- src/CMakeLists.txt | 4 +++- src/testing/interleaver.cpp | 20 ++++++++------------ test/testing/test_interleaver.cpp | 16 ++++++++-------- 4 files changed, 24 insertions(+), 26 deletions(-) diff --git a/include/asyncpp/testing/interleaver.hpp b/include/asyncpp/testing/interleaver.hpp index d068e2e..690ea38 100644 --- a/include/asyncpp/testing/interleaver.hpp +++ b/include/asyncpp/testing/interleaver.hpp @@ -49,9 +49,9 @@ struct thread_state { return thread_state{ static_cast(reinterpret_cast(&sp)) }; } - static constinit const thread_state running; - static constinit const thread_state blocked; - static constinit const thread_state completed; + static constexpr thread_state running() { return thread_state{ code::running }; } + static constexpr thread_state blocked() { return thread_state{ code::blocked }; } + static constexpr thread_state completed() { return thread_state{ code::completed }; } code value = code::running; }; @@ -68,7 +68,7 @@ class thread { initialize_this_thread(); INTERLEAVED("initial_point"); func(std::forward(args_)...); - m_content->state.store(thread_state::completed); + m_content->state.store(thread_state::completed()); }; m_content->thread = std::jthread(wrapper, std::forward(args)...); } @@ -84,7 +84,7 @@ class thread { private: struct content { std::jthread thread; - std::atomic state = thread_state::running; + std::atomic state = thread_state::running(); }; std::unique_ptr m_content = std::make_unique(); static thread_local thread* current_thread; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e013054..daf2536 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,4 +10,6 @@ target_sources(asyncpp semaphore.cpp ) -target_link_libraries(asyncpp asyncpp-headers) \ No newline at end of file +target_link_libraries(asyncpp asyncpp-headers) + +set_target_properties(asyncpp PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) \ No newline at end of file diff --git a/src/testing/interleaver.cpp b/src/testing/interleaver.cpp index 4982372..b46580f 100644 --- a/src/testing/interleaver.cpp +++ b/src/testing/interleaver.cpp @@ -13,10 +13,6 @@ namespace asyncpp::testing { -constinit const thread_state thread_state::running = thread_state{ code::running }; -constinit const thread_state thread_state::blocked = thread_state{ code::blocked }; -constinit const thread_state thread_state::completed = thread_state{ code::completed }; - static_assert(std::atomic::is_always_lock_free); thread_local thread* thread::current_thread = nullptr; @@ -33,7 +29,7 @@ void thread::resume() { const auto current_state = m_content->state.load(); const auto current_suspension_point = current_state.get_suspension_point(); assert(current_suspension_point && "thread must be suspended at a suspension point"); - const auto next_state = current_suspension_point->acquire ? thread_state::blocked : thread_state::running; + const auto next_state = current_suspension_point->acquire ? thread_state::blocked() : thread_state::running(); m_content->state.store(next_state); } @@ -52,7 +48,7 @@ thread_state thread::get_state() const { void thread::suspend(const suspension_point& sp) { const auto prev_state = m_content->state.exchange(thread_state::suspended(sp)); - assert(prev_state == thread_state::running || prev_state == thread_state::blocked); + assert(prev_state == thread_state::running() || prev_state == thread_state::blocked()); while (m_content->state.load().is_suspended()) { // Wait. } @@ -101,13 +97,13 @@ tree::stable_node& tree::previous(transition_node& node) { std::string dump(const swarm_state& state) { std::stringstream ss; for (const auto& th : state.thread_states) { - if (th == thread_state::completed) { + if (th == thread_state::completed()) { ss << "completed"; } - else if (th == thread_state::blocked) { + else if (th == thread_state::blocked()) { ss << "blocked"; } - else if (th == thread_state::running) { + else if (th == thread_state::running()) { ss << "running"; } else { @@ -206,7 +202,7 @@ bool is_stable(const std::vector& states) { bool is_unblocked(const std::vector& states) { - const auto num_blocked = std::ranges::count_if(states, [](const auto& state) { return state == thread_state::blocked; }); + const auto num_blocked = std::ranges::count_if(states, [](const auto& state) { return state == thread_state::blocked(); }); const auto num_suspended = std::ranges::count_if(states, [](const auto& state) { return state.is_suspended(); }); if (num_blocked != 0) { return num_suspended != 0; @@ -249,7 +245,7 @@ bool is_transitively_complete(const tree& tree, const tree::stable_node& node) { completed_paths.resize(swarm.thread_states.size(), false); for (size_t resumed = 0; resumed < swarm.thread_states.size(); ++resumed) { const auto& ts = swarm.thread_states[resumed]; - if (ts == thread_state::completed || ts == thread_state::blocked) { + if (ts == thread_state::completed() || ts == thread_state::blocked()) { completed_paths[resumed] = true; } } @@ -287,7 +283,7 @@ path run_next_interleaving(tree& tree, std::span> swarm) try { const auto state = swarm_state(stabilize(swarm)); path.steps.push_back({ state, -1 }); - if (std::ranges::all_of(state.thread_states, [](const auto& ts) { return ts == thread_state::completed; })) { + if (std::ranges::all_of(state.thread_states, [](const auto& ts) { return ts == thread_state::completed(); })) { break; } for (size_t thread_idx = 0; thread_idx < swarm.size(); ++thread_idx) { diff --git a/test/testing/test_interleaver.cpp b/test/testing/test_interleaver.cpp index be474cc..55c1f61 100644 --- a/test/testing/test_interleaver.cpp +++ b/test/testing/test_interleaver.cpp @@ -84,8 +84,8 @@ TEST_CASE("Interleaver - next from transition node", "[Interleaver]") { TEST_CASE("Interleaver - is transitively complete", "[Interleaver]") { const std::vector initial = { thread_state::suspended(p1) }; - const std::vector final = { thread_state::completed }; - const std::vector blocked = { thread_state::blocked }; + const std::vector final = { thread_state::completed() }; + const std::vector blocked = { thread_state::blocked() }; SECTION("empty root node") { tree t; @@ -118,7 +118,7 @@ TEST_CASE("Interleaver - is transitively complete", "[Interleaver]") { TEST_CASE("Interleaver - mark complete", "[Interleaver]") { const std::vector at_p1 = { thread_state::suspended(p1) }; const std::vector at_p2 = { thread_state::suspended(p2) }; - const std::vector final = { thread_state::completed }; + const std::vector final = { thread_state::completed() }; tree t; auto& n1 = t.root(); @@ -136,11 +136,11 @@ TEST_CASE("Interleaver - mark complete", "[Interleaver]") { TEST_CASE("Interleaver - select resumed", "[Interleaver]") { const std::vector initial = { thread_state::suspended(p3), thread_state::suspended(p3) }; const std::vector both_ready = { thread_state::suspended(p1), thread_state::suspended(p1) }; - const std::vector left_ready = { thread_state::suspended(p1), thread_state::completed }; - const std::vector right_ready = { thread_state::completed, thread_state::suspended(p1) }; - const std::vector none_ready = { thread_state::completed, thread_state::completed }; - const std::vector left_blocked = { thread_state::blocked, thread_state::suspended(p1) }; - const std::vector right_blocked = { thread_state::suspended(p1), thread_state::blocked }; + const std::vector left_ready = { thread_state::suspended(p1), thread_state::completed() }; + const std::vector right_ready = { thread_state::completed(), thread_state::suspended(p1) }; + const std::vector none_ready = { thread_state::completed(), thread_state::completed() }; + const std::vector left_blocked = { thread_state::blocked(), thread_state::suspended(p1) }; + const std::vector right_blocked = { thread_state::suspended(p1), thread_state::blocked() }; tree t; auto& transition = t.next(t.root(), swarm_state(initial));