diff --git a/.gitignore b/.gitignore index bf3858f97..46ecf5658 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ build*/ +.build*/ .cache .vscode/* !.vscode/launch.json diff --git a/include/exec/system_context.hpp b/include/exec/system_context.hpp index bb0658719..6feb3a90a 100644 --- a/include/exec/system_context.hpp +++ b/include/exec/system_context.hpp @@ -71,28 +71,8 @@ namespace exec { template class system_bulk_sender; - /// Provides a view on some global underlying execution context supporting parallel forward progress. - class system_context { - public: - /// Initializes the system context with the default implementation. - system_context(); - ~system_context() = default; - - system_context(const system_context&) = delete; - system_context(system_context&&) = delete; - system_context& operator=(const system_context&) = delete; - system_context& operator=(system_context&&) = delete; - - // Returns a scheduler that can add work to the underlying execution context. - system_scheduler get_scheduler(); - - /// Returns the maximum number of threads the context may support; this is just a hint. - size_t max_concurrency() const noexcept; - - private: - /// The actual implementation of the system context. - system_context_replaceability::system_scheduler* __impl_{nullptr}; - }; + /// Returns a scheduler that can add work to the underlying execution context. + system_scheduler get_system_scheduler(); /// The execution domain of the system_scheduler, used for the purposes of customizing /// sender algorithms such as `bulk`. @@ -540,20 +520,13 @@ namespace exec { _Fn __fun_; }; - inline system_context::system_context() { - __impl_ = system_context_replaceability::query_system_context< + inline system_scheduler get_system_scheduler() { + auto __impl = system_context_replaceability::query_system_context< system_context_replaceability::system_scheduler>(); - if (!__impl_) { + if (!__impl) { throw std::runtime_error{"No system context implementation found"}; } - } - - inline system_scheduler system_context::get_scheduler() { - return system_scheduler{__impl_}; - } - - inline size_t system_context::max_concurrency() const noexcept { - return std::thread::hardware_concurrency(); + return system_scheduler{__impl}; } inline auto system_scheduler::query(stdexec::get_forward_progress_guarantee_t) const noexcept diff --git a/test/exec/test_system_context.cpp b/test/exec/test_system_context.cpp index 8f4d6c366..1f8cf42aa 100644 --- a/test/exec/test_system_context.cpp +++ b/test/exec/test_system_context.cpp @@ -33,70 +33,41 @@ namespace ex = stdexec; -TEST_CASE("system_context has default ctor and dtor", "[types][system_scheduler]") { - STATIC_REQUIRE(std::is_default_constructible_v); - STATIC_REQUIRE(std::is_destructible_v); -} - -TEST_CASE("system_context is not copyable nor movable", "[types][system_scheduler]") { - STATIC_REQUIRE_FALSE(std::is_copy_constructible_v); - STATIC_REQUIRE_FALSE(std::is_move_constructible_v); -} - TEST_CASE("system_context can return a scheduler", "[types][system_scheduler]") { - auto sched = exec::system_context{}.get_scheduler(); + auto sched = exec::get_system_scheduler(); STATIC_REQUIRE(ex::scheduler); } -TEST_CASE("can query max concurrency from system_context", "[types][system_scheduler]") { - exec::system_context ctx; - size_t max_concurrency = ctx.max_concurrency(); - REQUIRE(max_concurrency >= 1); -} - TEST_CASE("system scheduler is not default constructible", "[types][system_scheduler]") { - auto sched = exec::system_context{}.get_scheduler(); + auto sched = exec::get_system_scheduler(); using sched_t = decltype(sched); STATIC_REQUIRE(!std::is_default_constructible_v); STATIC_REQUIRE(std::is_destructible_v); } TEST_CASE("system scheduler is copyable and movable", "[types][system_scheduler]") { - auto sched = exec::system_context{}.get_scheduler(); + auto sched = exec::get_system_scheduler(); using sched_t = decltype(sched); STATIC_REQUIRE(std::is_copy_constructible_v); STATIC_REQUIRE(std::is_move_constructible_v); } TEST_CASE("a copied scheduler is equal to the original", "[types][system_scheduler]") { - exec::system_context ctx; - auto sched1 = ctx.get_scheduler(); + auto sched1 = exec::get_system_scheduler(); auto sched2 = sched1; REQUIRE(sched1 == sched2); } TEST_CASE( - "two schedulers obtained from the same system_context are equal", - "[types][system_scheduler]") { - exec::system_context ctx; - auto sched1 = ctx.get_scheduler(); - auto sched2 = ctx.get_scheduler(); - REQUIRE(sched1 == sched2); -} - -TEST_CASE( - "compare two schedulers obtained from different system_context objects", + "two schedulers obtained from get_system_scheduler() are equal", "[types][system_scheduler]") { - exec::system_context ctx1; - auto sched1 = ctx1.get_scheduler(); - exec::system_context ctx2; - auto sched2 = ctx2.get_scheduler(); - // TODO: clarify the result of this in the paper + auto sched1 = exec::get_system_scheduler(); + auto sched2 = exec::get_system_scheduler(); REQUIRE(sched1 == sched2); } TEST_CASE("system scheduler can produce a sender", "[types][system_scheduler]") { - auto snd = ex::schedule(exec::system_context{}.get_scheduler()); + auto snd = ex::schedule(exec::get_system_scheduler()); using sender_t = decltype(snd); STATIC_REQUIRE(ex::sender); @@ -105,8 +76,7 @@ TEST_CASE("system scheduler can produce a sender", "[types][system_scheduler]") } TEST_CASE("trivial schedule task on system context", "[types][system_scheduler]") { - exec::system_context ctx; - exec::system_scheduler sched = ctx.get_scheduler(); + exec::system_scheduler sched = exec::get_system_scheduler(); ex::sync_wait(ex::schedule(sched)); } @@ -114,8 +84,7 @@ TEST_CASE("trivial schedule task on system context", "[types][system_scheduler]" TEST_CASE("simple schedule task on system context", "[types][system_scheduler]") { std::thread::id this_id = std::this_thread::get_id(); std::thread::id pool_id{}; - exec::system_context ctx; - exec::system_scheduler sched = ctx.get_scheduler(); + exec::system_scheduler sched = exec::get_system_scheduler(); auto snd = ex::then(ex::schedule(sched), [&] { pool_id = std::this_thread::get_id(); }); @@ -127,14 +96,12 @@ TEST_CASE("simple schedule task on system context", "[types][system_scheduler]") } TEST_CASE("simple schedule forward progress guarantee", "[types][system_scheduler]") { - exec::system_context ctx; - exec::system_scheduler sched = ctx.get_scheduler(); + exec::system_scheduler sched = exec::get_system_scheduler(); REQUIRE(ex::get_forward_progress_guarantee(sched) == ex::forward_progress_guarantee::parallel); } TEST_CASE("get_completion_scheduler", "[types][system_scheduler]") { - exec::system_context ctx; - exec::system_scheduler sched = ctx.get_scheduler(); + exec::system_scheduler sched = exec::get_system_scheduler(); REQUIRE(ex::get_completion_scheduler(ex::get_env(ex::schedule(sched))) == sched); REQUIRE( ex::get_completion_scheduler(ex::get_env(ex::schedule(sched))) == sched); @@ -144,8 +111,7 @@ TEST_CASE("simple chain task on system context", "[types][system_scheduler]") { std::thread::id this_id = std::this_thread::get_id(); std::thread::id pool_id{}; std::thread::id pool_id2{}; - exec::system_context ctx; - exec::system_scheduler sched = ctx.get_scheduler(); + exec::system_scheduler sched = exec::get_system_scheduler(); auto snd = ex::then(ex::schedule(sched), [&] { pool_id = std::this_thread::get_id(); }); auto snd2 = ex::then(std::move(snd), [&] { pool_id2 = std::this_thread::get_id(); }); @@ -161,8 +127,7 @@ TEST_CASE("simple chain task on system context", "[types][system_scheduler]") { // TODO: fix this test. This also makes tsan and asan unhappy. // TEST_CASE("checks stop_token before starting the work", "[types][system_scheduler]") { -// exec::system_context ctx; -// exec::system_scheduler sched = ctx.get_scheduler(); +// exec::system_scheduler sched = exec::get_system_scheduler(); // exec::async_scope scope; // scope.request_stop(); @@ -185,8 +150,7 @@ TEST_CASE("simple bulk task on system context", "[types][system_scheduler]") { std::thread::id this_id = std::this_thread::get_id(); constexpr size_t num_tasks = 16; std::thread::id pool_ids[num_tasks]; - exec::system_context ctx; - exec::system_scheduler sched = ctx.get_scheduler(); + exec::system_scheduler sched = exec::get_system_scheduler(); auto bulk_snd = ex::bulk(ex::schedule(sched), num_tasks, [&](unsigned long id) { pool_ids[id] = std::this_thread::get_id(); @@ -207,8 +171,7 @@ TEST_CASE("simple bulk chaining on system context", "[types][system_scheduler]") std::thread::id pool_id{}; std::thread::id propagated_pool_ids[num_tasks]; std::thread::id pool_ids[num_tasks]; - exec::system_context ctx; - exec::system_scheduler sched = ctx.get_scheduler(); + exec::system_scheduler sched = exec::get_system_scheduler(); auto snd = ex::then(ex::schedule(sched), [&] { pool_id = std::this_thread::get_id(); @@ -268,8 +231,7 @@ TEST_CASE("can change the implementation of system context", "[types][system_sch std::thread::id this_id = std::this_thread::get_id(); std::thread::id pool_id{}; - exec::system_context ctx; - exec::system_scheduler sched = ctx.get_scheduler(); + exec::system_scheduler sched = exec::get_system_scheduler(); auto snd = ex::then(ex::schedule(sched), [&] { pool_id = std::this_thread::get_id(); }); diff --git a/test/exec/test_system_context_replaceability.cpp b/test/exec/test_system_context_replaceability.cpp index 10553c741..5b76ec9b6 100644 --- a/test/exec/test_system_context_replaceability.cpp +++ b/test/exec/test_system_context_replaceability.cpp @@ -58,8 +58,7 @@ TEST_CASE( "[system_scheduler][replaceability]") { std::thread::id this_id = std::this_thread::get_id(); std::thread::id pool_id{}; - exec::system_context ctx; - exec::system_scheduler sched = ctx.get_scheduler(); + exec::system_scheduler sched = exec::get_system_scheduler(); auto snd = ex::then(ex::schedule(sched), [&] { pool_id = std::this_thread::get_id(); });