use a custom coroutine type for tasks

This commit is contained in:
q66 2017-03-22 17:58:34 +01:00
parent 2537d955d1
commit bffc917f46

View file

@ -235,27 +235,29 @@ private:
using tlist = std::list<task>; using tlist = std::list<task>;
using titer = typename tlist::iterator; using titer = typename tlist::iterator;
struct task { struct task: coroutine_context {
struct coro: coroutine<void()> { std::function<void()> func;
using coroutine<void()>::coroutine;
task *tptr = nullptr;
};
coro func;
task_cond *waiting_on = nullptr; task_cond *waiting_on = nullptr;
task *next_waiting = nullptr; task *next_waiting = nullptr;
titer pos; titer pos;
task() = delete; task() = delete;
task(task const &) = delete;
task(task &&) = delete;
task &operator=(task const &) = delete;
task &operator=(task &&) = delete;
template<typename F, typename SA> template<typename F, typename SA>
task(F &&f, SA &&alloc): task(F &&f, SA &&sa): func(std::forward<F>(f)) {
func(std::forward<F>(f), std::forward<SA>(alloc)) if (!func) {
{ this->set_dead();
func.tptr = this; return;
}
this->make_context<task>(sa);
} }
void operator()() { void operator()() {
func(); this->call();
} }
void yield() { void yield() {
@ -263,20 +265,24 @@ private:
* will appropriately notify one or all other waiting threads * will appropriately notify one or all other waiting threads
* so we either get re-scheduled or the whole scheduler dies * so we either get re-scheduled or the whole scheduler dies
*/ */
typename coro::yield_type{func}(); this->yield_jump();
} }
bool dead() const { bool dead() const {
return !func; return this->is_dead();
} }
static task *current() { static task *current() {
auto ctx = coroutine_context::current(); auto ctx = coroutine_context::current();
coro *c = dynamic_cast<coro *>(ctx); task *t = dynamic_cast<task *>(ctx);
if (!c) { if (!t) {
std::terminate(); std::terminate();
} }
return c->tptr; return t;
}
void resume_call() {
func();
} }
}; };
@ -377,16 +383,14 @@ private:
task *t = nullptr; task *t = nullptr;
if constexpr(sizeof...(A) == 0) { if constexpr(sizeof...(A) == 0) {
t = &p_available.emplace_back( t = &p_available.emplace_back(
[lfunc = std::forward<F>(func)](auto) { std::forward<F>(func),
lfunc();
},
std::forward<SA>(sa) std::forward<SA>(sa)
); );
} else { } else {
t = &p_available.emplace_back( t = &p_available.emplace_back(
[lfunc = std::bind( [lfunc = std::bind(
std::forward<F>(func), std::forward<A>(args)... std::forward<F>(func), std::forward<A>(args)...
)](auto) mutable { )]() mutable {
lfunc(); lfunc();
}, },
std::forward<SA>(sa) std::forward<SA>(sa)