forked from OctaForge/libostd
use a custom coroutine type for tasks
This commit is contained in:
parent
2537d955d1
commit
bffc917f46
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue