summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common/fiber.cpp14
-rw-r--r--src/common/fiber.h4
-rw-r--r--src/core/cpu_manager.cpp11
-rw-r--r--src/core/cpu_manager.h2
-rw-r--r--src/core/hle/kernel/k_scheduler.cpp18
-rw-r--r--src/core/hle/kernel/k_scheduler.h10
-rw-r--r--src/core/hle/kernel/k_thread.cpp6
-rw-r--r--src/core/hle/kernel/k_thread.h10
-rw-r--r--src/core/hle/kernel/svc.cpp3
-rw-r--r--src/tests/common/fibers.cpp39
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
119void Fiber::YieldTo(Fiber* from, Fiber* to) { 119void 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
131std::unique_ptr<Fiber> Fiber::ThreadToFiber() { 131std::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
610KScheduler::KScheduler(Core::System& system, s32 core_id) : system(system), core_id(core_id) { 610KScheduler::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
994std::shared_ptr<Common::Fiber>& KThread::GetHostContext() {
995 return host_context;
996}
997
994ResultVal<std::shared_ptr<KThread>> KThread::Create(Core::System& system, ThreadType type_flags, 998ResultVal<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
73void TestControl1::ExecuteThread(u32 id) { 73void 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
185void TestControl2::ExecuteThread(u32 id) { 186void 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
190void TestControl2::Exit() { 192void 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
282void TestControl3::ExecuteThread(u32 id) { 284void 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
287void TestControl3::Exit() { 290void 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();