aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xREADME.md2
-rwxr-xr-xsrc/core/core.cpp16
-rwxr-xr-xsrc/core/hle/kernel/k_handle_table.cpp1
-rwxr-xr-xsrc/core/hle/kernel/k_process.cpp11
-rwxr-xr-xsrc/core/hle/kernel/kernel.cpp36
-rwxr-xr-xsrc/core/hle/kernel/kernel.h8
-rwxr-xr-xsrc/core/hle/kernel/svc.cpp6
-rwxr-xr-xsrc/core/hle/result.h24
8 files changed, 77 insertions, 27 deletions
diff --git a/README.md b/README.md
index f86b6e589..3ae60b138 100755
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
1yuzu emulator early access 1yuzu emulator early access
2============= 2=============
3 3
4This is the source code for early-access 2165. 4This is the source code for early-access 2166.
5 5
6## Legal Notice 6## Legal Notice
7 7
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 3c75f42ae..c3a0f9dae 100755
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -83,12 +83,6 @@ FileSys::StorageId GetStorageIdForFrontendSlot(
83 } 83 }
84} 84}
85 85
86void KProcessDeleter(Kernel::KProcess* process) {
87 process->Destroy();
88}
89
90using KProcessPtr = std::unique_ptr<Kernel::KProcess, decltype(&KProcessDeleter)>;
91
92} // Anonymous namespace 86} // Anonymous namespace
93 87
94FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs, 88FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
@@ -261,11 +255,10 @@ struct System::Impl {
261 } 255 }
262 256
263 telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider); 257 telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider);
264 main_process = KProcessPtr{Kernel::KProcess::Create(system.Kernel()), KProcessDeleter}; 258 auto main_process = Kernel::KProcess::Create(system.Kernel());
265 ASSERT(Kernel::KProcess::Initialize(main_process.get(), system, "main", 259 ASSERT(Kernel::KProcess::Initialize(main_process, system, "main",
266 Kernel::KProcess::ProcessType::Userland) 260 Kernel::KProcess::ProcessType::Userland)
267 .IsSuccess()); 261 .IsSuccess());
268 main_process->Open();
269 const auto [load_result, load_parameters] = app_loader->Load(*main_process, system); 262 const auto [load_result, load_parameters] = app_loader->Load(*main_process, system);
270 if (load_result != Loader::ResultStatus::Success) { 263 if (load_result != Loader::ResultStatus::Success) {
271 LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result); 264 LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result);
@@ -275,7 +268,7 @@ struct System::Impl {
275 static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result)); 268 static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result));
276 } 269 }
277 AddGlueRegistrationForProcess(*app_loader, *main_process); 270 AddGlueRegistrationForProcess(*app_loader, *main_process);
278 kernel.MakeCurrentProcess(main_process.get()); 271 kernel.MakeCurrentProcess(main_process);
279 kernel.InitializeCores(); 272 kernel.InitializeCores();
280 273
281 // Initialize cheat engine 274 // Initialize cheat engine
@@ -340,8 +333,6 @@ struct System::Impl {
340 kernel.Shutdown(); 333 kernel.Shutdown();
341 memory.Reset(); 334 memory.Reset();
342 applet_manager.ClearAll(); 335 applet_manager.ClearAll();
343 // TODO: The main process should be freed based on KAutoObject ref counting.
344 main_process.reset();
345 336
346 LOG_DEBUG(Core, "Shutdown OK"); 337 LOG_DEBUG(Core, "Shutdown OK");
347 } 338 }
@@ -403,7 +394,6 @@ struct System::Impl {
403 std::unique_ptr<Tegra::GPU> gpu_core; 394 std::unique_ptr<Tegra::GPU> gpu_core;
404 std::unique_ptr<Hardware::InterruptManager> interrupt_manager; 395 std::unique_ptr<Hardware::InterruptManager> interrupt_manager;
405 std::unique_ptr<Core::DeviceMemory> device_memory; 396 std::unique_ptr<Core::DeviceMemory> device_memory;
406 KProcessPtr main_process{nullptr, KProcessDeleter};
407 Core::Memory::Memory memory; 397 Core::Memory::Memory memory;
408 CpuManager cpu_manager; 398 CpuManager cpu_manager;
409 std::atomic_bool is_powered_on{}; 399 std::atomic_bool is_powered_on{};
diff --git a/src/core/hle/kernel/k_handle_table.cpp b/src/core/hle/kernel/k_handle_table.cpp
index 44d13169f..e90fc0628 100755
--- a/src/core/hle/kernel/k_handle_table.cpp
+++ b/src/core/hle/kernel/k_handle_table.cpp
@@ -56,6 +56,7 @@ bool KHandleTable::Remove(Handle handle) {
56 } 56 }
57 57
58 // Close the object. 58 // Close the object.
59 kernel.UnregisterInUseObject(obj);
59 obj->Close(); 60 obj->Close();
60 return true; 61 return true;
61} 62}
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index 211157ccc..76fd8c285 100755
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -434,11 +434,6 @@ void KProcess::PrepareForTermination() {
434} 434}
435 435
436void KProcess::Finalize() { 436void KProcess::Finalize() {
437 // Release memory to the resource limit.
438 if (resource_limit != nullptr) {
439 resource_limit->Close();
440 }
441
442 // Finalize the handle table and close any open handles. 437 // Finalize the handle table and close any open handles.
443 handle_table.Finalize(); 438 handle_table.Finalize();
444 439
@@ -460,6 +455,12 @@ void KProcess::Finalize() {
460 } 455 }
461 } 456 }
462 457
458 // Release memory to the resource limit.
459 if (resource_limit != nullptr) {
460 resource_limit->Close();
461 resource_limit = nullptr;
462 }
463
463 // Perform inherited finalization. 464 // Perform inherited finalization.
464 KAutoObjectWithSlabHeapAndContainer<KProcess, KSynchronizationObject>::Finalize(); 465 KAutoObjectWithSlabHeapAndContainer<KProcess, KSynchronizationObject>::Finalize();
465} 466}
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index bea945301..4a139c5e7 100755
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -91,12 +91,6 @@ struct KernelCore::Impl {
91 } 91 }
92 92
93 void Shutdown() { 93 void Shutdown() {
94 // Shutdown all processes.
95 if (current_process) {
96 current_process->Finalize();
97 current_process->Close();
98 current_process = nullptr;
99 }
100 process_list.clear(); 94 process_list.clear();
101 95
102 // Close all open server ports. 96 // Close all open server ports.
@@ -170,6 +164,24 @@ struct KernelCore::Impl {
170 // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others 164 // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others
171 next_host_thread_id = Core::Hardware::NUM_CPU_CORES; 165 next_host_thread_id = Core::Hardware::NUM_CPU_CORES;
172 166
167 // Close kernel objects that were not freed on shutdown
168 {
169 std::lock_guard lk(registered_in_use_objects_lock);
170 if (registered_in_use_objects.size()) {
171 for (auto& object : registered_in_use_objects) {
172 object->Close();
173 }
174 registered_in_use_objects.clear();
175 }
176 }
177
178 // Shutdown all processes.
179 if (current_process) {
180 current_process->Finalize();
181 current_process->Close();
182 current_process = nullptr;
183 }
184
173 // Track kernel objects that were not freed on shutdown 185 // Track kernel objects that were not freed on shutdown
174 { 186 {
175 std::lock_guard lk(registered_objects_lock); 187 std::lock_guard lk(registered_objects_lock);
@@ -714,9 +726,11 @@ struct KernelCore::Impl {
714 std::unordered_set<KServerPort*> server_ports; 726 std::unordered_set<KServerPort*> server_ports;
715 std::unordered_set<KServerSession*> server_sessions; 727 std::unordered_set<KServerSession*> server_sessions;
716 std::unordered_set<KAutoObject*> registered_objects; 728 std::unordered_set<KAutoObject*> registered_objects;
729 std::unordered_set<KAutoObject*> registered_in_use_objects;
717 std::mutex server_ports_lock; 730 std::mutex server_ports_lock;
718 std::mutex server_sessions_lock; 731 std::mutex server_sessions_lock;
719 std::mutex registered_objects_lock; 732 std::mutex registered_objects_lock;
733 std::mutex registered_in_use_objects_lock;
720 734
721 std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor; 735 std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor;
722 std::vector<Kernel::PhysicalCore> cores; 736 std::vector<Kernel::PhysicalCore> cores;
@@ -928,6 +942,16 @@ void KernelCore::UnregisterKernelObject(KAutoObject* object) {
928 impl->registered_objects.erase(object); 942 impl->registered_objects.erase(object);
929} 943}
930 944
945void KernelCore::RegisterInUseObject(KAutoObject* object) {
946 std::lock_guard lk(impl->registered_in_use_objects_lock);
947 impl->registered_in_use_objects.insert(object);
948}
949
950void KernelCore::UnregisterInUseObject(KAutoObject* object) {
951 std::lock_guard lk(impl->registered_in_use_objects_lock);
952 impl->registered_in_use_objects.erase(object);
953}
954
931bool KernelCore::IsValidNamedPort(NamedPortTable::const_iterator port) const { 955bool KernelCore::IsValidNamedPort(NamedPortTable::const_iterator port) const {
932 return port != impl->named_ports.cend(); 956 return port != impl->named_ports.cend();
933} 957}
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index b6658b437..d2ceae950 100755
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -204,6 +204,14 @@ public:
204 /// destroyed during the current emulation session. 204 /// destroyed during the current emulation session.
205 void UnregisterKernelObject(KAutoObject* object); 205 void UnregisterKernelObject(KAutoObject* object);
206 206
207 /// Registers kernel objects with guest in use state, this is purely for close
208 /// after emulation has been shutdown.
209 void RegisterInUseObject(KAutoObject* object);
210
211 /// Unregisters a kernel object previously registered with RegisterInUseObject when it was
212 /// destroyed during the current emulation session.
213 void UnregisterInUseObject(KAutoObject* object);
214
207 /// Determines whether or not the given port is a valid named port. 215 /// Determines whether or not the given port is a valid named port.
208 bool IsValidNamedPort(NamedPortTable::const_iterator port) const; 216 bool IsValidNamedPort(NamedPortTable::const_iterator port) const;
209 217
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 7f38ade1c..c43135856 100755
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -427,11 +427,15 @@ static ResultCode WaitSynchronization(Core::System& system, s32* index, VAddr ha
427 R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles, 427 R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles,
428 num_handles), 428 num_handles),
429 ResultInvalidHandle); 429 ResultInvalidHandle);
430 for (const auto& obj : objs) {
431 kernel.RegisterInUseObject(obj);
432 }
430 } 433 }
431 434
432 // Ensure handles are closed when we're done. 435 // Ensure handles are closed when we're done.
433 SCOPE_EXIT({ 436 SCOPE_EXIT({
434 for (u64 i = 0; i < num_handles; ++i) { 437 for (u64 i = 0; i < num_handles; ++i) {
438 kernel.UnregisterInUseObject(objs[i]);
435 objs[i]->Close(); 439 objs[i]->Close();
436 } 440 }
437 }); 441 });
@@ -1561,6 +1565,7 @@ static ResultCode StartThread(Core::System& system, Handle thread_handle) {
1561 1565
1562 // If we succeeded, persist a reference to the thread. 1566 // If we succeeded, persist a reference to the thread.
1563 thread->Open(); 1567 thread->Open();
1568 system.Kernel().RegisterInUseObject(thread.GetPointerUnsafe());
1564 1569
1565 return ResultSuccess; 1570 return ResultSuccess;
1566} 1571}
@@ -1576,6 +1581,7 @@ static void ExitThread(Core::System& system) {
1576 auto* const current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread(); 1581 auto* const current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread();
1577 system.GlobalSchedulerContext().RemoveThread(current_thread); 1582 system.GlobalSchedulerContext().RemoveThread(current_thread);
1578 current_thread->Exit(); 1583 current_thread->Exit();
1584 system.Kernel().UnregisterInUseObject(current_thread);
1579} 1585}
1580 1586
1581static void ExitThread32(Core::System& system) { 1587static void ExitThread32(Core::System& system) {
diff --git a/src/core/hle/result.h b/src/core/hle/result.h
index a755008d5..00fe70998 100755
--- a/src/core/hle/result.h
+++ b/src/core/hle/result.h
@@ -206,7 +206,7 @@ public:
206 return result; 206 return result;
207 } 207 }
208 208
209 ResultVal(const ResultVal& o) : result_code(o.result_code) { 209 ResultVal(const ResultVal& o) noexcept : result_code(o.result_code) {
210 if (!o.empty()) { 210 if (!o.empty()) {
211 new (&object) T(o.object); 211 new (&object) T(o.object);
212 } 212 }
@@ -224,7 +224,7 @@ public:
224 } 224 }
225 } 225 }
226 226
227 ResultVal& operator=(const ResultVal& o) { 227 ResultVal& operator=(const ResultVal& o) noexcept {
228 if (this == &o) { 228 if (this == &o) {
229 return *this; 229 return *this;
230 } 230 }
@@ -244,6 +244,26 @@ public:
244 return *this; 244 return *this;
245 } 245 }
246 246
247 ResultVal& operator=(ResultVal&& o) noexcept {
248 if (this == &o) {
249 return *this;
250 }
251 if (!empty()) {
252 if (!o.empty()) {
253 object = std::move(o.object);
254 } else {
255 object.~T();
256 }
257 } else {
258 if (!o.empty()) {
259 new (&object) T(std::move(o.object));
260 }
261 }
262 result_code = o.result_code;
263
264 return *this;
265 }
266
247 /** 267 /**
248 * Replaces the current result with a new constructed result value in-place. The code must not 268 * Replaces the current result with a new constructed result value in-place. The code must not
249 * be an error code. 269 * be an error code.