diff --git a/ostd/concurrency.hh b/ostd/concurrency.hh index 1520bd2..e673f0d 100644 --- a/ostd/concurrency.hh +++ b/ostd/concurrency.hh @@ -117,7 +117,7 @@ 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 { + auto start(F func, A &&...args) -> std::result_of_t { detail::current_scheduler_owner iface{*this}; if constexpr(std::is_same_v, void>) { func(std::forward(args)...); @@ -302,43 +302,51 @@ public: p_stacks(std::move(sa)) {} - template - auto start(F &&func, A &&...args) -> std::result_of_t { + template + auto start(std::allocator_arg_t, TSA &&sa, F func, A &&...args) + -> std::result_of_t + { detail::current_scheduler_owner iface{*this}; using R = std::result_of_t; - basic_fixedsize_stack sa{ - detail::stack_main_size() - }; - if constexpr(std::is_same_v) { if constexpr(sizeof...(A) == 0) { - p_coros.emplace_back(std::forward(func), sa); + p_coros.emplace_back(std::move(func), std::forward(sa)); } else { p_coros.emplace_back(std::bind( - std::forward(func), std::forward(args)... - ), sa); + std::move(func), std::forward(args)... + ), std::forward(sa)); } dispatch(); } else { R ret; if constexpr(sizeof...(A) == 0) { - p_coros.emplace_back([&ret, lfunc = std::forward(func)] { + p_coros.emplace_back([&ret, lfunc = std::move(func)] { ret = lfunc(); - }, sa); + }, std::forward(sa)); } else { p_coros.emplace_back([&ret, lfunc = std::bind( - std::forward(func), std::forward(args)... + std::move(func), std::forward(args)... )]() { ret = lfunc(); - }, sa); + }, std::forward(sa)); } dispatch(); return ret; } } + template + auto start(F func, A &&...args) -> std::result_of_t { + basic_fixedsize_stack sa{ + detail::stack_main_size() + }; + return start( + std::allocator_arg, sa, std::move(func), std::forward(args)... + ); + } + void spawn(std::function func) { p_coros.emplace_back(std::move(func), p_stacks.get_allocator()); } @@ -472,8 +480,10 @@ public: ~basic_coroutine_scheduler() {} - template - auto start(F func, A &&...args) -> std::result_of_t { + template + auto start(std::allocator_arg_t, TSA &&sa, F func, A &&...args) + -> std::result_of_t + { detail::current_scheduler_owner iface{*this}; /* start with one task in the queue, this way we can @@ -481,25 +491,38 @@ public: */ using R = std::result_of_t; + if constexpr(std::is_same_v) { + spawn_add( + std::forward(sa), std::move(func), + std::forward(args)... + ); + /* actually start the thread pool */ + init(); + } else { + R ret; + spawn_add( + std::forward(sa), + [&ret, func = std::move(func)](auto &&...args) { + ret = func(std::forward(args)...); + }, + std::forward(args)... + ); + init(); + return ret; + } + } + + template + auto start(F func, A &&...args) -> std::result_of_t { /* 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() }; - - if constexpr(std::is_same_v) { - spawn_add(sa, std::move(func), std::forward(args)...); - /* actually start the thread pool */ - init(); - } else { - R ret; - spawn_add(sa, [&ret, func = std::move(func)](auto &&...args) { - ret = func(std::forward(args)...); - }, std::forward(args)...); - init(); - return ret; - } + return start( + std::allocator_arg, sa, std::move(func), std::forward(args)... + ); } void spawn(std::function func) {