diff options
| -rw-r--r-- | src/core/hle/kernel/k_thread.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_thread.h | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 27 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/service_thread.cpp | 24 |
5 files changed, 39 insertions, 20 deletions
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index cc88d08f0..78076a346 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp | |||
| @@ -263,9 +263,9 @@ Result KThread::InitializeThread(KThread* thread, KThreadFunction func, uintptr_ | |||
| 263 | R_SUCCEED(); | 263 | R_SUCCEED(); |
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | Result KThread::InitializeDummyThread(KThread* thread) { | 266 | Result KThread::InitializeDummyThread(KThread* thread, KProcess* owner) { |
| 267 | // Initialize the thread. | 267 | // Initialize the thread. |
| 268 | R_TRY(thread->Initialize({}, {}, {}, DummyThreadPriority, 3, {}, ThreadType::Dummy)); | 268 | R_TRY(thread->Initialize({}, {}, {}, DummyThreadPriority, 3, owner, ThreadType::Dummy)); |
| 269 | 269 | ||
| 270 | // Initialize emulation parameters. | 270 | // Initialize emulation parameters. |
| 271 | thread->stack_parameters.disable_count = 0; | 271 | thread->stack_parameters.disable_count = 0; |
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h index 30aa10c9a..f38c92bff 100644 --- a/src/core/hle/kernel/k_thread.h +++ b/src/core/hle/kernel/k_thread.h | |||
| @@ -415,7 +415,7 @@ public: | |||
| 415 | 415 | ||
| 416 | static void PostDestroy(uintptr_t arg); | 416 | static void PostDestroy(uintptr_t arg); |
| 417 | 417 | ||
| 418 | [[nodiscard]] static Result InitializeDummyThread(KThread* thread); | 418 | [[nodiscard]] static Result InitializeDummyThread(KThread* thread, KProcess* owner); |
| 419 | 419 | ||
| 420 | [[nodiscard]] static Result InitializeMainThread(Core::System& system, KThread* thread, | 420 | [[nodiscard]] static Result InitializeMainThread(Core::System& system, KThread* thread, |
| 421 | s32 virt_core); | 421 | s32 virt_core); |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 6df77b423..d1892e078 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -84,7 +84,7 @@ struct KernelCore::Impl { | |||
| 84 | InitializeResourceManagers(pt_heap_region.GetAddress(), pt_heap_region.GetSize()); | 84 | InitializeResourceManagers(pt_heap_region.GetAddress(), pt_heap_region.GetSize()); |
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | RegisterHostThread(); | 87 | RegisterHostThread(nullptr); |
| 88 | 88 | ||
| 89 | default_service_thread = CreateServiceThread(kernel, "DefaultServiceThread"); | 89 | default_service_thread = CreateServiceThread(kernel, "DefaultServiceThread"); |
| 90 | } | 90 | } |
| @@ -300,15 +300,18 @@ struct KernelCore::Impl { | |||
| 300 | } | 300 | } |
| 301 | 301 | ||
| 302 | // Gets the dummy KThread for the caller, allocating a new one if this is the first time | 302 | // Gets the dummy KThread for the caller, allocating a new one if this is the first time |
| 303 | KThread* GetHostDummyThread() { | 303 | KThread* GetHostDummyThread(KThread* existing_thread) { |
| 304 | auto initialize = [this](KThread* thread) { | 304 | auto initialize = [this](KThread* thread) { |
| 305 | ASSERT(KThread::InitializeDummyThread(thread).IsSuccess()); | 305 | ASSERT(KThread::InitializeDummyThread(thread, nullptr).IsSuccess()); |
| 306 | thread->SetName(fmt::format("DummyThread:{}", GetHostThreadId())); | 306 | thread->SetName(fmt::format("DummyThread:{}", GetHostThreadId())); |
| 307 | return thread; | 307 | return thread; |
| 308 | }; | 308 | }; |
| 309 | 309 | ||
| 310 | thread_local auto raw_thread = KThread(system.Kernel()); | 310 | thread_local KThread raw_thread{system.Kernel()}; |
| 311 | thread_local auto thread = initialize(&raw_thread); | 311 | thread_local KThread* thread = nullptr; |
| 312 | if (thread == nullptr) { | ||
| 313 | thread = (existing_thread == nullptr) ? initialize(&raw_thread) : existing_thread; | ||
| 314 | } | ||
| 312 | 315 | ||
| 313 | return thread; | 316 | return thread; |
| 314 | } | 317 | } |
| @@ -323,9 +326,9 @@ struct KernelCore::Impl { | |||
| 323 | } | 326 | } |
| 324 | 327 | ||
| 325 | /// Registers a new host thread by allocating a host thread ID for it | 328 | /// Registers a new host thread by allocating a host thread ID for it |
| 326 | void RegisterHostThread() { | 329 | void RegisterHostThread(KThread* existing_thread) { |
| 327 | [[maybe_unused]] const auto this_id = GetHostThreadId(); | 330 | [[maybe_unused]] const auto this_id = GetHostThreadId(); |
| 328 | [[maybe_unused]] const auto dummy_thread = GetHostDummyThread(); | 331 | [[maybe_unused]] const auto dummy_thread = GetHostDummyThread(existing_thread); |
| 329 | } | 332 | } |
| 330 | 333 | ||
| 331 | [[nodiscard]] u32 GetCurrentHostThreadID() { | 334 | [[nodiscard]] u32 GetCurrentHostThreadID() { |
| @@ -356,7 +359,7 @@ struct KernelCore::Impl { | |||
| 356 | KThread* GetCurrentEmuThread() { | 359 | KThread* GetCurrentEmuThread() { |
| 357 | const auto thread_id = GetCurrentHostThreadID(); | 360 | const auto thread_id = GetCurrentHostThreadID(); |
| 358 | if (thread_id >= Core::Hardware::NUM_CPU_CORES) { | 361 | if (thread_id >= Core::Hardware::NUM_CPU_CORES) { |
| 359 | return GetHostDummyThread(); | 362 | return GetHostDummyThread(nullptr); |
| 360 | } | 363 | } |
| 361 | 364 | ||
| 362 | return current_thread; | 365 | return current_thread; |
| @@ -1033,8 +1036,12 @@ void KernelCore::RegisterCoreThread(std::size_t core_id) { | |||
| 1033 | impl->RegisterCoreThread(core_id); | 1036 | impl->RegisterCoreThread(core_id); |
| 1034 | } | 1037 | } |
| 1035 | 1038 | ||
| 1036 | void KernelCore::RegisterHostThread() { | 1039 | void KernelCore::RegisterHostThread(KThread* existing_thread) { |
| 1037 | impl->RegisterHostThread(); | 1040 | impl->RegisterHostThread(existing_thread); |
| 1041 | |||
| 1042 | if (existing_thread != nullptr) { | ||
| 1043 | ASSERT(GetCurrentEmuThread() == existing_thread); | ||
| 1044 | } | ||
| 1038 | } | 1045 | } |
| 1039 | 1046 | ||
| 1040 | u32 KernelCore::GetCurrentHostThreadID() const { | 1047 | u32 KernelCore::GetCurrentHostThreadID() const { |
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 4ae6b3923..8a21568f7 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -236,7 +236,7 @@ public: | |||
| 236 | void RegisterCoreThread(std::size_t core_id); | 236 | void RegisterCoreThread(std::size_t core_id); |
| 237 | 237 | ||
| 238 | /// Register the current thread as a non CPU core thread. | 238 | /// Register the current thread as a non CPU core thread. |
| 239 | void RegisterHostThread(); | 239 | void RegisterHostThread(KThread* existing_thread = nullptr); |
| 240 | 240 | ||
| 241 | /// Gets the virtual memory manager for the kernel. | 241 | /// Gets the virtual memory manager for the kernel. |
| 242 | KMemoryManager& MemoryManager(); | 242 | KMemoryManager& MemoryManager(); |
diff --git a/src/core/hle/kernel/service_thread.cpp b/src/core/hle/kernel/service_thread.cpp index c8fe42537..7a85be77f 100644 --- a/src/core/hle/kernel/service_thread.cpp +++ b/src/core/hle/kernel/service_thread.cpp | |||
| @@ -36,11 +36,12 @@ public: | |||
| 36 | private: | 36 | private: |
| 37 | KernelCore& kernel; | 37 | KernelCore& kernel; |
| 38 | 38 | ||
| 39 | std::jthread m_thread; | 39 | std::jthread m_host_thread; |
| 40 | std::mutex m_session_mutex; | 40 | std::mutex m_session_mutex; |
| 41 | std::map<KServerSession*, std::shared_ptr<SessionRequestManager>> m_sessions; | 41 | std::map<KServerSession*, std::shared_ptr<SessionRequestManager>> m_sessions; |
| 42 | KEvent* m_wakeup_event; | 42 | KEvent* m_wakeup_event; |
| 43 | KProcess* m_process; | 43 | KProcess* m_process; |
| 44 | KThread* m_thread; | ||
| 44 | std::atomic<bool> m_shutdown_requested; | 45 | std::atomic<bool> m_shutdown_requested; |
| 45 | const std::string m_service_name; | 46 | const std::string m_service_name; |
| 46 | }; | 47 | }; |
| @@ -132,7 +133,7 @@ void ServiceThread::Impl::SessionClosed(KServerSession* server_session, | |||
| 132 | void ServiceThread::Impl::LoopProcess() { | 133 | void ServiceThread::Impl::LoopProcess() { |
| 133 | Common::SetCurrentThreadName(m_service_name.c_str()); | 134 | Common::SetCurrentThreadName(m_service_name.c_str()); |
| 134 | 135 | ||
| 135 | kernel.RegisterHostThread(); | 136 | kernel.RegisterHostThread(m_thread); |
| 136 | 137 | ||
| 137 | while (!m_shutdown_requested.load()) { | 138 | while (!m_shutdown_requested.load()) { |
| 138 | WaitAndProcessImpl(); | 139 | WaitAndProcessImpl(); |
| @@ -160,7 +161,7 @@ ServiceThread::Impl::~Impl() { | |||
| 160 | // Shut down the processing thread. | 161 | // Shut down the processing thread. |
| 161 | m_shutdown_requested.store(true); | 162 | m_shutdown_requested.store(true); |
| 162 | m_wakeup_event->Signal(); | 163 | m_wakeup_event->Signal(); |
| 163 | m_thread.join(); | 164 | m_host_thread.join(); |
| 164 | 165 | ||
| 165 | // Lock mutex. | 166 | // Lock mutex. |
| 166 | m_session_mutex.lock(); | 167 | m_session_mutex.lock(); |
| @@ -177,6 +178,9 @@ ServiceThread::Impl::~Impl() { | |||
| 177 | m_wakeup_event->GetReadableEvent().Close(); | 178 | m_wakeup_event->GetReadableEvent().Close(); |
| 178 | m_wakeup_event->Close(); | 179 | m_wakeup_event->Close(); |
| 179 | 180 | ||
| 181 | // Close thread. | ||
| 182 | m_thread->Close(); | ||
| 183 | |||
| 180 | // Close process. | 184 | // Close process. |
| 181 | m_process->Close(); | 185 | m_process->Close(); |
| 182 | } | 186 | } |
| @@ -199,11 +203,19 @@ ServiceThread::Impl::Impl(KernelCore& kernel_, const std::string& service_name) | |||
| 199 | // Commit the event reservation. | 203 | // Commit the event reservation. |
| 200 | event_reservation.Commit(); | 204 | event_reservation.Commit(); |
| 201 | 205 | ||
| 202 | // Register the event. | 206 | // Reserve a new thread from the process resource limit |
| 203 | KEvent::Register(kernel, m_wakeup_event); | 207 | KScopedResourceReservation thread_reservation(m_process, LimitableResource::Threads); |
| 208 | ASSERT(thread_reservation.Succeeded()); | ||
| 209 | |||
| 210 | // Initialize thread. | ||
| 211 | m_thread = KThread::Create(kernel); | ||
| 212 | ASSERT(KThread::InitializeDummyThread(m_thread, m_process).IsSuccess()); | ||
| 213 | |||
| 214 | // Commit the thread reservation. | ||
| 215 | thread_reservation.Commit(); | ||
| 204 | 216 | ||
| 205 | // Start thread. | 217 | // Start thread. |
| 206 | m_thread = std::jthread([this] { LoopProcess(); }); | 218 | m_host_thread = std::jthread([this] { LoopProcess(); }); |
| 207 | } | 219 | } |
| 208 | 220 | ||
| 209 | ServiceThread::ServiceThread(KernelCore& kernel, const std::string& name) | 221 | ServiceThread::ServiceThread(KernelCore& kernel, const std::string& name) |