From b1d95faa4186bdcb2d04715ae079ea37ba948cea Mon Sep 17 00:00:00 2001 From: q66 Date: Sat, 25 Mar 2017 15:01:14 +0100 Subject: [PATCH] make it possible to provide custom stack allocator types to schedulers --- ostd/concurrency.hh | 73 ++++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/ostd/concurrency.hh b/ostd/concurrency.hh index a92719c..b88c623 100644 --- a/ostd/concurrency.hh +++ b/ostd/concurrency.hh @@ -111,7 +111,10 @@ namespace detail { }; } -struct thread_scheduler: scheduler { +template +struct basic_thread_scheduler: scheduler { + basic_thread_scheduler(SA &&sa = SA{}): p_stacks(std::move(sa)) {} + template auto start(F &&func, A &&...args) -> std::result_of_t { detail::current_scheduler_owner iface{*this}; @@ -144,12 +147,15 @@ struct thread_scheduler: scheduler { } stack_context allocate_stack() { - /* TODO: store the allocator properly, for now it's fine */ - return fixedsize_stack{}.allocate(); + return p_stacks.allocate(); } void deallocate_stack(stack_context &st) noexcept { - fixedsize_stack{}.deallocate(st); + p_stacks.deallocate(st); + } + + void reserve_stacks(size_t n) { + p_stacks.reserve(n); } private: @@ -174,11 +180,14 @@ private: } } + SA p_stacks; std::list p_threads; std::thread p_dead; std::mutex p_lock; }; +using thread_scheduler = basic_thread_scheduler; + namespace detail { struct csched_task; @@ -235,7 +244,7 @@ namespace detail { }; } -template +template struct basic_simple_coroutine_scheduler: scheduler { private: /* simple one just for channels */ @@ -273,11 +282,8 @@ private: }; public: - basic_simple_coroutine_scheduler( - size_t ss = TR::default_size(), - size_t cs = basic_stack_pool::DEFAULT_CHUNK_SIZE - ): - p_stacks(ss, cs), p_coros() + basic_simple_coroutine_scheduler(SA &&sa = SA{}): + p_stacks(std::move(sa)) {} template @@ -286,7 +292,9 @@ public: using R = std::result_of_t; - basic_fixedsize_stack sa{detail::stack_main_size()}; + basic_fixedsize_stack sa{ + detail::stack_main_size() + }; if constexpr(std::is_same_v) { if constexpr(sizeof...(A) == 0) { @@ -352,18 +360,14 @@ private: } } - basic_stack_pool p_stacks; + SA p_stacks; std::list p_coros; typename std::list::iterator p_idx = p_coros.end(); }; -using simple_coroutine_scheduler = - basic_simple_coroutine_scheduler; +using simple_coroutine_scheduler = basic_simple_coroutine_scheduler; -using protected_simple_coroutine_scheduler = - basic_simple_coroutine_scheduler; - -template +template struct basic_coroutine_scheduler: scheduler { private: struct task_cond; @@ -381,9 +385,9 @@ private: task *next_waiting = nullptr; titer pos; - template - task(F &&f, SA &&sa): - p_func(std::forward(f), std::forward(sa)) + template + task(F &&f, TSA &&sa): + p_func(std::forward(f), std::forward(sa)) {} void operator()() { @@ -442,11 +446,8 @@ private: }; public: - basic_coroutine_scheduler( - size_t ss = TR::default_size(), - size_t cs = basic_stack_pool::DEFAULT_CHUNK_SIZE - ): - p_stacks(ss, cs) + basic_coroutine_scheduler(SA &&sa = SA{}): + p_stacks(std::move(sa)) {} ~basic_coroutine_scheduler() {} @@ -463,7 +464,9 @@ public: /* the default 64 KiB stack won't cut it for main, allocate a stack * which matches the size of the process stack outside of the pool */ - basic_fixedsize_stack sa{detail::stack_main_size()}; + basic_fixedsize_stack sa{ + detail::stack_main_size() + }; if constexpr(std::is_same_v) { spawn_add(sa, std::move(func), std::forward(args)...); @@ -506,13 +509,13 @@ public: } private: - template - void spawn_add(SA &&sa, F &&func, A &&...args) { + template + void spawn_add(TSA &&sa, F &&func, A &&...args) { task *t = nullptr; if constexpr(sizeof...(A) == 0) { t = &p_available.emplace_back( std::forward(func), - std::forward(sa) + std::forward(sa) ); } else { t = &p_available.emplace_back( @@ -521,7 +524,7 @@ private: )]() mutable { lfunc(); }, - std::forward(sa) + std::forward(sa) ); } t->pos = --p_available.end(); @@ -619,17 +622,13 @@ private: std::condition_variable p_cond; std::mutex p_lock; - basic_stack_pool p_stacks; + SA p_stacks; tlist p_available; tlist p_waiting; tlist p_running; }; -using coroutine_scheduler = - basic_coroutine_scheduler; - -using protected_coroutine_scheduler = - basic_coroutine_scheduler; +using coroutine_scheduler = basic_coroutine_scheduler; template inline void spawn(F &&func, A &&...args) {