forked from OctaForge/libostd
make it possible to allocate coroutines/generators with scheduler
This commit is contained in:
parent
4562156200
commit
1826511187
|
@ -21,6 +21,24 @@
|
||||||
namespace ostd {
|
namespace ostd {
|
||||||
|
|
||||||
struct scheduler {
|
struct scheduler {
|
||||||
|
private:
|
||||||
|
struct stack_allocator {
|
||||||
|
stack_allocator() = delete;
|
||||||
|
stack_allocator(scheduler &s) noexcept: p_sched(&s) {}
|
||||||
|
|
||||||
|
stack_context allocate() {
|
||||||
|
return p_sched->allocate_stack();
|
||||||
|
}
|
||||||
|
|
||||||
|
void deaallocate(stack_context &st) noexcept {
|
||||||
|
p_sched->deallocate_stack(st);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
scheduler *p_sched;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
scheduler() {}
|
scheduler() {}
|
||||||
|
|
||||||
scheduler(scheduler const &) = delete;
|
scheduler(scheduler const &) = delete;
|
||||||
|
@ -32,6 +50,13 @@ struct scheduler {
|
||||||
virtual void yield() noexcept = 0;
|
virtual void yield() noexcept = 0;
|
||||||
virtual generic_condvar make_condition() = 0;
|
virtual generic_condvar make_condition() = 0;
|
||||||
|
|
||||||
|
virtual stack_context allocate_stack() = 0;
|
||||||
|
virtual void deallocate_stack(stack_context &st) noexcept = 0;
|
||||||
|
|
||||||
|
stack_allocator get_stack_allocator() noexcept {
|
||||||
|
return stack_allocator{*this};
|
||||||
|
}
|
||||||
|
|
||||||
template<typename F, typename ...A>
|
template<typename F, typename ...A>
|
||||||
void spawn(F &&func, A &&...args) {
|
void spawn(F &&func, A &&...args) {
|
||||||
if constexpr(sizeof...(A) == 0) {
|
if constexpr(sizeof...(A) == 0) {
|
||||||
|
@ -49,6 +74,16 @@ struct scheduler {
|
||||||
return make_condition();
|
return make_condition();
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T, typename F>
|
||||||
|
coroutine<T> make_coroutine(F &&func) {
|
||||||
|
return coroutine<T>{std::forward<F>(func), get_stack_allocator()};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename F>
|
||||||
|
generator<T> make_generator(F &&func) {
|
||||||
|
return generator<T>{std::forward<F>(func), get_stack_allocator()};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
@ -108,6 +143,15 @@ struct thread_scheduler: scheduler {
|
||||||
return generic_condvar{};
|
return generic_condvar{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stack_context allocate_stack() {
|
||||||
|
/* TODO: store the allocator properly, for now it's fine */
|
||||||
|
return fixedsize_stack{}.allocate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void deallocate_stack(stack_context &st) noexcept {
|
||||||
|
fixedsize_stack{}.deallocate(st);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void remove_thread(typename std::list<std::thread>::iterator it) {
|
void remove_thread(typename std::list<std::thread>::iterator it) {
|
||||||
std::lock_guard<std::mutex> l{p_lock};
|
std::lock_guard<std::mutex> l{p_lock};
|
||||||
|
@ -284,6 +328,15 @@ public:
|
||||||
return coro_cond{*this};
|
return coro_cond{*this};
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stack_context allocate_stack() {
|
||||||
|
return p_stacks.allocate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void deallocate_stack(stack_context &st) noexcept {
|
||||||
|
p_stacks.deallocate(st);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void dispatch() {
|
void dispatch() {
|
||||||
while (!p_coros.empty()) {
|
while (!p_coros.empty()) {
|
||||||
|
@ -443,6 +496,15 @@ public:
|
||||||
return task_cond{*this};
|
return task_cond{*this};
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stack_context allocate_stack() {
|
||||||
|
return p_stacks.allocate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void deallocate_stack(stack_context &st) noexcept {
|
||||||
|
p_stacks.deallocate(st);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<typename SA, typename F, typename ...A>
|
template<typename SA, typename F, typename ...A>
|
||||||
void spawn_add(SA &&sa, F &&func, A &&...args) {
|
void spawn_add(SA &&sa, F &&func, A &&...args) {
|
||||||
|
@ -585,6 +647,16 @@ inline channel<T> make_channel() {
|
||||||
return detail::current_scheduler->make_channel<T>();
|
return detail::current_scheduler->make_channel<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T, typename F>
|
||||||
|
coroutine<T> make_coroutine(F &&func) {
|
||||||
|
return detail::current_scheduler->make_coroutine<T>(std::forward<F>(func));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename F>
|
||||||
|
generator<T> make_generator(F &&func) {
|
||||||
|
return detail::current_scheduler->make_generator<T>(std::forward<F>(func));
|
||||||
|
}
|
||||||
|
|
||||||
} /* namespace ostd */
|
} /* namespace ostd */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue