diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/thread.h | 11 | ||||
| -rw-r--r-- | src/core/core.cpp | 4 | ||||
| -rw-r--r-- | src/core/cpu_manager.cpp | 15 | ||||
| -rw-r--r-- | src/core/cpu_manager.h | 4 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 14 |
5 files changed, 27 insertions, 21 deletions
diff --git a/src/common/thread.h b/src/common/thread.h index e17a7850f..8ae169b4e 100644 --- a/src/common/thread.h +++ b/src/common/thread.h | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #include <mutex> | 11 | #include <mutex> |
| 12 | #include <thread> | 12 | #include <thread> |
| 13 | #include "common/common_types.h" | 13 | #include "common/common_types.h" |
| 14 | #include "common/polyfill_thread.h" | ||
| 14 | 15 | ||
| 15 | namespace Common { | 16 | namespace Common { |
| 16 | 17 | ||
| @@ -69,7 +70,7 @@ public: | |||
| 69 | explicit Barrier(std::size_t count_) : count(count_) {} | 70 | explicit Barrier(std::size_t count_) : count(count_) {} |
| 70 | 71 | ||
| 71 | /// Blocks until all "count" threads have called Sync() | 72 | /// Blocks until all "count" threads have called Sync() |
| 72 | void Sync() { | 73 | bool Sync(std::stop_token token = {}) { |
| 73 | std::unique_lock lk{mutex}; | 74 | std::unique_lock lk{mutex}; |
| 74 | const std::size_t current_generation = generation; | 75 | const std::size_t current_generation = generation; |
| 75 | 76 | ||
| @@ -77,14 +78,16 @@ public: | |||
| 77 | generation++; | 78 | generation++; |
| 78 | waiting = 0; | 79 | waiting = 0; |
| 79 | condvar.notify_all(); | 80 | condvar.notify_all(); |
| 81 | return true; | ||
| 80 | } else { | 82 | } else { |
| 81 | condvar.wait(lk, | 83 | CondvarWait(condvar, lk, token, |
| 82 | [this, current_generation] { return current_generation != generation; }); | 84 | [this, current_generation] { return current_generation != generation; }); |
| 85 | return !token.stop_requested(); | ||
| 83 | } | 86 | } |
| 84 | } | 87 | } |
| 85 | 88 | ||
| 86 | private: | 89 | private: |
| 87 | std::condition_variable condvar; | 90 | std::condition_variable_any condvar; |
| 88 | std::mutex mutex; | 91 | std::mutex mutex; |
| 89 | std::size_t count; | 92 | std::size_t count; |
| 90 | std::size_t waiting = 0; | 93 | std::size_t waiting = 0; |
diff --git a/src/core/core.cpp b/src/core/core.cpp index 94d4e2212..a738f221f 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -389,7 +389,9 @@ struct System::Impl { | |||
| 389 | kernel.ShutdownCores(); | 389 | kernel.ShutdownCores(); |
| 390 | cpu_manager.Shutdown(); | 390 | cpu_manager.Shutdown(); |
| 391 | debugger.reset(); | 391 | debugger.reset(); |
| 392 | services->KillNVNFlinger(); | 392 | if (services) { |
| 393 | services->KillNVNFlinger(); | ||
| 394 | } | ||
| 393 | kernel.CloseServices(); | 395 | kernel.CloseServices(); |
| 394 | services.reset(); | 396 | services.reset(); |
| 395 | service_manager.reset(); | 397 | service_manager.reset(); |
diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp index 0dd4c2196..04a11f444 100644 --- a/src/core/cpu_manager.cpp +++ b/src/core/cpu_manager.cpp | |||
| @@ -20,23 +20,20 @@ namespace Core { | |||
| 20 | CpuManager::CpuManager(System& system_) : system{system_} {} | 20 | CpuManager::CpuManager(System& system_) : system{system_} {} |
| 21 | CpuManager::~CpuManager() = default; | 21 | CpuManager::~CpuManager() = default; |
| 22 | 22 | ||
| 23 | void CpuManager::ThreadStart(std::stop_token stop_token, CpuManager& cpu_manager, | ||
| 24 | std::size_t core) { | ||
| 25 | cpu_manager.RunThread(core); | ||
| 26 | } | ||
| 27 | |||
| 28 | void CpuManager::Initialize() { | 23 | void CpuManager::Initialize() { |
| 29 | num_cores = is_multicore ? Core::Hardware::NUM_CPU_CORES : 1; | 24 | num_cores = is_multicore ? Core::Hardware::NUM_CPU_CORES : 1; |
| 30 | gpu_barrier = std::make_unique<Common::Barrier>(num_cores + 1); | 25 | gpu_barrier = std::make_unique<Common::Barrier>(num_cores + 1); |
| 31 | 26 | ||
| 32 | for (std::size_t core = 0; core < num_cores; core++) { | 27 | for (std::size_t core = 0; core < num_cores; core++) { |
| 33 | core_data[core].host_thread = std::jthread(ThreadStart, std::ref(*this), core); | 28 | core_data[core].host_thread = |
| 29 | std::jthread([this, core](std::stop_token token) { RunThread(token, core); }); | ||
| 34 | } | 30 | } |
| 35 | } | 31 | } |
| 36 | 32 | ||
| 37 | void CpuManager::Shutdown() { | 33 | void CpuManager::Shutdown() { |
| 38 | for (std::size_t core = 0; core < num_cores; core++) { | 34 | for (std::size_t core = 0; core < num_cores; core++) { |
| 39 | if (core_data[core].host_thread.joinable()) { | 35 | if (core_data[core].host_thread.joinable()) { |
| 36 | core_data[core].host_thread.request_stop(); | ||
| 40 | core_data[core].host_thread.join(); | 37 | core_data[core].host_thread.join(); |
| 41 | } | 38 | } |
| 42 | } | 39 | } |
| @@ -184,7 +181,7 @@ void CpuManager::ShutdownThread() { | |||
| 184 | UNREACHABLE(); | 181 | UNREACHABLE(); |
| 185 | } | 182 | } |
| 186 | 183 | ||
| 187 | void CpuManager::RunThread(std::size_t core) { | 184 | void CpuManager::RunThread(std::stop_token token, std::size_t core) { |
| 188 | /// Initialization | 185 | /// Initialization |
| 189 | system.RegisterCoreThread(core); | 186 | system.RegisterCoreThread(core); |
| 190 | std::string name; | 187 | std::string name; |
| @@ -206,7 +203,9 @@ void CpuManager::RunThread(std::size_t core) { | |||
| 206 | }); | 203 | }); |
| 207 | 204 | ||
| 208 | // Running | 205 | // Running |
| 209 | gpu_barrier->Sync(); | 206 | if (!gpu_barrier->Sync(token)) { |
| 207 | return; | ||
| 208 | } | ||
| 210 | 209 | ||
| 211 | if (!is_async_gpu && !is_multicore) { | 210 | if (!is_async_gpu && !is_multicore) { |
| 212 | system.GPU().ObtainContext(); | 211 | system.GPU().ObtainContext(); |
diff --git a/src/core/cpu_manager.h b/src/core/cpu_manager.h index 374367468..0deea9c58 100644 --- a/src/core/cpu_manager.h +++ b/src/core/cpu_manager.h | |||
| @@ -81,12 +81,10 @@ private: | |||
| 81 | void SingleCoreRunGuestThread(); | 81 | void SingleCoreRunGuestThread(); |
| 82 | void SingleCoreRunIdleThread(); | 82 | void SingleCoreRunIdleThread(); |
| 83 | 83 | ||
| 84 | static void ThreadStart(std::stop_token stop_token, CpuManager& cpu_manager, std::size_t core); | ||
| 85 | |||
| 86 | void GuestActivate(); | 84 | void GuestActivate(); |
| 87 | void HandleInterrupt(); | 85 | void HandleInterrupt(); |
| 88 | void ShutdownThread(); | 86 | void ShutdownThread(); |
| 89 | void RunThread(std::size_t core); | 87 | void RunThread(std::stop_token stop_token, std::size_t core); |
| 90 | 88 | ||
| 91 | struct CoreData { | 89 | struct CoreData { |
| 92 | std::shared_ptr<Common::Fiber> host_context; | 90 | std::shared_ptr<Common::Fiber> host_context; |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 288f97df5..0eb74a422 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -104,12 +104,16 @@ struct KernelCore::Impl { | |||
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | void CloseCurrentProcess() { | 106 | void CloseCurrentProcess() { |
| 107 | (*current_process).Finalize(); | 107 | KProcess* old_process = current_process.exchange(nullptr); |
| 108 | // current_process->Close(); | 108 | if (old_process == nullptr) { |
| 109 | // TODO: The current process should be destroyed based on accurate ref counting after | 109 | return; |
| 110 | } | ||
| 111 | |||
| 112 | // old_process->Close(); | ||
| 113 | // TODO: The process should be destroyed based on accurate ref counting after | ||
| 110 | // calling Close(). Adding a manual Destroy() call instead to avoid a memory leak. | 114 | // calling Close(). Adding a manual Destroy() call instead to avoid a memory leak. |
| 111 | (*current_process).Destroy(); | 115 | old_process->Finalize(); |
| 112 | current_process = nullptr; | 116 | old_process->Destroy(); |
| 113 | } | 117 | } |
| 114 | 118 | ||
| 115 | void Shutdown() { | 119 | void Shutdown() { |