summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/kernel/k_thread.cpp4
-rw-r--r--src/core/hle/kernel/k_thread.h2
-rw-r--r--src/core/hle/kernel/kernel.cpp27
-rw-r--r--src/core/hle/kernel/kernel.h2
-rw-r--r--src/core/hle/kernel/service_thread.cpp24
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
266Result KThread::InitializeDummyThread(KThread* thread) { 266Result 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
1036void KernelCore::RegisterHostThread() { 1039void 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
1040u32 KernelCore::GetCurrentHostThreadID() const { 1047u32 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:
36private: 36private:
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,
132void ServiceThread::Impl::LoopProcess() { 133void 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
209ServiceThread::ServiceThread(KernelCore& kernel, const std::string& name) 221ServiceThread::ServiceThread(KernelCore& kernel, const std::string& name)