Merge pull request #6039 from yuzu-emu/revert-6006-fiber-unique-ptr
Revert "core: Switch to unique_ptr for usage of Common::Fiber."
This commit is contained in:
		| @@ -24,7 +24,7 @@ struct Fiber::FiberImpl { | ||||
|     std::function<void(void*)> rewind_point; | ||||
|     void* rewind_parameter{}; | ||||
|     void* start_parameter{}; | ||||
|     Fiber* previous_fiber; | ||||
|     std::shared_ptr<Fiber> previous_fiber; | ||||
|     bool is_thread_fiber{}; | ||||
|     bool released{}; | ||||
|  | ||||
| @@ -47,7 +47,7 @@ void Fiber::Start(boost::context::detail::transfer_t& transfer) { | ||||
|     ASSERT(impl->previous_fiber != nullptr); | ||||
|     impl->previous_fiber->impl->context = transfer.fctx; | ||||
|     impl->previous_fiber->impl->guard.unlock(); | ||||
|     impl->previous_fiber = nullptr; | ||||
|     impl->previous_fiber.reset(); | ||||
|     impl->entry_point(impl->start_parameter); | ||||
|     UNREACHABLE(); | ||||
| } | ||||
| @@ -116,20 +116,20 @@ void Fiber::Rewind() { | ||||
|     boost::context::detail::jump_fcontext(impl->rewind_context, this); | ||||
| } | ||||
|  | ||||
| void Fiber::YieldTo(Fiber* from, Fiber* to) { | ||||
| void Fiber::YieldTo(std::shared_ptr<Fiber> from, std::shared_ptr<Fiber> to) { | ||||
|     ASSERT_MSG(from != nullptr, "Yielding fiber is null!"); | ||||
|     ASSERT_MSG(to != nullptr, "Next fiber is null!"); | ||||
|     to->impl->guard.lock(); | ||||
|     to->impl->previous_fiber = from; | ||||
|     auto transfer = boost::context::detail::jump_fcontext(to->impl->context, to); | ||||
|     auto transfer = boost::context::detail::jump_fcontext(to->impl->context, to.get()); | ||||
|     ASSERT(from->impl->previous_fiber != nullptr); | ||||
|     from->impl->previous_fiber->impl->context = transfer.fctx; | ||||
|     from->impl->previous_fiber->impl->guard.unlock(); | ||||
|     from->impl->previous_fiber = nullptr; | ||||
|     from->impl->previous_fiber.reset(); | ||||
| } | ||||
|  | ||||
| std::unique_ptr<Fiber> Fiber::ThreadToFiber() { | ||||
|     std::unique_ptr<Fiber> fiber = std::unique_ptr<Fiber>{new Fiber()}; | ||||
| std::shared_ptr<Fiber> Fiber::ThreadToFiber() { | ||||
|     std::shared_ptr<Fiber> fiber = std::shared_ptr<Fiber>{new Fiber()}; | ||||
|     fiber->impl->guard.lock(); | ||||
|     fiber->impl->is_thread_fiber = true; | ||||
|     return fiber; | ||||
|   | ||||
| @@ -41,8 +41,8 @@ public: | ||||
|  | ||||
|     /// Yields control from Fiber 'from' to Fiber 'to' | ||||
|     /// Fiber 'from' must be the currently running fiber. | ||||
|     static void YieldTo(Fiber* from, Fiber* to); | ||||
|     [[nodiscard]] static std::unique_ptr<Fiber> ThreadToFiber(); | ||||
|     static void YieldTo(std::shared_ptr<Fiber> from, std::shared_ptr<Fiber> to); | ||||
|     [[nodiscard]] static std::shared_ptr<Fiber> ThreadToFiber(); | ||||
|  | ||||
|     void SetRewindPoint(std::function<void(void*)>&& rewind_func, void* rewind_param); | ||||
|  | ||||
|   | ||||
| @@ -111,7 +111,7 @@ void CpuManager::MultiCoreRunGuestThread() { | ||||
|     auto& kernel = system.Kernel(); | ||||
|     kernel.CurrentScheduler()->OnThreadStart(); | ||||
|     auto* thread = kernel.CurrentScheduler()->GetCurrentThread(); | ||||
|     auto host_context = thread->GetHostContext(); | ||||
|     auto& host_context = thread->GetHostContext(); | ||||
|     host_context->SetRewindPoint(GuestRewindFunction, this); | ||||
|     MultiCoreRunGuestLoop(); | ||||
| } | ||||
| @@ -148,8 +148,7 @@ void CpuManager::MultiCoreRunSuspendThread() { | ||||
|         auto core = kernel.GetCurrentHostThreadID(); | ||||
|         auto& scheduler = *kernel.CurrentScheduler(); | ||||
|         Kernel::KThread* current_thread = scheduler.GetCurrentThread(); | ||||
|         Common::Fiber::YieldTo(current_thread->GetHostContext(), | ||||
|                                core_data[core].host_context.get()); | ||||
|         Common::Fiber::YieldTo(current_thread->GetHostContext(), core_data[core].host_context); | ||||
|         ASSERT(scheduler.ContextSwitchPending()); | ||||
|         ASSERT(core == kernel.GetCurrentHostThreadID()); | ||||
|         scheduler.RescheduleCurrentCore(); | ||||
| @@ -202,7 +201,7 @@ void CpuManager::SingleCoreRunGuestThread() { | ||||
|     auto& kernel = system.Kernel(); | ||||
|     kernel.CurrentScheduler()->OnThreadStart(); | ||||
|     auto* thread = kernel.CurrentScheduler()->GetCurrentThread(); | ||||
|     auto host_context = thread->GetHostContext(); | ||||
|     auto& host_context = thread->GetHostContext(); | ||||
|     host_context->SetRewindPoint(GuestRewindFunction, this); | ||||
|     SingleCoreRunGuestLoop(); | ||||
| } | ||||
| @@ -246,7 +245,7 @@ void CpuManager::SingleCoreRunSuspendThread() { | ||||
|         auto core = kernel.GetCurrentHostThreadID(); | ||||
|         auto& scheduler = *kernel.CurrentScheduler(); | ||||
|         Kernel::KThread* current_thread = scheduler.GetCurrentThread(); | ||||
|         Common::Fiber::YieldTo(current_thread->GetHostContext(), core_data[0].host_context.get()); | ||||
|         Common::Fiber::YieldTo(current_thread->GetHostContext(), core_data[0].host_context); | ||||
|         ASSERT(scheduler.ContextSwitchPending()); | ||||
|         ASSERT(core == kernel.GetCurrentHostThreadID()); | ||||
|         scheduler.RescheduleCurrentCore(); | ||||
| @@ -364,7 +363,7 @@ void CpuManager::RunThread(std::size_t core) { | ||||
|  | ||||
|         auto current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread(); | ||||
|         data.is_running = true; | ||||
|         Common::Fiber::YieldTo(data.host_context.get(), current_thread->GetHostContext()); | ||||
|         Common::Fiber::YieldTo(data.host_context, current_thread->GetHostContext()); | ||||
|         data.is_running = false; | ||||
|         data.is_paused = true; | ||||
|         data.exit_barrier->Wait(); | ||||
|   | ||||
| @@ -83,7 +83,7 @@ private: | ||||
|     void RunThread(std::size_t core); | ||||
|  | ||||
|     struct CoreData { | ||||
|         std::unique_ptr<Common::Fiber> host_context; | ||||
|         std::shared_ptr<Common::Fiber> host_context; | ||||
|         std::unique_ptr<Common::Event> enter_barrier; | ||||
|         std::unique_ptr<Common::Event> exit_barrier; | ||||
|         std::atomic<bool> is_running; | ||||
|   | ||||
| @@ -608,7 +608,7 @@ void KScheduler::YieldToAnyThread(KernelCore& kernel) { | ||||
| } | ||||
|  | ||||
| KScheduler::KScheduler(Core::System& system, s32 core_id) : system(system), core_id(core_id) { | ||||
|     switch_fiber = std::make_unique<Common::Fiber>(OnSwitch, this); | ||||
|     switch_fiber = std::make_shared<Common::Fiber>(OnSwitch, this); | ||||
|     state.needs_scheduling.store(true); | ||||
|     state.interrupt_task_thread_runnable = false; | ||||
|     state.should_count_idle = false; | ||||
| @@ -726,15 +726,15 @@ void KScheduler::ScheduleImpl() { | ||||
|     // Save context for previous thread | ||||
|     Unload(previous_thread); | ||||
|  | ||||
|     Common::Fiber* old_context; | ||||
|     std::shared_ptr<Common::Fiber>* old_context; | ||||
|     if (previous_thread != nullptr) { | ||||
|         old_context = previous_thread->GetHostContext(); | ||||
|         old_context = &previous_thread->GetHostContext(); | ||||
|     } else { | ||||
|         old_context = idle_thread->GetHostContext(); | ||||
|         old_context = &idle_thread->GetHostContext(); | ||||
|     } | ||||
|     guard.unlock(); | ||||
|  | ||||
|     Common::Fiber::YieldTo(old_context, switch_fiber.get()); | ||||
|     Common::Fiber::YieldTo(*old_context, switch_fiber); | ||||
|     /// When a thread wakes up, the scheduler may have changed to other in another core. | ||||
|     auto& next_scheduler = *system.Kernel().CurrentScheduler(); | ||||
|     next_scheduler.SwitchContextStep2(); | ||||
| @@ -769,13 +769,13 @@ void KScheduler::SwitchToCurrent() { | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|             Common::Fiber* next_context; | ||||
|             std::shared_ptr<Common::Fiber>* next_context; | ||||
|             if (next_thread != nullptr) { | ||||
|                 next_context = next_thread->GetHostContext(); | ||||
|                 next_context = &next_thread->GetHostContext(); | ||||
|             } else { | ||||
|                 next_context = idle_thread->GetHostContext(); | ||||
|                 next_context = &idle_thread->GetHostContext(); | ||||
|             } | ||||
|             Common::Fiber::YieldTo(switch_fiber.get(), next_context); | ||||
|             Common::Fiber::YieldTo(switch_fiber, *next_context); | ||||
|         } while (!is_switch_pending()); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -68,12 +68,12 @@ public: | ||||
|  | ||||
|     void OnThreadStart(); | ||||
|  | ||||
|     [[nodiscard]] Common::Fiber* ControlContext() { | ||||
|         return switch_fiber.get(); | ||||
|     [[nodiscard]] std::shared_ptr<Common::Fiber>& ControlContext() { | ||||
|         return switch_fiber; | ||||
|     } | ||||
|  | ||||
|     [[nodiscard]] const Common::Fiber* ControlContext() const { | ||||
|         return switch_fiber.get(); | ||||
|     [[nodiscard]] const std::shared_ptr<Common::Fiber>& ControlContext() const { | ||||
|         return switch_fiber; | ||||
|     } | ||||
|  | ||||
|     [[nodiscard]] u64 UpdateHighestPriorityThread(KThread* highest_thread); | ||||
| @@ -178,7 +178,7 @@ private: | ||||
|  | ||||
|     KThread* idle_thread; | ||||
|  | ||||
|     std::unique_ptr<Common::Fiber> switch_fiber{}; | ||||
|     std::shared_ptr<Common::Fiber> switch_fiber{}; | ||||
|  | ||||
|     struct SchedulingState { | ||||
|         std::atomic<bool> needs_scheduling; | ||||
|   | ||||
| @@ -991,6 +991,10 @@ void KThread::SetState(ThreadState state) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| std::shared_ptr<Common::Fiber>& KThread::GetHostContext() { | ||||
|     return host_context; | ||||
| } | ||||
|  | ||||
| ResultVal<std::shared_ptr<KThread>> KThread::Create(Core::System& system, ThreadType type_flags, | ||||
|                                                     std::string name, VAddr entry_point, | ||||
|                                                     u32 priority, u64 arg, s32 processor_id, | ||||
| @@ -1024,7 +1028,7 @@ ResultVal<std::shared_ptr<KThread>> KThread::Create(Core::System& system, Thread | ||||
|     scheduler.AddThread(thread); | ||||
|  | ||||
|     thread->host_context = | ||||
|         std::make_unique<Common::Fiber>(std::move(thread_start_func), thread_start_parameter); | ||||
|         std::make_shared<Common::Fiber>(std::move(thread_start_func), thread_start_parameter); | ||||
|  | ||||
|     return MakeResult<std::shared_ptr<KThread>>(std::move(thread)); | ||||
| } | ||||
|   | ||||
| @@ -293,13 +293,7 @@ public: | ||||
|         return thread_context_64; | ||||
|     } | ||||
|  | ||||
|     [[nodiscard]] Common::Fiber* GetHostContext() { | ||||
|         return host_context.get(); | ||||
|     } | ||||
|  | ||||
|     [[nodiscard]] const Common::Fiber* GetHostContext() const { | ||||
|         return host_context.get(); | ||||
|     } | ||||
|     [[nodiscard]] std::shared_ptr<Common::Fiber>& GetHostContext(); | ||||
|  | ||||
|     [[nodiscard]] ThreadState GetState() const { | ||||
|         return thread_state & ThreadState::Mask; | ||||
| @@ -725,7 +719,7 @@ private: | ||||
|     Common::SpinLock context_guard{}; | ||||
|  | ||||
|     // For emulation | ||||
|     std::unique_ptr<Common::Fiber> host_context{}; | ||||
|     std::shared_ptr<Common::Fiber> host_context{}; | ||||
|  | ||||
|     // For debugging | ||||
|     std::vector<KSynchronizationObject*> wait_objects_for_debugging; | ||||
|   | ||||
| @@ -2626,7 +2626,8 @@ void Call(Core::System& system, u32 immediate) { | ||||
|     kernel.ExitSVCProfile(); | ||||
|  | ||||
|     if (!thread->IsCallingSvc()) { | ||||
|         thread->GetHostContext()->Rewind(); | ||||
|         auto* host_context = thread->GetHostContext().get(); | ||||
|         host_context->Rewind(); | ||||
|     } | ||||
|  | ||||
|     system.EnterDynarmicProfile(); | ||||
|   | ||||
| @@ -67,15 +67,16 @@ void TestControl1::DoWork() { | ||||
|         value++; | ||||
|     } | ||||
|     results[id] = value; | ||||
|     Fiber::YieldTo(work_fibers[id].get(), thread_fibers[id].get()); | ||||
|     Fiber::YieldTo(work_fibers[id], thread_fibers[id]); | ||||
| } | ||||
|  | ||||
| void TestControl1::ExecuteThread(u32 id) { | ||||
|     thread_ids.Register(id); | ||||
|     thread_fibers[id] = Fiber::ThreadToFiber(); | ||||
|     auto thread_fiber = Fiber::ThreadToFiber(); | ||||
|     thread_fibers[id] = thread_fiber; | ||||
|     work_fibers[id] = std::make_shared<Fiber>(std::function<void(void*)>{WorkControl1}, this); | ||||
|     items[id] = rand() % 256; | ||||
|     Fiber::YieldTo(thread_fibers[id].get(), work_fibers[id].get()); | ||||
|     Fiber::YieldTo(thread_fibers[id], work_fibers[id]); | ||||
|     thread_fibers[id]->Exit(); | ||||
| } | ||||
|  | ||||
| @@ -116,11 +117,11 @@ public: | ||||
|         for (u32 i = 0; i < 12000; i++) { | ||||
|             value1 += i; | ||||
|         } | ||||
|         Fiber::YieldTo(fiber1.get(), fiber3.get()); | ||||
|         Fiber::YieldTo(fiber1, fiber3); | ||||
|         const u32 id = thread_ids.Get(); | ||||
|         assert1 = id == 1; | ||||
|         value2 += 5000; | ||||
|         Fiber::YieldTo(fiber1.get(), thread_fibers[id].get()); | ||||
|         Fiber::YieldTo(fiber1, thread_fibers[id]); | ||||
|     } | ||||
|  | ||||
|     void DoWork2() { | ||||
| @@ -128,7 +129,7 @@ public: | ||||
|             ; | ||||
|         value2 = 2000; | ||||
|         trap = false; | ||||
|         Fiber::YieldTo(fiber2.get(), fiber1.get()); | ||||
|         Fiber::YieldTo(fiber2, fiber1); | ||||
|         assert3 = false; | ||||
|     } | ||||
|  | ||||
| @@ -136,19 +137,19 @@ public: | ||||
|         const u32 id = thread_ids.Get(); | ||||
|         assert2 = id == 0; | ||||
|         value1 += 1000; | ||||
|         Fiber::YieldTo(fiber3.get(), thread_fibers[id].get()); | ||||
|         Fiber::YieldTo(fiber3, thread_fibers[id]); | ||||
|     } | ||||
|  | ||||
|     void ExecuteThread(u32 id); | ||||
|  | ||||
|     void CallFiber1() { | ||||
|         const u32 id = thread_ids.Get(); | ||||
|         Fiber::YieldTo(thread_fibers[id].get(), fiber1.get()); | ||||
|         Fiber::YieldTo(thread_fibers[id], fiber1); | ||||
|     } | ||||
|  | ||||
|     void CallFiber2() { | ||||
|         const u32 id = thread_ids.Get(); | ||||
|         Fiber::YieldTo(thread_fibers[id].get(), fiber2.get()); | ||||
|         Fiber::YieldTo(thread_fibers[id], fiber2); | ||||
|     } | ||||
|  | ||||
|     void Exit(); | ||||
| @@ -184,7 +185,8 @@ static void WorkControl2_3(void* control) { | ||||
|  | ||||
| void TestControl2::ExecuteThread(u32 id) { | ||||
|     thread_ids.Register(id); | ||||
|     thread_fibers[id] = Fiber::ThreadToFiber(); | ||||
|     auto thread_fiber = Fiber::ThreadToFiber(); | ||||
|     thread_fibers[id] = thread_fiber; | ||||
| } | ||||
|  | ||||
| void TestControl2::Exit() { | ||||
| @@ -239,23 +241,23 @@ public: | ||||
|  | ||||
|     void DoWork1() { | ||||
|         value1 += 1; | ||||
|         Fiber::YieldTo(fiber1.get(), fiber2.get()); | ||||
|         Fiber::YieldTo(fiber1, fiber2); | ||||
|         const u32 id = thread_ids.Get(); | ||||
|         value3 += 1; | ||||
|         Fiber::YieldTo(fiber1.get(), thread_fibers[id].get()); | ||||
|         Fiber::YieldTo(fiber1, thread_fibers[id]); | ||||
|     } | ||||
|  | ||||
|     void DoWork2() { | ||||
|         value2 += 1; | ||||
|         const u32 id = thread_ids.Get(); | ||||
|         Fiber::YieldTo(fiber2.get(), thread_fibers[id].get()); | ||||
|         Fiber::YieldTo(fiber2, thread_fibers[id]); | ||||
|     } | ||||
|  | ||||
|     void ExecuteThread(u32 id); | ||||
|  | ||||
|     void CallFiber1() { | ||||
|         const u32 id = thread_ids.Get(); | ||||
|         Fiber::YieldTo(thread_fibers[id].get(), fiber1.get()); | ||||
|         Fiber::YieldTo(thread_fibers[id], fiber1); | ||||
|     } | ||||
|  | ||||
|     void Exit(); | ||||
| @@ -264,7 +266,7 @@ public: | ||||
|     u32 value2{}; | ||||
|     u32 value3{}; | ||||
|     ThreadIds thread_ids; | ||||
|     std::vector<std::unique_ptr<Common::Fiber>> thread_fibers; | ||||
|     std::vector<std::shared_ptr<Common::Fiber>> thread_fibers; | ||||
|     std::shared_ptr<Common::Fiber> fiber1; | ||||
|     std::shared_ptr<Common::Fiber> fiber2; | ||||
| }; | ||||
| @@ -281,7 +283,8 @@ static void WorkControl3_2(void* control) { | ||||
|  | ||||
| void TestControl3::ExecuteThread(u32 id) { | ||||
|     thread_ids.Register(id); | ||||
|     thread_fibers[id] = Fiber::ThreadToFiber(); | ||||
|     auto thread_fiber = Fiber::ThreadToFiber(); | ||||
|     thread_fibers[id] = thread_fiber; | ||||
| } | ||||
|  | ||||
| void TestControl3::Exit() { | ||||
| @@ -329,7 +332,7 @@ public: | ||||
|  | ||||
|     void Execute() { | ||||
|         thread_fiber = Fiber::ThreadToFiber(); | ||||
|         Fiber::YieldTo(thread_fiber.get(), fiber1.get()); | ||||
|         Fiber::YieldTo(thread_fiber, fiber1); | ||||
|         thread_fiber->Exit(); | ||||
|     } | ||||
|  | ||||
| @@ -337,7 +340,7 @@ public: | ||||
|         fiber1->SetRewindPoint(std::function<void(void*)>{WorkControl4}, this); | ||||
|         if (rewinded) { | ||||
|             goal_reached = true; | ||||
|             Fiber::YieldTo(fiber1.get(), thread_fiber.get()); | ||||
|             Fiber::YieldTo(fiber1, thread_fiber); | ||||
|         } | ||||
|         rewinded = true; | ||||
|         fiber1->Rewind(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user