Commit 7594bee5 authored by Xavier Thompson's avatar Xavier Thompson

Refactor continuation.hpp

parent 1decadad
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#define TYPON_CORE_CONTINUATION_HPP_INCLUDED #define TYPON_CORE_CONTINUATION_HPP_INCLUDED
#include <atomic> #include <atomic>
#include <concepts>
#include <coroutine> #include <coroutine>
#include <cstdint> #include <cstdint>
#include <exception> #include <exception>
...@@ -11,19 +12,23 @@ ...@@ -11,19 +12,23 @@
namespace typon namespace typon
{ {
struct coroutine_node struct ForkList
{ {
coroutine_node * _next; struct Node
{
Node * _next;
std::coroutine_handle<> _coroutine; std::coroutine_handle<> _coroutine;
std::exception_ptr * _exception; std::exception_ptr * _exception;
}; };
Node * _first = nullptr;
struct coroutine_list
{
coroutine_node * _first = nullptr;
template <typename Promise> template <typename Promise>
requires requires (Promise p)
{
{ p._exception } -> std::same_as<std::exception_ptr&>;
{ p._node } -> std::same_as<Node&>;
}
void insert(std::coroutine_handle<Promise> coroutine) noexcept void insert(std::coroutine_handle<Promise> coroutine) noexcept
{ {
std::exception_ptr * exception = &(coroutine.promise()._exception); std::exception_ptr * exception = &(coroutine.promise()._exception);
...@@ -57,32 +62,33 @@ namespace typon ...@@ -57,32 +62,33 @@ namespace typon
}; };
struct continuation_data struct Continuation
{
struct Data
{ {
using u64 = std::uint_fast64_t; using u64 = std::uint_fast64_t;
static constexpr u64 UMAX = std::numeric_limits<u64>::max(); static constexpr u64 UMAX = std::numeric_limits<u64>::max();
std::coroutine_handle<> _coroutine; std::coroutine_handle<> _coroutine;
std::coroutine_handle<> _continuation; std::coroutine_handle<> _continuation;
coroutine_list _children;
ForkList _children;
std::atomic<u64> _n = UMAX; std::atomic<u64> _n = UMAX;
u64 _thefts = 0; u64 _thefts = 0;
continuation_data(std::coroutine_handle<> coroutine) Data(std::coroutine_handle<> coroutine) noexcept
: _coroutine(coroutine) : _coroutine(coroutine)
{} {}
}; };
Data * _data;
struct continuation_handle Continuation() noexcept {}
{
continuation_data * _data;
continuation_handle() noexcept {}
template <typename Promise> template <typename Promise>
continuation_handle(std::coroutine_handle<Promise> coroutine) noexcept Continuation(std::coroutine_handle<Promise> coroutine) noexcept
: _data(&(coroutine.promise()._data)) : _data(&(coroutine.promise()._data))
{} {}
...@@ -123,4 +129,5 @@ namespace typon ...@@ -123,4 +129,5 @@ namespace typon
} }
#endif // TYPON_CONTINUATION_HPP_INCLUDED #endif // TYPON_CONTINUATION_HPP_INCLUDED
...@@ -17,7 +17,7 @@ namespace typon ...@@ -17,7 +17,7 @@ namespace typon
struct [[nodiscard]] Fork struct [[nodiscard]] Fork
{ {
struct promise_type; struct promise_type;
using u64 = continuation_data::u64; using u64 = Continuation::Data::u64;
std::coroutine_handle<promise_type> _coroutine; std::coroutine_handle<promise_type> _coroutine;
...@@ -32,8 +32,8 @@ namespace typon ...@@ -32,8 +32,8 @@ namespace typon
struct promise_type : Result<T> struct promise_type : Result<T>
{ {
continuation_handle _continuation; Continuation _continuation;
coroutine_node _node; ForkList::Node _node;
Fork get_return_object() noexcept Fork get_return_object() noexcept
{ {
......
...@@ -47,10 +47,10 @@ namespace typon ...@@ -47,10 +47,10 @@ namespace typon
struct promise_type : Result<T> struct promise_type : Result<T>
{ {
using u64 = continuation_data::u64; using u64 = Continuation::Data::u64;
static constexpr u64 UMAX = continuation_data::UMAX; static constexpr u64 UMAX = Continuation::Data::UMAX;
continuation_data _data; Continuation::Data _data;
promise_type() noexcept promise_type() noexcept
: _data(std::coroutine_handle<promise_type>::from_promise(*this)) : _data(std::coroutine_handle<promise_type>::from_promise(*this))
...@@ -76,7 +76,7 @@ namespace typon ...@@ -76,7 +76,7 @@ namespace typon
{ {
struct awaitable struct awaitable
{ {
continuation_data & _data; Continuation::Data & _data;
bool await_ready() noexcept bool await_ready() noexcept
{ {
...@@ -119,7 +119,7 @@ namespace typon ...@@ -119,7 +119,7 @@ namespace typon
{ {
std::coroutine_handle<> await_suspend(std::coroutine_handle<promise_type> coroutine) noexcept std::coroutine_handle<> await_suspend(std::coroutine_handle<promise_type> coroutine) noexcept
{ {
continuation_data & data = coroutine.promise()._data; Continuation::Data & data = coroutine.promise()._data;
u64 thefts = data._thefts; u64 thefts = data._thefts;
u64 n = data._n.fetch_sub(UMAX - thefts, std::memory_order_acq_rel); u64 n = data._n.fetch_sub(UMAX - thefts, std::memory_order_acq_rel);
if (n - (UMAX - thefts) == 0) if (n - (UMAX - thefts) == 0)
......
...@@ -27,8 +27,7 @@ namespace typon ...@@ -27,8 +27,7 @@ namespace typon
struct promise_type : Result<void> struct promise_type : Result<void>
{ {
// std::atomic_bool _done = false; Continuation::Data _data;
continuation_data _data;
promise_type() noexcept promise_type() noexcept
: _data(std::coroutine_handle<promise_type>::from_promise(*this)) : _data(std::coroutine_handle<promise_type>::from_promise(*this))
...@@ -64,7 +63,7 @@ namespace typon ...@@ -64,7 +63,7 @@ namespace typon
{ {
Scheduler::get(); Scheduler::get();
Scheduler::schedule(_coroutine); Scheduler::schedule(_coroutine);
_coroutine.promise()._data._n.wait(continuation_data::UMAX, std::memory_order_acquire); _coroutine.promise()._data._n.wait(Continuation::Data::UMAX, std::memory_order_acquire);
} }
}; };
......
...@@ -21,7 +21,7 @@ namespace typon ...@@ -21,7 +21,7 @@ namespace typon
struct Scheduler struct Scheduler
{ {
using uint = unsigned int; using uint = unsigned int;
using Deque = fdt::lock_free::deque<continuation_handle>; using Deque = fdt::lock_free::deque<Continuation>;
using Task = typename Deque::pop_type; using Task = typename Deque::pop_type;
static inline thread_local uint thread_id; static inline thread_local uint thread_id;
...@@ -40,12 +40,12 @@ namespace typon ...@@ -40,12 +40,12 @@ namespace typon
return scheduler; return scheduler;
} }
static void push(continuation_handle task) noexcept static void push(Continuation task) noexcept
{ {
get()._deque[thread_id].push(task); get()._deque[thread_id].push(task);
} }
static void schedule(continuation_handle task) noexcept static void schedule(Continuation task) noexcept
{ {
Scheduler & scheduler = get(); Scheduler & scheduler = get();
scheduler._deque[thread_id].push(task); scheduler._deque[thread_id].push(task);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment