summaryrefslogtreecommitdiff
path: root/src/common/fiber.cpp
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2020-02-27 16:32:47 -0400
committerGravatar Fernando Sahmkow2020-06-18 16:29:25 -0400
commit137d862d9b275209b3d62a413396a15e9e14b4b4 (patch)
treeb2cdf3e5ac626e5c054c1df190b9371a11d2d694 /src/common/fiber.cpp
parentCommon/Fiber: Additional corrections to f_context. (diff)
downloadyuzu-137d862d9b275209b3d62a413396a15e9e14b4b4.tar.gz
yuzu-137d862d9b275209b3d62a413396a15e9e14b4b4.tar.xz
yuzu-137d862d9b275209b3d62a413396a15e9e14b4b4.zip
Common/Fiber: Implement Rewinding.
Diffstat (limited to 'src/common/fiber.cpp')
-rw-r--r--src/common/fiber.cpp32
1 files changed, 30 insertions, 2 deletions
diff --git a/src/common/fiber.cpp b/src/common/fiber.cpp
index e4ecc73df..f61479e13 100644
--- a/src/common/fiber.cpp
+++ b/src/common/fiber.cpp
@@ -12,10 +12,13 @@
12 12
13namespace Common { 13namespace Common {
14 14
15constexpr std::size_t default_stack_size = 256 * 1024; // 256kb
16
15#if defined(_WIN32) || defined(WIN32) 17#if defined(_WIN32) || defined(WIN32)
16 18
17struct Fiber::FiberImpl { 19struct Fiber::FiberImpl {
18 LPVOID handle = nullptr; 20 LPVOID handle = nullptr;
21 LPVOID rewind_handle = nullptr;
19}; 22};
20 23
21void Fiber::start() { 24void Fiber::start() {
@@ -26,15 +29,29 @@ void Fiber::start() {
26 UNREACHABLE(); 29 UNREACHABLE();
27} 30}
28 31
32void Fiber::onRewind() {
33 ASSERT(impl->handle != nullptr);
34 DeleteFiber(impl->handle);
35 impl->handle = impl->rewind_handle;
36 impl->rewind_handle = nullptr;
37 rewind_point(rewind_parameter);
38 UNREACHABLE();
39}
40
29void __stdcall Fiber::FiberStartFunc(void* fiber_parameter) { 41void __stdcall Fiber::FiberStartFunc(void* fiber_parameter) {
30 auto fiber = static_cast<Fiber*>(fiber_parameter); 42 auto fiber = static_cast<Fiber*>(fiber_parameter);
31 fiber->start(); 43 fiber->start();
32} 44}
33 45
46void __stdcall Fiber::RewindStartFunc(void* fiber_parameter) {
47 auto fiber = static_cast<Fiber*>(fiber_parameter);
48 fiber->onRewind();
49}
50
34Fiber::Fiber(std::function<void(void*)>&& entry_point_func, void* start_parameter) 51Fiber::Fiber(std::function<void(void*)>&& entry_point_func, void* start_parameter)
35 : entry_point{std::move(entry_point_func)}, start_parameter{start_parameter} { 52 : entry_point{std::move(entry_point_func)}, start_parameter{start_parameter} {
36 impl = std::make_unique<FiberImpl>(); 53 impl = std::make_unique<FiberImpl>();
37 impl->handle = CreateFiber(0, &FiberStartFunc, this); 54 impl->handle = CreateFiber(default_stack_size, &FiberStartFunc, this);
38} 55}
39 56
40Fiber::Fiber() { 57Fiber::Fiber() {
@@ -60,6 +77,18 @@ void Fiber::Exit() {
60 guard.unlock(); 77 guard.unlock();
61} 78}
62 79
80void Fiber::SetRewindPoint(std::function<void(void*)>&& rewind_func, void* start_parameter) {
81 rewind_point = std::move(rewind_func);
82 rewind_parameter = start_parameter;
83}
84
85void Fiber::Rewind() {
86 ASSERT(rewind_point);
87 ASSERT(impl->rewind_handle == nullptr);
88 impl->rewind_handle = CreateFiber(default_stack_size, &RewindStartFunc, this);
89 SwitchToFiber(impl->rewind_handle);
90}
91
63void Fiber::YieldTo(std::shared_ptr<Fiber> from, std::shared_ptr<Fiber> to) { 92void Fiber::YieldTo(std::shared_ptr<Fiber> from, std::shared_ptr<Fiber> to) {
64 ASSERT_MSG(from != nullptr, "Yielding fiber is null!"); 93 ASSERT_MSG(from != nullptr, "Yielding fiber is null!");
65 ASSERT_MSG(to != nullptr, "Next fiber is null!"); 94 ASSERT_MSG(to != nullptr, "Next fiber is null!");
@@ -81,7 +110,6 @@ std::shared_ptr<Fiber> Fiber::ThreadToFiber() {
81} 110}
82 111
83#else 112#else
84constexpr std::size_t default_stack_size = 1024 * 1024; // 1MB
85 113
86struct Fiber::FiberImpl { 114struct Fiber::FiberImpl {
87 alignas(64) std::array<u8, default_stack_size> stack; 115 alignas(64) std::array<u8, default_stack_size> stack;