mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-05-28 15:34:31 +00:00
test(kernel): expand coroutine tests
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
This commit is contained in:
parent
a6ca98987e
commit
91ad0e14df
@ -24,6 +24,7 @@
|
|||||||
#include "../kernel.h"
|
#include "../kernel.h"
|
||||||
|
|
||||||
#include <coroutine>
|
#include <coroutine>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
/* https://gist.github.com/Qix-/caa277fbf1a4e6ca55a27f2242df3b9a */
|
/* https://gist.github.com/Qix-/caa277fbf1a4e6ca55a27f2242df3b9a */
|
||||||
|
|
||||||
@ -58,7 +59,7 @@ struct resumable::promise_type
|
|||||||
auto initial_suspend() { return std::suspend_always(); }
|
auto initial_suspend() { return std::suspend_always(); }
|
||||||
auto final_suspend() noexcept { return std::suspend_always(); }
|
auto final_suspend() noexcept { return std::suspend_always(); }
|
||||||
void return_void() {}
|
void return_void() {}
|
||||||
void unhandled_exception() { assert(!"std::terminate();"); }
|
void unhandled_exception() { std::terminate(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
resumable foo()
|
resumable foo()
|
||||||
@ -70,6 +71,122 @@ resumable foo()
|
|||||||
|
|
||||||
/* ===================================================================== */
|
/* ===================================================================== */
|
||||||
|
|
||||||
|
struct Generator
|
||||||
|
{
|
||||||
|
struct promise_type
|
||||||
|
{
|
||||||
|
int current_value;
|
||||||
|
|
||||||
|
Generator get_return_object()
|
||||||
|
{
|
||||||
|
return Generator{std::coroutine_handle<promise_type>::from_promise(*this)};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::suspend_always initial_suspend()
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::suspend_always final_suspend() noexcept
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void return_void()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::suspend_always yield_value(int value)
|
||||||
|
{
|
||||||
|
current_value = value;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void unhandled_exception()
|
||||||
|
{
|
||||||
|
std::terminate();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::coroutine_handle<promise_type> handle;
|
||||||
|
|
||||||
|
Generator(std::coroutine_handle<promise_type> h) : handle(h) {}
|
||||||
|
|
||||||
|
~Generator()
|
||||||
|
{
|
||||||
|
if (handle)
|
||||||
|
handle.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool next()
|
||||||
|
{
|
||||||
|
if (!handle || handle.done())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
handle.resume();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int value() const
|
||||||
|
{
|
||||||
|
int ret = handle.promise().current_value;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Generator CountToThree()
|
||||||
|
{
|
||||||
|
debug("1");
|
||||||
|
co_yield 1;
|
||||||
|
debug("2");
|
||||||
|
co_yield 2;
|
||||||
|
debug("3");
|
||||||
|
co_yield 3;
|
||||||
|
debug("end");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===================================================================== */
|
||||||
|
|
||||||
|
struct Task
|
||||||
|
{
|
||||||
|
struct promise_type
|
||||||
|
{
|
||||||
|
Task get_return_object() { return Task{std::coroutine_handle<promise_type>::from_promise(*this)}; }
|
||||||
|
std::suspend_never initial_suspend() { return {}; }
|
||||||
|
std::suspend_never final_suspend() noexcept { return {}; }
|
||||||
|
void return_void() {}
|
||||||
|
void unhandled_exception() { std::terminate(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
std::coroutine_handle<promise_type> handle;
|
||||||
|
Task(std::coroutine_handle<promise_type> h) : handle(h) {}
|
||||||
|
~Task()
|
||||||
|
{
|
||||||
|
if (handle)
|
||||||
|
handle.destroy();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Awaiter
|
||||||
|
{
|
||||||
|
bool await_ready() { return false; }
|
||||||
|
void await_suspend(std::coroutine_handle<> h)
|
||||||
|
{
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
|
h.resume();
|
||||||
|
}
|
||||||
|
void await_resume() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
Task AsyncFunc()
|
||||||
|
{
|
||||||
|
debug("waiting");
|
||||||
|
co_await Awaiter{};
|
||||||
|
debug("done");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===================================================================== */
|
||||||
|
|
||||||
class SyscallAwaitable
|
class SyscallAwaitable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -120,7 +237,7 @@ public:
|
|||||||
|
|
||||||
void unhandled_exception()
|
void unhandled_exception()
|
||||||
{
|
{
|
||||||
assert("std::terminate();");
|
std::terminate();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -146,6 +263,17 @@ void coroutineTest()
|
|||||||
auto task = perform_syscall();
|
auto task = perform_syscall();
|
||||||
task.handle.resume();
|
task.handle.resume();
|
||||||
|
|
||||||
|
/* async task */
|
||||||
|
AsyncFunc();
|
||||||
|
|
||||||
|
/* generator */
|
||||||
|
auto gen = CountToThree();
|
||||||
|
while (gen.next())
|
||||||
|
{
|
||||||
|
auto a = gen.value();
|
||||||
|
debug("%d", a);
|
||||||
|
}
|
||||||
|
|
||||||
/* Example of coroutine */
|
/* Example of coroutine */
|
||||||
auto p = foo();
|
auto p = foo();
|
||||||
while (p.resume())
|
while (p.resume())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user