diff options
| author | 2020-02-27 16:32:47 -0400 | |
|---|---|---|
| committer | 2020-06-18 16:29:25 -0400 | |
| commit | 137d862d9b275209b3d62a413396a15e9e14b4b4 (patch) | |
| tree | b2cdf3e5ac626e5c054c1df190b9371a11d2d694 /src/common/fiber.cpp | |
| parent | Common/Fiber: Additional corrections to f_context. (diff) | |
| download | yuzu-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.cpp | 32 |
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 | ||
| 13 | namespace Common { | 13 | namespace Common { |
| 14 | 14 | ||
| 15 | constexpr std::size_t default_stack_size = 256 * 1024; // 256kb | ||
| 16 | |||
| 15 | #if defined(_WIN32) || defined(WIN32) | 17 | #if defined(_WIN32) || defined(WIN32) |
| 16 | 18 | ||
| 17 | struct Fiber::FiberImpl { | 19 | struct Fiber::FiberImpl { |
| 18 | LPVOID handle = nullptr; | 20 | LPVOID handle = nullptr; |
| 21 | LPVOID rewind_handle = nullptr; | ||
| 19 | }; | 22 | }; |
| 20 | 23 | ||
| 21 | void Fiber::start() { | 24 | void Fiber::start() { |
| @@ -26,15 +29,29 @@ void Fiber::start() { | |||
| 26 | UNREACHABLE(); | 29 | UNREACHABLE(); |
| 27 | } | 30 | } |
| 28 | 31 | ||
| 32 | void 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 | |||
| 29 | void __stdcall Fiber::FiberStartFunc(void* fiber_parameter) { | 41 | void __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 | ||
| 46 | void __stdcall Fiber::RewindStartFunc(void* fiber_parameter) { | ||
| 47 | auto fiber = static_cast<Fiber*>(fiber_parameter); | ||
| 48 | fiber->onRewind(); | ||
| 49 | } | ||
| 50 | |||
| 34 | Fiber::Fiber(std::function<void(void*)>&& entry_point_func, void* start_parameter) | 51 | Fiber::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 | ||
| 40 | Fiber::Fiber() { | 57 | Fiber::Fiber() { |
| @@ -60,6 +77,18 @@ void Fiber::Exit() { | |||
| 60 | guard.unlock(); | 77 | guard.unlock(); |
| 61 | } | 78 | } |
| 62 | 79 | ||
| 80 | void 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 | |||
| 85 | void 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 | |||
| 63 | void Fiber::YieldTo(std::shared_ptr<Fiber> from, std::shared_ptr<Fiber> to) { | 92 | void 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 |
| 84 | constexpr std::size_t default_stack_size = 1024 * 1024; // 1MB | ||
| 85 | 113 | ||
| 86 | struct Fiber::FiberImpl { | 114 | struct Fiber::FiberImpl { |
| 87 | alignas(64) std::array<u8, default_stack_size> stack; | 115 | alignas(64) std::array<u8, default_stack_size> stack; |