From c96d64e5baff7d518361622b67b6fc9bf4fbf0b6 Mon Sep 17 00:00:00 2001 From: q66 Date: Fri, 24 Mar 2017 15:18:41 +0100 Subject: [PATCH] remove the scheduler iface nonsense (just make a virtual base) --- ostd/concurrency.hh | 136 +++++++++++++------------------------------- src/concurrency.cc | 2 +- 2 files changed, 39 insertions(+), 99 deletions(-) diff --git a/ostd/concurrency.hh b/ostd/concurrency.hh index 474b863..7c64046 100644 --- a/ostd/concurrency.hh +++ b/ostd/concurrency.hh @@ -19,105 +19,45 @@ namespace ostd { +struct scheduler { + scheduler() {} + + scheduler(scheduler const &) = delete; + scheduler(scheduler &&) = delete; + scheduler &operator=(scheduler const &) = delete; + scheduler &operator=(scheduler &&) = delete; + + virtual void spawn(std::function) = 0; + virtual void yield() = 0; + virtual generic_condvar make_condition() = 0; +}; + namespace detail { - struct sched_iface_base { - sched_iface_base() {} - virtual ~sched_iface_base() {} + OSTD_EXPORT extern scheduler *current_scheduler; - virtual void spawn(std::function &&func) = 0; - virtual void yield() = 0; - virtual generic_condvar make_condition() = 0; - }; - - template - struct sched_iface_impl final: sched_iface_base { - sched_iface_impl(S &sched): p_sched(&sched) {} - - virtual void spawn(std::function &&func) { - p_sched->spawn(std::move(func)); - } - virtual void yield() { - p_sched->yield(); - } - virtual generic_condvar make_condition() { - return p_sched->make_condition(); - } - private: - S *p_sched; - }; - - struct sched_iface { - sched_iface() {} + struct current_scheduler_owner { + current_scheduler_owner() = delete; template - void set(S &sched) { - if (p_curr) { - p_curr->~sched_iface_base(); - } - new (reinterpret_cast(&p_buf)) - sched_iface_impl(sched); - p_curr = reinterpret_cast(&p_buf); + current_scheduler_owner(S &sched) { + current_scheduler = &sched; } - void unset() { - if (p_curr) { - p_curr->~sched_iface_base(); - p_curr = nullptr; - } - } + current_scheduler_owner(current_scheduler_owner const &) = delete; + current_scheduler_owner(current_scheduler_owner &&) = delete; + current_scheduler_owner &operator=(current_scheduler_owner const &) = delete; + current_scheduler_owner &operator=(current_scheduler_owner &&) = delete; - ~sched_iface() { - unset(); - } - - sched_iface(sched_iface const &) = delete; - sched_iface(sched_iface &&) = delete; - sched_iface &operator=(sched_iface const &) = delete; - sched_iface &operator=(sched_iface &&) = delete; - - void spawn(std::function &&func) { - p_curr->spawn(std::move(func)); - } - void yield() { - p_curr->yield(); - } - generic_condvar make_condition() { - return p_curr->make_condition(); - } - - private: - std::aligned_storage_t< - sizeof(detail::sched_iface_impl), - alignof(detail::sched_iface_impl) - > p_buf; - sched_iface_base *p_curr = nullptr; - }; - - OSTD_EXPORT extern sched_iface current_sched_iface; - - struct sched_iface_owner { - sched_iface_owner() = delete; - - template - sched_iface_owner(S &sched) { - current_sched_iface.set(sched); - } - - sched_iface_owner(sched_iface_owner const &) = delete; - sched_iface_owner(sched_iface_owner &&) = delete; - sched_iface_owner &operator=(sched_iface_owner const &) = delete; - sched_iface_owner &operator=(sched_iface_owner &&) = delete; - - ~sched_iface_owner() { - current_sched_iface.unset(); + ~current_scheduler_owner() { + current_scheduler = nullptr; } }; } -struct thread_scheduler { +struct thread_scheduler: scheduler { template auto start(F &&func, A &&...args) -> std::result_of_t { - detail::sched_iface_owner iface{*this}; + detail::current_scheduler_owner iface{*this}; if constexpr(std::is_same_v, void>) { func(std::forward(args)...); join_all(); @@ -230,7 +170,7 @@ namespace detail { } template -struct basic_simple_coroutine_scheduler { +struct basic_simple_coroutine_scheduler: scheduler { private: /* simple one just for channels */ struct coro_cond { @@ -276,7 +216,7 @@ public: template auto start(F &&func, A &&...args) -> std::result_of_t { - detail::sched_iface_owner iface{*this}; + detail::current_scheduler_owner iface{*this}; using R = std::result_of_t; @@ -349,7 +289,7 @@ using protected_simple_coroutine_scheduler = basic_simple_coroutine_scheduler; template -struct basic_coroutine_scheduler { +struct basic_coroutine_scheduler: scheduler { private: struct task_cond; struct task; @@ -438,7 +378,7 @@ public: template auto start(F func, A &&...args) -> std::result_of_t { - detail::sched_iface_owner iface{*this}; + detail::current_scheduler_owner iface{*this}; /* start with one task in the queue, this way we can * say we've finished when the task queue becomes empty @@ -622,7 +562,7 @@ namespace detail { template inline auto spawn(S &sched, F &&func, A &&...args) -> std::enable_if_t< - detail::has_sched_spawn + std::is_base_of_v > { if constexpr(sizeof...(A) == 0) { sched.spawn(std::forward(func)); @@ -633,12 +573,12 @@ inline auto spawn(S &sched, F &&func, A &&...args) -> std::enable_if_t< template inline auto spawn(F &&func, A &&...args) -> std::enable_if_t< - !detail::has_sched_spawn + !std::is_base_of_v > { if constexpr(sizeof...(A) == 0) { - detail::current_sched_iface.spawn(std::forward(func)); + detail::current_scheduler->spawn(std::forward(func)); } else { - detail::current_sched_iface.spawn( + detail::current_scheduler->spawn( std::bind(std::forward(func), std::forward(args)...) ); } @@ -650,7 +590,7 @@ inline void yield(S &sched) { } inline void yield() { - detail::current_sched_iface.yield(); + detail::current_scheduler->yield(); } template @@ -662,9 +602,9 @@ inline channel make_channel(S &sched) { template inline channel make_channel() { - auto &sciface = detail::current_sched_iface; - return channel{[&sciface]() { - return sciface.make_condition(); + auto *curr = detail::current_scheduler; + return channel{[curr]() { + return curr->make_condition(); }}; } diff --git a/src/concurrency.cc b/src/concurrency.cc index 6f313d8..c0c1004 100644 --- a/src/concurrency.cc +++ b/src/concurrency.cc @@ -8,7 +8,7 @@ namespace ostd { namespace detail { -OSTD_EXPORT sched_iface current_sched_iface; +OSTD_EXPORT scheduler *current_scheduler = nullptr; OSTD_EXPORT thread_local csched_task *current_csched_task = nullptr; } /* namespace detail */