forked from OctaForge/libostd
track current task for coroutine scheduler separately
This commit is contained in:
parent
bffc917f46
commit
18cfe5119f
2
build.sh
2
build.sh
|
@ -13,7 +13,7 @@ ASM_SOURCES="jump_all_gas make_all_gas ontop_all_gas"
|
||||||
|
|
||||||
# c++ sources
|
# c++ sources
|
||||||
CXX_SOURCE_DIR="src"
|
CXX_SOURCE_DIR="src"
|
||||||
CXX_SOURCES="context_stack io"
|
CXX_SOURCES="context_stack io concurrency"
|
||||||
|
|
||||||
# output lib
|
# output lib
|
||||||
OSTD_LIB="libostd"
|
OSTD_LIB="libostd"
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
#ifndef OSTD_CONCURRENCY_HH
|
#ifndef OSTD_CONCURRENCY_HH
|
||||||
#define OSTD_CONCURRENCY_HH
|
#define OSTD_CONCURRENCY_HH
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <list>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -226,38 +228,38 @@ using simple_coroutine_scheduler =
|
||||||
using protected_simple_coroutine_scheduler =
|
using protected_simple_coroutine_scheduler =
|
||||||
basic_simple_coroutine_scheduler<stack_traits, true>;
|
basic_simple_coroutine_scheduler<stack_traits, true>;
|
||||||
|
|
||||||
template<typename TR, bool Protected>
|
namespace detail {
|
||||||
struct basic_coroutine_scheduler {
|
struct csched_task;
|
||||||
private:
|
|
||||||
struct task_cond;
|
|
||||||
struct task;
|
|
||||||
|
|
||||||
using tlist = std::list<task>;
|
OSTD_EXPORT extern thread_local csched_task *current_csched_task;
|
||||||
using titer = typename tlist::iterator;
|
|
||||||
|
|
||||||
struct task: coroutine_context {
|
struct csched_task: coroutine_context {
|
||||||
std::function<void()> func;
|
std::function<void()> func;
|
||||||
task_cond *waiting_on = nullptr;
|
void *waiting_on = nullptr;
|
||||||
task *next_waiting = nullptr;
|
csched_task *next_waiting = nullptr;
|
||||||
titer pos;
|
typename std::list<csched_task>::iterator pos;
|
||||||
|
|
||||||
task() = delete;
|
csched_task() = delete;
|
||||||
task(task const &) = delete;
|
csched_task(csched_task const &) = delete;
|
||||||
task(task &&) = delete;
|
csched_task(csched_task &&) = delete;
|
||||||
task &operator=(task const &) = delete;
|
csched_task &operator=(csched_task const &) = delete;
|
||||||
task &operator=(task &&) = delete;
|
csched_task &operator=(csched_task &&) = delete;
|
||||||
|
|
||||||
template<typename F, typename SA>
|
template<typename F, typename SA>
|
||||||
task(F &&f, SA &&sa): func(std::forward<F>(f)) {
|
csched_task(F &&f, SA &&sa): func(std::forward<F>(f)) {
|
||||||
if (!func) {
|
if (!func) {
|
||||||
this->set_dead();
|
this->set_dead();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->make_context<task>(sa);
|
this->make_context<csched_task>(sa);
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()() {
|
void operator()() {
|
||||||
this->call();
|
this->set_exec();
|
||||||
|
csched_task *curr = std::exchange(current_csched_task, this);
|
||||||
|
this->coro_jump();
|
||||||
|
current_csched_task = curr;
|
||||||
|
this->rethrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
void yield() {
|
void yield() {
|
||||||
|
@ -272,19 +274,24 @@ private:
|
||||||
return this->is_dead();
|
return this->is_dead();
|
||||||
}
|
}
|
||||||
|
|
||||||
static task *current() {
|
static csched_task *current() {
|
||||||
auto ctx = coroutine_context::current();
|
return current_csched_task;
|
||||||
task *t = dynamic_cast<task *>(ctx);
|
|
||||||
if (!t) {
|
|
||||||
std::terminate();
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void resume_call() {
|
void resume_call() {
|
||||||
func();
|
func();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TR, bool Protected>
|
||||||
|
struct basic_coroutine_scheduler {
|
||||||
|
private:
|
||||||
|
struct task_cond;
|
||||||
|
using task = detail::csched_task;
|
||||||
|
|
||||||
|
using tlist = std::list<task>;
|
||||||
|
using titer = typename tlist::iterator;
|
||||||
|
|
||||||
struct task_cond {
|
struct task_cond {
|
||||||
task_cond() = delete;
|
task_cond() = delete;
|
||||||
|
|
|
@ -75,15 +75,13 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
void call() {
|
void call() {
|
||||||
p_state = state::EXEC;
|
set_exec();
|
||||||
/* switch to new coroutine */
|
/* switch to new coroutine */
|
||||||
coroutine_context *curr = std::exchange(detail::coro_current, this);
|
coroutine_context *curr = std::exchange(detail::coro_current, this);
|
||||||
coro_jump();
|
coro_jump();
|
||||||
/* switch back to previous */
|
/* switch back to previous */
|
||||||
detail::coro_current = curr;
|
detail::coro_current = curr;
|
||||||
if (p_except) {
|
rethrow();
|
||||||
std::rethrow_exception(std::move(p_except));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void coro_jump() {
|
void coro_jump() {
|
||||||
|
@ -107,6 +105,16 @@ protected:
|
||||||
p_state = state::TERM;
|
p_state = state::TERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_exec() {
|
||||||
|
p_state = state::EXEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rethrow() {
|
||||||
|
if (p_except) {
|
||||||
|
std::rethrow_exception(std::move(p_except));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void swap(coroutine_context &other) noexcept {
|
void swap(coroutine_context &other) noexcept {
|
||||||
using std::swap;
|
using std::swap;
|
||||||
swap(p_stack, other.p_stack);
|
swap(p_stack, other.p_stack);
|
||||||
|
|
14
src/concurrency.cc
Normal file
14
src/concurrency.cc
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
/* Concurrency C implementation bits.
|
||||||
|
*
|
||||||
|
* This file is part of OctaSTD. See COPYING.md for futher information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ostd/concurrency.hh"
|
||||||
|
|
||||||
|
namespace ostd {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
OSTD_EXPORT thread_local csched_task *current_csched_task = nullptr;
|
||||||
|
|
||||||
|
} /* namespace detail */
|
||||||
|
} /* namespace ostd */
|
Loading…
Reference in a new issue