diff options
| -rw-r--r-- | src/common/fiber.cpp | 14 | ||||
| -rw-r--r-- | src/common/fiber.h | 4 | ||||
| -rw-r--r-- | src/core/cpu_manager.cpp | 11 | ||||
| -rw-r--r-- | src/core/cpu_manager.h | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_scheduler.cpp | 18 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_scheduler.h | 10 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_thread.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_thread.h | 10 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 3 | ||||
| -rw-r--r-- | src/tests/common/fibers.cpp | 39 |
10 files changed, 59 insertions, 58 deletions
diff --git a/src/common/fiber.cpp b/src/common/fiber.cpp index b8e98b12a..3c1eefcb7 100644 --- a/src/common/fiber.cpp +++ b/src/common/fiber.cpp | |||
| @@ -24,7 +24,7 @@ struct Fiber::FiberImpl { | |||
| 24 | std::function<void(void*)> rewind_point; | 24 | std::function<void(void*)> rewind_point; |
| 25 | void* rewind_parameter{}; | 25 | void* rewind_parameter{}; |
| 26 | void* start_parameter{}; | 26 | void* start_parameter{}; |
| 27 | Fiber* previous_fiber; | 27 | std::shared_ptr<Fiber> previous_fiber; |
| 28 | bool is_thread_fiber{}; | 28 | bool is_thread_fiber{}; |
| 29 | bool released{}; | 29 | bool released{}; |
| 30 | 30 | ||
| @@ -47,7 +47,7 @@ void Fiber::Start(boost::context::detail::transfer_t& transfer) { | |||
| 47 | ASSERT(impl->previous_fiber != nullptr); | 47 | ASSERT(impl->previous_fiber != nullptr); |
| 48 | impl->previous_fiber->impl->context = transfer.fctx; | 48 | impl->previous_fiber->impl->context = transfer.fctx; |
| 49 | impl->previous_fiber->impl->guard.unlock(); | 49 | impl->previous_fiber->impl->guard.unlock(); |
| 50 | impl->previous_fiber = nullptr; | 50 | impl->previous_fiber.reset(); |
| 51 | impl->entry_point(impl->start_parameter); | 51 | impl->entry_point(impl->start_parameter); |
| 52 | UNREACHABLE(); | 52 | UNREACHABLE(); |
| 53 | } | 53 | } |
| @@ -116,20 +116,20 @@ void Fiber::Rewind() { | |||
| 116 | boost::context::detail::jump_fcontext(impl->rewind_context, this); | 116 | boost::context::detail::jump_fcontext(impl->rewind_context, this); |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | void Fiber::YieldTo(Fiber* from, Fiber* to) { | 119 | void Fiber::YieldTo(std::shared_ptr<Fiber> from, std::shared_ptr<Fiber> to) { |
| 120 | ASSERT_MSG(from != nullptr, "Yielding fiber is null!"); | 120 | ASSERT_MSG(from != nullptr, "Yielding fiber is null!"); |
| 121 | ASSERT_MSG(to != nullptr, "Next fiber is null!"); | 121 | ASSERT_MSG(to != nullptr, "Next fiber is null!"); |
| 122 | to->impl->guard.lock(); | 122 | to->impl->guard.lock(); |
| 123 | to->impl->previous_fiber = from; | 123 | to->impl->previous_fiber = from; |
| 124 | auto transfer = boost::context::detail::jump_fcontext(to->impl->context, to); | 124 | auto transfer = boost::context::detail::jump_fcontext(to->impl->context, to.get()); |
| 125 | ASSERT(from->impl->previous_fiber != nullptr); | 125 | ASSERT(from->impl->previous_fiber != nullptr); |
| 126 | from->impl->previous_fiber->impl->context = transfer.fctx; | 126 | from->impl->previous_fiber->impl->context = transfer.fctx; |
| 127 | from->impl->previous_fiber->impl->guard.unlock(); | 127 | from->impl->previous_fiber->impl->guard.unlock(); |
| 128 | from->impl->previous_fiber = nullptr; | 128 | from->impl->previous_fiber.reset(); |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | std::unique_ptr<Fiber> Fiber::ThreadToFiber() { | 131 | std::shared_ptr<Fiber> Fiber::ThreadToFiber() { |
| 132 | std::unique_ptr<Fiber> fiber = std::unique_ptr<Fiber>{new Fiber()}; | 132 | std::shared_ptr<Fiber> fiber = std::shared_ptr<Fiber>{new Fiber()}; |
| 133 | fiber->impl->guard.lock(); | 133 | fiber->impl->guard.lock(); |
| 134 | fiber->impl->is_thread_fiber = true; | 134 | fiber->impl->is_thread_fiber = true; |
| 135 | return fiber; | 135 | return fiber; |
diff --git a/src/common/fiber.h b/src/common/fiber.h index 6924f7996..f7f587f8c 100644 --- a/src/common/fiber.h +++ b/src/common/fiber.h | |||
| @@ -41,8 +41,8 @@ public: | |||
| 41 | 41 | ||
| 42 | /// Yields control from Fiber 'from' to Fiber 'to' | 42 | /// Yields control from Fiber 'from' to Fiber 'to' |
| 43 | /// Fiber 'from' must be the currently running fiber. | 43 | /// Fiber 'from' must be the currently running fiber. |
| 44 | static void YieldTo(Fiber* from, Fiber* to); | 44 | static void YieldTo(std::shared_ptr<Fiber> from, std::shared_ptr<Fiber> to); |
| 45 | [[nodiscard]] static std::unique_ptr<Fiber> ThreadToFiber(); | 45 | [[nodiscard]] static std::shared_ptr<Fiber> ThreadToFiber(); |
| 46 | 46 | ||
| 47 | void SetRewindPoint(std::function<void(void*)>&& rewind_func, void* rewind_param); | 47 | void SetRewindPoint(std::function<void(void*)>&& rewind_func, void* rewind_param); |
| 48 | 48 | ||
diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp index c35438c6f..8f04fb8f5 100644 --- a/src/core/cpu_manager.cpp +++ b/src/core/cpu_manager.cpp | |||
| @@ -111,7 +111,7 @@ void CpuManager::MultiCoreRunGuestThread() { | |||
| 111 | auto& kernel = system.Kernel(); | 111 | auto& kernel = system.Kernel(); |
| 112 | kernel.CurrentScheduler()->OnThreadStart(); | 112 | kernel.CurrentScheduler()->OnThreadStart(); |
| 113 | auto* thread = kernel.CurrentScheduler()->GetCurrentThread(); | 113 | auto* thread = kernel.CurrentScheduler()->GetCurrentThread(); |
| 114 | auto host_context = thread->GetHostContext(); | 114 | auto& host_context = thread->GetHostContext(); |
| 115 | host_context->SetRewindPoint(GuestRewindFunction, this); | 115 | host_context->SetRewindPoint(GuestRewindFunction, this); |
| 116 | MultiCoreRunGuestLoop(); | 116 | MultiCoreRunGuestLoop(); |
| 117 | } | 117 | } |
| @@ -148,8 +148,7 @@ void CpuManager::MultiCoreRunSuspendThread() { | |||
| 148 | auto core = kernel.GetCurrentHostThreadID(); | 148 | auto core = kernel.GetCurrentHostThreadID(); |
| 149 | auto& scheduler = *kernel.CurrentScheduler(); | 149 | auto& scheduler = *kernel.CurrentScheduler(); |
| 150 | Kernel::KThread* current_thread = scheduler.GetCurrentThread(); | 150 | Kernel::KThread* current_thread = scheduler.GetCurrentThread(); |
| 151 | Common::Fiber::YieldTo(current_thread->GetHostContext(), | 151 | Common::Fiber::YieldTo(current_thread->GetHostContext(), core_data[core].host_context); |
| 152 | core_data[core].host_context.get()); | ||
| 153 | ASSERT(scheduler.ContextSwitchPending()); | 152 | ASSERT(scheduler.ContextSwitchPending()); |
| 154 | ASSERT(core == kernel.GetCurrentHostThreadID()); | 153 | ASSERT(core == kernel.GetCurrentHostThreadID()); |
| 155 | scheduler.RescheduleCurrentCore(); | 154 | scheduler.RescheduleCurrentCore(); |
| @@ -202,7 +201,7 @@ void CpuManager::SingleCoreRunGuestThread() { | |||
| 202 | auto& kernel = system.Kernel(); | 201 | auto& kernel = system.Kernel(); |
| 203 | kernel.CurrentScheduler()->OnThreadStart(); | 202 | kernel.CurrentScheduler()->OnThreadStart(); |
| 204 | auto* thread = kernel.CurrentScheduler()->GetCurrentThread(); | 203 | auto* thread = kernel.CurrentScheduler()->GetCurrentThread(); |
| 205 | auto host_context = thread->GetHostContext(); | 204 | auto& host_context = thread->GetHostContext(); |
| 206 | host_context->SetRewindPoint(GuestRewindFunction, this); | 205 | host_context->SetRewindPoint(GuestRewindFunction, this); |
| 207 | SingleCoreRunGuestLoop(); | 206 | SingleCoreRunGuestLoop(); |
| 208 | } | 207 | } |
| @@ -246,7 +245,7 @@ void CpuManager::SingleCoreRunSuspendThread() { | |||
| 246 | auto core = kernel.GetCurrentHostThreadID(); | 245 | auto core = kernel.GetCurrentHostThreadID(); |
| 247 | auto& scheduler = *kernel.CurrentScheduler(); | 246 | auto& scheduler = *kernel.CurrentScheduler(); |
| 248 | Kernel::KThread* current_thread = scheduler.GetCurrentThread(); | 247 | Kernel::KThread* current_thread = scheduler.GetCurrentThread(); |
| 249 | Common::Fiber::YieldTo(current_thread->GetHostContext(), core_data[0].host_context.get()); | 248 | Common::Fiber::YieldTo(current_thread->GetHostContext(), core_data[0].host_context); |
| 250 | ASSERT(scheduler.ContextSwitchPending()); | 249 | ASSERT(scheduler.ContextSwitchPending()); |
| 251 | ASSERT(core == kernel.GetCurrentHostThreadID()); | 250 | ASSERT(core == kernel.GetCurrentHostThreadID()); |
| 252 | scheduler.RescheduleCurrentCore(); | 251 | scheduler.RescheduleCurrentCore(); |
| @@ -364,7 +363,7 @@ void CpuManager::RunThread(std::size_t core) { | |||
| 364 | 363 | ||
| 365 | auto current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread(); | 364 | auto current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread(); |
| 366 | data.is_running = true; | 365 | data.is_running = true; |
| 367 | Common::Fiber::YieldTo(data.host_context.get(), current_thread->GetHostContext()); | 366 | Common::Fiber::YieldTo(data.host_context, current_thread->GetHostContext()); |
| 368 | data.is_running = false; | 367 | data.is_running = false; |
| 369 | data.is_paused = true; | 368 | data.is_paused = true; |
| 370 | data.exit_barrier->Wait(); | 369 | data.exit_barrier->Wait(); |
diff --git a/src/core/cpu_manager.h b/src/core/cpu_manager.h index 5ea149f1f..17420c941 100644 --- a/src/core/cpu_manager.h +++ b/src/core/cpu_manager.h | |||
| @@ -83,7 +83,7 @@ private: | |||
| 83 | void RunThread(std::size_t core); | 83 | void RunThread(std::size_t core); |
| 84 | 84 | ||
| 85 | struct CoreData { | 85 | struct CoreData { |
| 86 | std::unique_ptr<Common::Fiber> host_context; | 86 | std::shared_ptr<Common::Fiber> host_context; |
| 87 | std::unique_ptr<Common::Event> enter_barrier; | 87 | std::unique_ptr<Common::Event> enter_barrier; |
| 88 | std::unique_ptr<Common::Event> exit_barrier; | 88 | std::unique_ptr<Common::Event> exit_barrier; |
| 89 | std::atomic<bool> is_running; | 89 | std::atomic<bool> is_running; |
diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp index 465036f3d..bb5f43b53 100644 --- a/src/core/hle/kernel/k_scheduler.cpp +++ b/src/core/hle/kernel/k_scheduler.cpp | |||
| @@ -608,7 +608,7 @@ void KScheduler::YieldToAnyThread(KernelCore& kernel) { | |||
| 608 | } | 608 | } |
| 609 | 609 | ||
| 610 | KScheduler::KScheduler(Core::System& system, s32 core_id) : system(system), core_id(core_id) { | 610 | KScheduler::KScheduler(Core::System& system, s32 core_id) : system(system), core_id(core_id) { |
| 611 | switch_fiber = std::make_unique<Common::Fiber>(OnSwitch, this); | 611 | switch_fiber = std::make_shared<Common::Fiber>(OnSwitch, this); |
| 612 | state.needs_scheduling.store(true); | 612 | state.needs_scheduling.store(true); |
| 613 | state.interrupt_task_thread_runnable = false; | 613 | state.interrupt_task_thread_runnable = false; |
| 614 | state.should_count_idle = false; | 614 | state.should_count_idle = false; |
| @@ -726,15 +726,15 @@ void KScheduler::ScheduleImpl() { | |||
| 726 | // Save context for previous thread | 726 | // Save context for previous thread |
| 727 | Unload(previous_thread); | 727 | Unload(previous_thread); |
| 728 | 728 | ||
| 729 | Common::Fiber* old_context; | 729 | std::shared_ptr<Common::Fiber>* old_context; |
| 730 | if (previous_thread != nullptr) { | 730 | if (previous_thread != nullptr) { |
| 731 | old_context = previous_thread->GetHostContext(); | 731 | old_context = &previous_thread->GetHostContext(); |
| 732 | } else { | 732 | } else { |
| 733 | old_context = idle_thread->GetHostContext(); | 733 | old_context = &idle_thread->GetHostContext(); |
| 734 | } | 734 | } |
| 735 | guard.unlock(); | 735 | guard.unlock(); |
| 736 | 736 | ||
| 737 | Common::Fiber::YieldTo(old_context, switch_fiber.get()); | 737 | Common::Fiber::YieldTo(*old_context, switch_fiber); |
| 738 | /// When a thread wakes up, the scheduler may have changed to other in another core. | 738 | /// When a thread wakes up, the scheduler may have changed to other in another core. |
| 739 | auto& next_scheduler = *system.Kernel().CurrentScheduler(); | 739 | auto& next_scheduler = *system.Kernel().CurrentScheduler(); |
| 740 | next_scheduler.SwitchContextStep2(); | 740 | next_scheduler.SwitchContextStep2(); |
| @@ -769,13 +769,13 @@ void KScheduler::SwitchToCurrent() { | |||
| 769 | break; | 769 | break; |
| 770 | } | 770 | } |
| 771 | } | 771 | } |
| 772 | Common::Fiber* next_context; | 772 | std::shared_ptr<Common::Fiber>* next_context; |
| 773 | if (next_thread != nullptr) { | 773 | if (next_thread != nullptr) { |
| 774 | next_context = next_thread->GetHostContext(); | 774 | next_context = &next_thread->GetHostContext(); |
| 775 | } else { | 775 | } else { |
| 776 | next_context = idle_thread->GetHostContext(); | 776 | next_context = &idle_thread->GetHostContext(); |
| 777 | } | 777 | } |
| 778 | Common::Fiber::YieldTo(switch_fiber.get(), next_context); | 778 | Common::Fiber::YieldTo(switch_fiber, *next_context); |
| 779 | } while (!is_switch_pending()); | 779 | } while (!is_switch_pending()); |
| 780 | } | 780 | } |
| 781 | } | 781 | } |
diff --git a/src/core/hle/kernel/k_scheduler.h b/src/core/hle/kernel/k_scheduler.h index a4285c595..f595b9a5c 100644 --- a/src/core/hle/kernel/k_scheduler.h +++ b/src/core/hle/kernel/k_scheduler.h | |||
| @@ -68,12 +68,12 @@ public: | |||
| 68 | 68 | ||
| 69 | void OnThreadStart(); | 69 | void OnThreadStart(); |
| 70 | 70 | ||
| 71 | [[nodiscard]] Common::Fiber* ControlContext() { | 71 | [[nodiscard]] std::shared_ptr<Common::Fiber>& ControlContext() { |
| 72 | return switch_fiber.get(); | 72 | return switch_fiber; |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | [[nodiscard]] const Common::Fiber* ControlContext() const { | 75 | [[nodiscard]] const std::shared_ptr<Common::Fiber>& ControlContext() const { |
| 76 | return switch_fiber.get(); | 76 | return switch_fiber; |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | [[nodiscard]] u64 UpdateHighestPriorityThread(KThread* highest_thread); | 79 | [[nodiscard]] u64 UpdateHighestPriorityThread(KThread* highest_thread); |
| @@ -178,7 +178,7 @@ private: | |||
| 178 | 178 | ||
| 179 | KThread* idle_thread; | 179 | KThread* idle_thread; |
| 180 | 180 | ||
| 181 | std::unique_ptr<Common::Fiber> switch_fiber{}; | 181 | std::shared_ptr<Common::Fiber> switch_fiber{}; |
| 182 | 182 | ||
| 183 | struct SchedulingState { | 183 | struct SchedulingState { |
| 184 | std::atomic<bool> needs_scheduling; | 184 | std::atomic<bool> needs_scheduling; |
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index f49e31b72..1661afbd9 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp | |||
| @@ -991,6 +991,10 @@ void KThread::SetState(ThreadState state) { | |||
| 991 | } | 991 | } |
| 992 | } | 992 | } |
| 993 | 993 | ||
| 994 | std::shared_ptr<Common::Fiber>& KThread::GetHostContext() { | ||
| 995 | return host_context; | ||
| 996 | } | ||
| 997 | |||
| 994 | ResultVal<std::shared_ptr<KThread>> KThread::Create(Core::System& system, ThreadType type_flags, | 998 | ResultVal<std::shared_ptr<KThread>> KThread::Create(Core::System& system, ThreadType type_flags, |
| 995 | std::string name, VAddr entry_point, | 999 | std::string name, VAddr entry_point, |
| 996 | u32 priority, u64 arg, s32 processor_id, | 1000 | u32 priority, u64 arg, s32 processor_id, |
| @@ -1024,7 +1028,7 @@ ResultVal<std::shared_ptr<KThread>> KThread::Create(Core::System& system, Thread | |||
| 1024 | scheduler.AddThread(thread); | 1028 | scheduler.AddThread(thread); |
| 1025 | 1029 | ||
| 1026 | thread->host_context = | 1030 | thread->host_context = |
| 1027 | std::make_unique<Common::Fiber>(std::move(thread_start_func), thread_start_parameter); | 1031 | std::make_shared<Common::Fiber>(std::move(thread_start_func), thread_start_parameter); |
| 1028 | 1032 | ||
| 1029 | return MakeResult<std::shared_ptr<KThread>>(std::move(thread)); | 1033 | return MakeResult<std::shared_ptr<KThread>>(std::move(thread)); |
| 1030 | } | 1034 | } |
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h index a2893d939..c8ac656a4 100644 --- a/src/core/hle/kernel/k_thread.h +++ b/src/core/hle/kernel/k_thread.h | |||
| @@ -293,13 +293,7 @@ public: | |||
| 293 | return thread_context_64; | 293 | return thread_context_64; |
| 294 | } | 294 | } |
| 295 | 295 | ||
| 296 | [[nodiscard]] Common::Fiber* GetHostContext() { | 296 | [[nodiscard]] std::shared_ptr<Common::Fiber>& GetHostContext(); |
| 297 | return host_context.get(); | ||
| 298 | } | ||
| 299 | |||
| 300 | [[nodiscard]] const Common::Fiber* GetHostContext() const { | ||
| 301 | return host_context.get(); | ||
| 302 | } | ||
| 303 | 297 | ||
| 304 | [[nodiscard]] ThreadState GetState() const { | 298 | [[nodiscard]] ThreadState GetState() const { |
| 305 | return thread_state & ThreadState::Mask; | 299 | return thread_state & ThreadState::Mask; |
| @@ -725,7 +719,7 @@ private: | |||
| 725 | Common::SpinLock context_guard{}; | 719 | Common::SpinLock context_guard{}; |
| 726 | 720 | ||
| 727 | // For emulation | 721 | // For emulation |
| 728 | std::unique_ptr<Common::Fiber> host_context{}; | 722 | std::shared_ptr<Common::Fiber> host_context{}; |
| 729 | 723 | ||
| 730 | // For debugging | 724 | // For debugging |
| 731 | std::vector<KSynchronizationObject*> wait_objects_for_debugging; | 725 | std::vector<KSynchronizationObject*> wait_objects_for_debugging; |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index d04116115..cc8fa6576 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -2626,7 +2626,8 @@ void Call(Core::System& system, u32 immediate) { | |||
| 2626 | kernel.ExitSVCProfile(); | 2626 | kernel.ExitSVCProfile(); |
| 2627 | 2627 | ||
| 2628 | if (!thread->IsCallingSvc()) { | 2628 | if (!thread->IsCallingSvc()) { |
| 2629 | thread->GetHostContext()->Rewind(); | 2629 | auto* host_context = thread->GetHostContext().get(); |
| 2630 | host_context->Rewind(); | ||
| 2630 | } | 2631 | } |
| 2631 | 2632 | ||
| 2632 | system.EnterDynarmicProfile(); | 2633 | system.EnterDynarmicProfile(); |
diff --git a/src/tests/common/fibers.cpp b/src/tests/common/fibers.cpp index b2ded2065..d94492fc6 100644 --- a/src/tests/common/fibers.cpp +++ b/src/tests/common/fibers.cpp | |||
| @@ -67,15 +67,16 @@ void TestControl1::DoWork() { | |||
| 67 | value++; | 67 | value++; |
| 68 | } | 68 | } |
| 69 | results[id] = value; | 69 | results[id] = value; |
| 70 | Fiber::YieldTo(work_fibers[id].get(), thread_fibers[id].get()); | 70 | Fiber::YieldTo(work_fibers[id], thread_fibers[id]); |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | void TestControl1::ExecuteThread(u32 id) { | 73 | void TestControl1::ExecuteThread(u32 id) { |
| 74 | thread_ids.Register(id); | 74 | thread_ids.Register(id); |
| 75 | thread_fibers[id] = Fiber::ThreadToFiber(); | 75 | auto thread_fiber = Fiber::ThreadToFiber(); |
| 76 | thread_fibers[id] = thread_fiber; | ||
| 76 | work_fibers[id] = std::make_shared<Fiber>(std::function<void(void*)>{WorkControl1}, this); | 77 | work_fibers[id] = std::make_shared<Fiber>(std::function<void(void*)>{WorkControl1}, this); |
| 77 | items[id] = rand() % 256; | 78 | items[id] = rand() % 256; |
| 78 | Fiber::YieldTo(thread_fibers[id].get(), work_fibers[id].get()); | 79 | Fiber::YieldTo(thread_fibers[id], work_fibers[id]); |
| 79 | thread_fibers[id]->Exit(); | 80 | thread_fibers[id]->Exit(); |
| 80 | } | 81 | } |
| 81 | 82 | ||
| @@ -116,11 +117,11 @@ public: | |||
| 116 | for (u32 i = 0; i < 12000; i++) { | 117 | for (u32 i = 0; i < 12000; i++) { |
| 117 | value1 += i; | 118 | value1 += i; |
| 118 | } | 119 | } |
| 119 | Fiber::YieldTo(fiber1.get(), fiber3.get()); | 120 | Fiber::YieldTo(fiber1, fiber3); |
| 120 | const u32 id = thread_ids.Get(); | 121 | const u32 id = thread_ids.Get(); |
| 121 | assert1 = id == 1; | 122 | assert1 = id == 1; |
| 122 | value2 += 5000; | 123 | value2 += 5000; |
| 123 | Fiber::YieldTo(fiber1.get(), thread_fibers[id].get()); | 124 | Fiber::YieldTo(fiber1, thread_fibers[id]); |
| 124 | } | 125 | } |
| 125 | 126 | ||
| 126 | void DoWork2() { | 127 | void DoWork2() { |
| @@ -128,7 +129,7 @@ public: | |||
| 128 | ; | 129 | ; |
| 129 | value2 = 2000; | 130 | value2 = 2000; |
| 130 | trap = false; | 131 | trap = false; |
| 131 | Fiber::YieldTo(fiber2.get(), fiber1.get()); | 132 | Fiber::YieldTo(fiber2, fiber1); |
| 132 | assert3 = false; | 133 | assert3 = false; |
| 133 | } | 134 | } |
| 134 | 135 | ||
| @@ -136,19 +137,19 @@ public: | |||
| 136 | const u32 id = thread_ids.Get(); | 137 | const u32 id = thread_ids.Get(); |
| 137 | assert2 = id == 0; | 138 | assert2 = id == 0; |
| 138 | value1 += 1000; | 139 | value1 += 1000; |
| 139 | Fiber::YieldTo(fiber3.get(), thread_fibers[id].get()); | 140 | Fiber::YieldTo(fiber3, thread_fibers[id]); |
| 140 | } | 141 | } |
| 141 | 142 | ||
| 142 | void ExecuteThread(u32 id); | 143 | void ExecuteThread(u32 id); |
| 143 | 144 | ||
| 144 | void CallFiber1() { | 145 | void CallFiber1() { |
| 145 | const u32 id = thread_ids.Get(); | 146 | const u32 id = thread_ids.Get(); |
| 146 | Fiber::YieldTo(thread_fibers[id].get(), fiber1.get()); | 147 | Fiber::YieldTo(thread_fibers[id], fiber1); |
| 147 | } | 148 | } |
| 148 | 149 | ||
| 149 | void CallFiber2() { | 150 | void CallFiber2() { |
| 150 | const u32 id = thread_ids.Get(); | 151 | const u32 id = thread_ids.Get(); |
| 151 | Fiber::YieldTo(thread_fibers[id].get(), fiber2.get()); | 152 | Fiber::YieldTo(thread_fibers[id], fiber2); |
| 152 | } | 153 | } |
| 153 | 154 | ||
| 154 | void Exit(); | 155 | void Exit(); |
| @@ -184,7 +185,8 @@ static void WorkControl2_3(void* control) { | |||
| 184 | 185 | ||
| 185 | void TestControl2::ExecuteThread(u32 id) { | 186 | void TestControl2::ExecuteThread(u32 id) { |
| 186 | thread_ids.Register(id); | 187 | thread_ids.Register(id); |
| 187 | thread_fibers[id] = Fiber::ThreadToFiber(); | 188 | auto thread_fiber = Fiber::ThreadToFiber(); |
| 189 | thread_fibers[id] = thread_fiber; | ||
| 188 | } | 190 | } |
| 189 | 191 | ||
| 190 | void TestControl2::Exit() { | 192 | void TestControl2::Exit() { |
| @@ -239,23 +241,23 @@ public: | |||
| 239 | 241 | ||
| 240 | void DoWork1() { | 242 | void DoWork1() { |
| 241 | value1 += 1; | 243 | value1 += 1; |
| 242 | Fiber::YieldTo(fiber1.get(), fiber2.get()); | 244 | Fiber::YieldTo(fiber1, fiber2); |
| 243 | const u32 id = thread_ids.Get(); | 245 | const u32 id = thread_ids.Get(); |
| 244 | value3 += 1; | 246 | value3 += 1; |
| 245 | Fiber::YieldTo(fiber1.get(), thread_fibers[id].get()); | 247 | Fiber::YieldTo(fiber1, thread_fibers[id]); |
| 246 | } | 248 | } |
| 247 | 249 | ||
| 248 | void DoWork2() { | 250 | void DoWork2() { |
| 249 | value2 += 1; | 251 | value2 += 1; |
| 250 | const u32 id = thread_ids.Get(); | 252 | const u32 id = thread_ids.Get(); |
| 251 | Fiber::YieldTo(fiber2.get(), thread_fibers[id].get()); | 253 | Fiber::YieldTo(fiber2, thread_fibers[id]); |
| 252 | } | 254 | } |
| 253 | 255 | ||
| 254 | void ExecuteThread(u32 id); | 256 | void ExecuteThread(u32 id); |
| 255 | 257 | ||
| 256 | void CallFiber1() { | 258 | void CallFiber1() { |
| 257 | const u32 id = thread_ids.Get(); | 259 | const u32 id = thread_ids.Get(); |
| 258 | Fiber::YieldTo(thread_fibers[id].get(), fiber1.get()); | 260 | Fiber::YieldTo(thread_fibers[id], fiber1); |
| 259 | } | 261 | } |
| 260 | 262 | ||
| 261 | void Exit(); | 263 | void Exit(); |
| @@ -264,7 +266,7 @@ public: | |||
| 264 | u32 value2{}; | 266 | u32 value2{}; |
| 265 | u32 value3{}; | 267 | u32 value3{}; |
| 266 | ThreadIds thread_ids; | 268 | ThreadIds thread_ids; |
| 267 | std::vector<std::unique_ptr<Common::Fiber>> thread_fibers; | 269 | std::vector<std::shared_ptr<Common::Fiber>> thread_fibers; |
| 268 | std::shared_ptr<Common::Fiber> fiber1; | 270 | std::shared_ptr<Common::Fiber> fiber1; |
| 269 | std::shared_ptr<Common::Fiber> fiber2; | 271 | std::shared_ptr<Common::Fiber> fiber2; |
| 270 | }; | 272 | }; |
| @@ -281,7 +283,8 @@ static void WorkControl3_2(void* control) { | |||
| 281 | 283 | ||
| 282 | void TestControl3::ExecuteThread(u32 id) { | 284 | void TestControl3::ExecuteThread(u32 id) { |
| 283 | thread_ids.Register(id); | 285 | thread_ids.Register(id); |
| 284 | thread_fibers[id] = Fiber::ThreadToFiber(); | 286 | auto thread_fiber = Fiber::ThreadToFiber(); |
| 287 | thread_fibers[id] = thread_fiber; | ||
| 285 | } | 288 | } |
| 286 | 289 | ||
| 287 | void TestControl3::Exit() { | 290 | void TestControl3::Exit() { |
| @@ -329,7 +332,7 @@ public: | |||
| 329 | 332 | ||
| 330 | void Execute() { | 333 | void Execute() { |
| 331 | thread_fiber = Fiber::ThreadToFiber(); | 334 | thread_fiber = Fiber::ThreadToFiber(); |
| 332 | Fiber::YieldTo(thread_fiber.get(), fiber1.get()); | 335 | Fiber::YieldTo(thread_fiber, fiber1); |
| 333 | thread_fiber->Exit(); | 336 | thread_fiber->Exit(); |
| 334 | } | 337 | } |
| 335 | 338 | ||
| @@ -337,7 +340,7 @@ public: | |||
| 337 | fiber1->SetRewindPoint(std::function<void(void*)>{WorkControl4}, this); | 340 | fiber1->SetRewindPoint(std::function<void(void*)>{WorkControl4}, this); |
| 338 | if (rewinded) { | 341 | if (rewinded) { |
| 339 | goal_reached = true; | 342 | goal_reached = true; |
| 340 | Fiber::YieldTo(fiber1.get(), thread_fiber.get()); | 343 | Fiber::YieldTo(fiber1, thread_fiber); |
| 341 | } | 344 | } |
| 342 | rewinded = true; | 345 | rewinded = true; |
| 343 | fiber1->Rewind(); | 346 | fiber1->Rewind(); |