summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2021-02-27 11:56:04 -0800
committerGravatar bunnei2021-02-27 11:56:04 -0800
commit51fb0a6f9647ba199da10fe4f018ee36e44e65ba (patch)
tree89cd2ad6dfb310587aa546bb7b9847762795f08f /src
parentMerge pull request #5953 from bunnei/memory-refactor-1 (diff)
downloadyuzu-51fb0a6f9647ba199da10fe4f018ee36e44e65ba.tar.gz
yuzu-51fb0a6f9647ba199da10fe4f018ee36e44e65ba.tar.xz
yuzu-51fb0a6f9647ba199da10fe4f018ee36e44e65ba.zip
core: Switch to unique_ptr for usage of Common::Fiber.
- With using unique_ptr instead of shared_ptr, we have more explicit ownership of the context. - Fixes a memory leak due to circular reference of the shared pointer.
Diffstat (limited to 'src')
-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, 58 insertions, 59 deletions
diff --git a/src/common/fiber.cpp b/src/common/fiber.cpp
index 3c1eefcb7..b8e98b12a 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 std::shared_ptr<Fiber> previous_fiber; 27 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.reset(); 50 impl->previous_fiber = nullptr;
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(std::shared_ptr<Fiber> from, std::shared_ptr<Fiber> to) { 119void Fiber::YieldTo(Fiber* from, 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.get()); 124 auto transfer = boost::context::detail::jump_fcontext(to->impl->context, to);
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.reset(); 128 from->impl->previous_fiber = nullptr;
129} 129}
130 130
131std::shared_ptr<Fiber> Fiber::ThreadToFiber() { 131std::unique_ptr<Fiber> Fiber::ThreadToFiber() {
132 std::shared_ptr<Fiber> fiber = std::shared_ptr<Fiber>{new Fiber()}; 132 std::unique_ptr<Fiber> fiber = std::unique_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 f7f587f8c..6924f7996 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(std::shared_ptr<Fiber> from, std::shared_ptr<Fiber> to); 44 static void YieldTo(Fiber* from, Fiber* to);
45 [[nodiscard]] static std::shared_ptr<Fiber> ThreadToFiber(); 45 [[nodiscard]] static std::unique_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 8f04fb8f5..c35438c6f 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,7 +148,8 @@ 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(), core_data[core].host_context); 151 Common::Fiber::YieldTo(current_thread->GetHostContext(),
152 core_data[core].host_context.get());
152 ASSERT(scheduler.ContextSwitchPending()); 153 ASSERT(scheduler.ContextSwitchPending());
153 ASSERT(core == kernel.GetCurrentHostThreadID()); 154 ASSERT(core == kernel.GetCurrentHostThreadID());
154 scheduler.RescheduleCurrentCore(); 155 scheduler.RescheduleCurrentCore();
@@ -201,7 +202,7 @@ void CpuManager::SingleCoreRunGuestThread() {
201 auto& kernel = system.Kernel(); 202 auto& kernel = system.Kernel();
202 kernel.CurrentScheduler()->OnThreadStart(); 203 kernel.CurrentScheduler()->OnThreadStart();
203 auto* thread = kernel.CurrentScheduler()->GetCurrentThread(); 204 auto* thread = kernel.CurrentScheduler()->GetCurrentThread();
204 auto& host_context = thread->GetHostContext(); 205 auto host_context = thread->GetHostContext();
205 host_context->SetRewindPoint(GuestRewindFunction, this); 206 host_context->SetRewindPoint(GuestRewindFunction, this);
206 SingleCoreRunGuestLoop(); 207 SingleCoreRunGuestLoop();
207} 208}
@@ -245,7 +246,7 @@ void CpuManager::SingleCoreRunSuspendThread() {
245 auto core = kernel.GetCurrentHostThreadID(); 246 auto core = kernel.GetCurrentHostThreadID();
246 auto& scheduler = *kernel.CurrentScheduler(); 247 auto& scheduler = *kernel.CurrentScheduler();
247 Kernel::KThread* current_thread = scheduler.GetCurrentThread(); 248 Kernel::KThread* current_thread = scheduler.GetCurrentThread();
248 Common::Fiber::YieldTo(current_thread->GetHostContext(), core_data[0].host_context); 249 Common::Fiber::YieldTo(current_thread->GetHostContext(), core_data[0].host_context.get());
249 ASSERT(scheduler.ContextSwitchPending()); 250 ASSERT(scheduler.ContextSwitchPending());
250 ASSERT(core == kernel.GetCurrentHostThreadID()); 251 ASSERT(core == kernel.GetCurrentHostThreadID());
251 scheduler.RescheduleCurrentCore(); 252 scheduler.RescheduleCurrentCore();
@@ -363,7 +364,7 @@ void CpuManager::RunThread(std::size_t core) {
363 364
364 auto current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread(); 365 auto current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread();
365 data.is_running = true; 366 data.is_running = true;
366 Common::Fiber::YieldTo(data.host_context, current_thread->GetHostContext()); 367 Common::Fiber::YieldTo(data.host_context.get(), current_thread->GetHostContext());
367 data.is_running = false; 368 data.is_running = false;
368 data.is_paused = true; 369 data.is_paused = true;
369 data.exit_barrier->Wait(); 370 data.exit_barrier->Wait();
diff --git a/src/core/cpu_manager.h b/src/core/cpu_manager.h
index 17420c941..5ea149f1f 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::shared_ptr<Common::Fiber> host_context; 86 std::unique_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 bb5f43b53..465036f3d 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_shared<Common::Fiber>(OnSwitch, this); 611 switch_fiber = std::make_unique<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 std::shared_ptr<Common::Fiber>* old_context; 729 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); 737 Common::Fiber::YieldTo(old_context, switch_fiber.get());
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 std::shared_ptr<Common::Fiber>* next_context; 772 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, *next_context); 778 Common::Fiber::YieldTo(switch_fiber.get(), 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 f595b9a5c..a4285c595 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]] std::shared_ptr<Common::Fiber>& ControlContext() { 71 [[nodiscard]] Common::Fiber* ControlContext() {
72 return switch_fiber; 72 return switch_fiber.get();
73 } 73 }
74 74
75 [[nodiscard]] const std::shared_ptr<Common::Fiber>& ControlContext() const { 75 [[nodiscard]] const Common::Fiber* ControlContext() const {
76 return switch_fiber; 76 return switch_fiber.get();
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::shared_ptr<Common::Fiber> switch_fiber{}; 181 std::unique_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 1661afbd9..f49e31b72 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -991,10 +991,6 @@ void KThread::SetState(ThreadState state) {
991 } 991 }
992} 992}
993 993
994std::shared_ptr<Common::Fiber>& KThread::GetHostContext() {
995 return host_context;
996}
997
998ResultVal<std::shared_ptr<KThread>> KThread::Create(Core::System& system, ThreadType type_flags, 994ResultVal<std::shared_ptr<KThread>> KThread::Create(Core::System& system, ThreadType type_flags,
999 std::string name, VAddr entry_point, 995 std::string name, VAddr entry_point,
1000 u32 priority, u64 arg, s32 processor_id, 996 u32 priority, u64 arg, s32 processor_id,
@@ -1028,7 +1024,7 @@ ResultVal<std::shared_ptr<KThread>> KThread::Create(Core::System& system, Thread
1028 scheduler.AddThread(thread); 1024 scheduler.AddThread(thread);
1029 1025
1030 thread->host_context = 1026 thread->host_context =
1031 std::make_shared<Common::Fiber>(std::move(thread_start_func), thread_start_parameter); 1027 std::make_unique<Common::Fiber>(std::move(thread_start_func), thread_start_parameter);
1032 1028
1033 return MakeResult<std::shared_ptr<KThread>>(std::move(thread)); 1029 return MakeResult<std::shared_ptr<KThread>>(std::move(thread));
1034} 1030}
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h
index c8ac656a4..a2893d939 100644
--- a/src/core/hle/kernel/k_thread.h
+++ b/src/core/hle/kernel/k_thread.h
@@ -293,7 +293,13 @@ public:
293 return thread_context_64; 293 return thread_context_64;
294 } 294 }
295 295
296 [[nodiscard]] std::shared_ptr<Common::Fiber>& GetHostContext(); 296 [[nodiscard]] Common::Fiber* GetHostContext() {
297 return host_context.get();
298 }
299
300 [[nodiscard]] const Common::Fiber* GetHostContext() const {
301 return host_context.get();
302 }
297 303
298 [[nodiscard]] ThreadState GetState() const { 304 [[nodiscard]] ThreadState GetState() const {
299 return thread_state & ThreadState::Mask; 305 return thread_state & ThreadState::Mask;
@@ -719,7 +725,7 @@ private:
719 Common::SpinLock context_guard{}; 725 Common::SpinLock context_guard{};
720 726
721 // For emulation 727 // For emulation
722 std::shared_ptr<Common::Fiber> host_context{}; 728 std::unique_ptr<Common::Fiber> host_context{};
723 729
724 // For debugging 730 // For debugging
725 std::vector<KSynchronizationObject*> wait_objects_for_debugging; 731 std::vector<KSynchronizationObject*> wait_objects_for_debugging;
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index cc8fa6576..d04116115 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -2626,8 +2626,7 @@ void Call(Core::System& system, u32 immediate) {
2626 kernel.ExitSVCProfile(); 2626 kernel.ExitSVCProfile();
2627 2627
2628 if (!thread->IsCallingSvc()) { 2628 if (!thread->IsCallingSvc()) {
2629 auto* host_context = thread->GetHostContext().get(); 2629 thread->GetHostContext()->Rewind();
2630 host_context->Rewind();
2631 } 2630 }
2632 2631
2633 system.EnterDynarmicProfile(); 2632 system.EnterDynarmicProfile();
diff --git a/src/tests/common/fibers.cpp b/src/tests/common/fibers.cpp
index d94492fc6..b2ded2065 100644
--- a/src/tests/common/fibers.cpp
+++ b/src/tests/common/fibers.cpp
@@ -67,16 +67,15 @@ void TestControl1::DoWork() {
67 value++; 67 value++;
68 } 68 }
69 results[id] = value; 69 results[id] = value;
70 Fiber::YieldTo(work_fibers[id], thread_fibers[id]); 70 Fiber::YieldTo(work_fibers[id].get(), thread_fibers[id].get());
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 auto thread_fiber = Fiber::ThreadToFiber(); 75 thread_fibers[id] = Fiber::ThreadToFiber();
76 thread_fibers[id] = thread_fiber;
77 work_fibers[id] = std::make_shared<Fiber>(std::function<void(void*)>{WorkControl1}, this); 76 work_fibers[id] = std::make_shared<Fiber>(std::function<void(void*)>{WorkControl1}, this);
78 items[id] = rand() % 256; 77 items[id] = rand() % 256;
79 Fiber::YieldTo(thread_fibers[id], work_fibers[id]); 78 Fiber::YieldTo(thread_fibers[id].get(), work_fibers[id].get());
80 thread_fibers[id]->Exit(); 79 thread_fibers[id]->Exit();
81} 80}
82 81
@@ -117,11 +116,11 @@ public:
117 for (u32 i = 0; i < 12000; i++) { 116 for (u32 i = 0; i < 12000; i++) {
118 value1 += i; 117 value1 += i;
119 } 118 }
120 Fiber::YieldTo(fiber1, fiber3); 119 Fiber::YieldTo(fiber1.get(), fiber3.get());
121 const u32 id = thread_ids.Get(); 120 const u32 id = thread_ids.Get();
122 assert1 = id == 1; 121 assert1 = id == 1;
123 value2 += 5000; 122 value2 += 5000;
124 Fiber::YieldTo(fiber1, thread_fibers[id]); 123 Fiber::YieldTo(fiber1.get(), thread_fibers[id].get());
125 } 124 }
126 125
127 void DoWork2() { 126 void DoWork2() {
@@ -129,7 +128,7 @@ public:
129 ; 128 ;
130 value2 = 2000; 129 value2 = 2000;
131 trap = false; 130 trap = false;
132 Fiber::YieldTo(fiber2, fiber1); 131 Fiber::YieldTo(fiber2.get(), fiber1.get());
133 assert3 = false; 132 assert3 = false;
134 } 133 }
135 134
@@ -137,19 +136,19 @@ public:
137 const u32 id = thread_ids.Get(); 136 const u32 id = thread_ids.Get();
138 assert2 = id == 0; 137 assert2 = id == 0;
139 value1 += 1000; 138 value1 += 1000;
140 Fiber::YieldTo(fiber3, thread_fibers[id]); 139 Fiber::YieldTo(fiber3.get(), thread_fibers[id].get());
141 } 140 }
142 141
143 void ExecuteThread(u32 id); 142 void ExecuteThread(u32 id);
144 143
145 void CallFiber1() { 144 void CallFiber1() {
146 const u32 id = thread_ids.Get(); 145 const u32 id = thread_ids.Get();
147 Fiber::YieldTo(thread_fibers[id], fiber1); 146 Fiber::YieldTo(thread_fibers[id].get(), fiber1.get());
148 } 147 }
149 148
150 void CallFiber2() { 149 void CallFiber2() {
151 const u32 id = thread_ids.Get(); 150 const u32 id = thread_ids.Get();
152 Fiber::YieldTo(thread_fibers[id], fiber2); 151 Fiber::YieldTo(thread_fibers[id].get(), fiber2.get());
153 } 152 }
154 153
155 void Exit(); 154 void Exit();
@@ -185,8 +184,7 @@ static void WorkControl2_3(void* control) {
185 184
186void TestControl2::ExecuteThread(u32 id) { 185void TestControl2::ExecuteThread(u32 id) {
187 thread_ids.Register(id); 186 thread_ids.Register(id);
188 auto thread_fiber = Fiber::ThreadToFiber(); 187 thread_fibers[id] = Fiber::ThreadToFiber();
189 thread_fibers[id] = thread_fiber;
190} 188}
191 189
192void TestControl2::Exit() { 190void TestControl2::Exit() {
@@ -241,23 +239,23 @@ public:
241 239
242 void DoWork1() { 240 void DoWork1() {
243 value1 += 1; 241 value1 += 1;
244 Fiber::YieldTo(fiber1, fiber2); 242 Fiber::YieldTo(fiber1.get(), fiber2.get());
245 const u32 id = thread_ids.Get(); 243 const u32 id = thread_ids.Get();
246 value3 += 1; 244 value3 += 1;
247 Fiber::YieldTo(fiber1, thread_fibers[id]); 245 Fiber::YieldTo(fiber1.get(), thread_fibers[id].get());
248 } 246 }
249 247
250 void DoWork2() { 248 void DoWork2() {
251 value2 += 1; 249 value2 += 1;
252 const u32 id = thread_ids.Get(); 250 const u32 id = thread_ids.Get();
253 Fiber::YieldTo(fiber2, thread_fibers[id]); 251 Fiber::YieldTo(fiber2.get(), thread_fibers[id].get());
254 } 252 }
255 253
256 void ExecuteThread(u32 id); 254 void ExecuteThread(u32 id);
257 255
258 void CallFiber1() { 256 void CallFiber1() {
259 const u32 id = thread_ids.Get(); 257 const u32 id = thread_ids.Get();
260 Fiber::YieldTo(thread_fibers[id], fiber1); 258 Fiber::YieldTo(thread_fibers[id].get(), fiber1.get());
261 } 259 }
262 260
263 void Exit(); 261 void Exit();
@@ -266,7 +264,7 @@ public:
266 u32 value2{}; 264 u32 value2{};
267 u32 value3{}; 265 u32 value3{};
268 ThreadIds thread_ids; 266 ThreadIds thread_ids;
269 std::vector<std::shared_ptr<Common::Fiber>> thread_fibers; 267 std::vector<std::unique_ptr<Common::Fiber>> thread_fibers;
270 std::shared_ptr<Common::Fiber> fiber1; 268 std::shared_ptr<Common::Fiber> fiber1;
271 std::shared_ptr<Common::Fiber> fiber2; 269 std::shared_ptr<Common::Fiber> fiber2;
272}; 270};
@@ -283,8 +281,7 @@ static void WorkControl3_2(void* control) {
283 281
284void TestControl3::ExecuteThread(u32 id) { 282void TestControl3::ExecuteThread(u32 id) {
285 thread_ids.Register(id); 283 thread_ids.Register(id);
286 auto thread_fiber = Fiber::ThreadToFiber(); 284 thread_fibers[id] = Fiber::ThreadToFiber();
287 thread_fibers[id] = thread_fiber;
288} 285}
289 286
290void TestControl3::Exit() { 287void TestControl3::Exit() {
@@ -332,7 +329,7 @@ public:
332 329
333 void Execute() { 330 void Execute() {
334 thread_fiber = Fiber::ThreadToFiber(); 331 thread_fiber = Fiber::ThreadToFiber();
335 Fiber::YieldTo(thread_fiber, fiber1); 332 Fiber::YieldTo(thread_fiber.get(), fiber1.get());
336 thread_fiber->Exit(); 333 thread_fiber->Exit();
337 } 334 }
338 335
@@ -340,7 +337,7 @@ public:
340 fiber1->SetRewindPoint(std::function<void(void*)>{WorkControl4}, this); 337 fiber1->SetRewindPoint(std::function<void(void*)>{WorkControl4}, this);
341 if (rewinded) { 338 if (rewinded) {
342 goal_reached = true; 339 goal_reached = true;
343 Fiber::YieldTo(fiber1, thread_fiber); 340 Fiber::YieldTo(fiber1.get(), thread_fiber.get());
344 } 341 }
345 rewinded = true; 342 rewinded = true;
346 fiber1->Rewind(); 343 fiber1->Rewind();