29#include <EASTL/functional.h>
30#include <EASTL/utility.h>
53template <
typename T =
void>
56 typedef typename std::conditional<std::is_void<T>::value,
Empty, T>::type
SafeT;
61 if (m_handle) m_handle.destroy();
63 m_handle = other.m_handle;
64 m_value = eastl::move(other.m_value);
65 m_suspended = other.m_suspended;
66 m_earlyResume = other.m_earlyResume;
68 other.m_handle =
nullptr;
69 other.m_value =
SafeT{};
70 other.m_suspended =
true;
71 other.m_earlyResume =
false;
76 if (m_handle) m_handle.destroy();
78 m_handle = other.m_handle;
79 m_value = eastl::move(other.m_value);
80 m_suspended = other.m_suspended;
81 m_earlyResume = other.m_earlyResume;
83 other.m_handle =
nullptr;
84 other.m_value =
SafeT{};
85 other.m_suspended =
true;
86 other.m_earlyResume =
false;
94 if (m_handle) m_handle.destroy();
112 bool ret = m_coroutine->m_earlyResume;
113 m_coroutine->m_earlyResume =
false;
116 constexpr void await_suspend(std::coroutine_handle<> h) { m_coroutine->m_suspended =
true; }
143 if (!m_handle)
return;
145 m_earlyResume =
true;
162 if (!m_handle)
return true;
163 bool isDone = m_handle.done();
165 if constexpr (!std::is_void<T>::value) {
166 m_value = eastl::move(m_handle.promise().m_value);
190 return Coroutine<>{eastl::move(std::coroutine_handle<Promise>::from_promise(*
this))};
192 std::suspend_always initial_suspend() {
return {}; }
193 std::suspend_always final_suspend() noexcept {
return {}; }
194 void unhandled_exception() {}
196 if (m_awaitingCoroutine) {
198 m_awaitingCoroutine =
nullptr;
201 [[no_unique_address]] Empty m_value;
202 std::coroutine_handle<> m_awaitingCoroutine;
205 struct PromiseValue {
206 Coroutine<T> get_return_object() {
207 return Coroutine{eastl::move(std::coroutine_handle<Promise>::from_promise(*
this))};
209 std::suspend_always initial_suspend() {
return {}; }
210 std::suspend_always final_suspend() noexcept {
return {}; }
211 void unhandled_exception() {}
212 void return_value(T &&
value) {
213 m_value = eastl::move(
value);
214 if (m_awaitingCoroutine) {
216 m_awaitingCoroutine =
nullptr;
220 std::coroutine_handle<> m_awaitingCoroutine;
223 typedef typename std::conditional<std::is_void<T>::value, PromiseVoid, PromiseValue>::type Promise;
225 Coroutine(std::coroutine_handle<Promise> &&handle) : m_handle(eastl::
move(handle)) {}
227 std::coroutine_handle<Promise> m_handle;
228 [[no_unique_address]]
SafeT m_value;
229 bool m_suspended =
true;
230 bool m_earlyResume =
false;
236 template <
typename U>
238 m_handle.promise().m_awaitingCoroutine = h;
242 if constexpr (std::is_void<T>::value) {
245 return eastl::move(m_handle.promise().m_value);
252 void initializeInternal(eastl::function<
void()> &&func,
void *ss_sp,
unsigned ss_size);
255 [[nodiscard]]
bool isAlive()
const {
return m_isAlive; }
262 static void trampoline(
void *arg) {
269 eastl::function<
void()> m_func;
270 bool m_isAlive =
false;
286template <
unsigned StackSize = 0x10000>
337 struct alignas(8) Stack {
Definition coroutine.hh:250
void yield()
Definition coroutine.cpp:49
bool isAlive() const
Definition coroutine.hh:255
StackfulBase & operator=(const StackfulBase &)=delete
void resume()
Definition coroutine.cpp:44
StackfulBase(const StackfulBase &)=delete
void initializeInternal(eastl::function< void()> &&func, void *ss_sp, unsigned ss_size)
Definition coroutine.cpp:29
Stackful coroutine class.
Definition coroutine.hh:287
Stackful(const Stackful &)=delete
bool isAlive() const
Check if the coroutine is currently alive.
Definition coroutine.hh:334
void yield()
Yield the coroutine.
Definition coroutine.hh:324
void resume()
Resume the coroutine.
Definition coroutine.hh:314
void initialize(eastl::function< void()> &&func)
Initialize the coroutine with a function and an argument.
Definition coroutine.hh:301
static constexpr unsigned c_stackSize
Definition coroutine.hh:289
Stackful & operator=(const Stackful &)=delete
constexpr uint32_t move(Reg tgt, Reg src)
Definition encoder.hh:243
void queueCallback(eastl::function< void()> &&lambda)
Queues a callback to be called from the main thead.
Definition kernel.cpp:394
The awaiter type.
Definition coroutine.hh:106
Awaiter(Awaiter &&other)=default
Awaiter(Awaiter const &)=default
constexpr void await_suspend(std::coroutine_handle<> h)
Definition coroutine.hh:116
Awaiter & operator=(Awaiter const &)=default
constexpr void await_resume() const noexcept
Definition coroutine.hh:117
constexpr bool await_ready() const noexcept
Definition coroutine.hh:111
Awaiter & operator=(Awaiter &&other)=default
Definition coroutine.hh:55
A suitable type to hold and return a C++20 coroutine.
Definition coroutine.hh:54
Coroutine(Coroutine const &)=delete
Awaiter awaiter()
Creates an Awaiter object.
Definition coroutine.hh:131
~Coroutine()
Definition coroutine.hh:93
Coroutine & operator=(Coroutine const &)=delete
constexpr T await_resume()
Definition coroutine.hh:241
constexpr bool await_ready()
Definition coroutine.hh:235
Promise promise_type
Definition coroutine.hh:233
const SafeT & value() const
Returns the value returned by the coroutine.
Definition coroutine.hh:185
Coroutine(Coroutine &&other)
Definition coroutine.hh:60
std::conditional< std::is_void< T >::value, Empty, T >::type SafeT
Definition coroutine.hh:56
Coroutine & operator=(Coroutine &&other)
Definition coroutine.hh:74
void resume()
Resumes the coroutine.
Definition coroutine.hh:142
bool done()
Returns the status of the coroutine.
Definition coroutine.hh:161
constexpr void await_suspend(std::coroutine_handle< U > h)
Definition coroutine.hh:237
static int ret
Definition syscalls.h:72