summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp14
-rw-r--r--src/core/hle/kernel/hle_ipc.h6
-rw-r--r--src/core/hle/kernel/kernel.cpp42
-rw-r--r--src/core/hle/kernel/kernel.h10
4 files changed, 33 insertions, 39 deletions
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index fd354d484..06010b8d1 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -27,16 +27,12 @@ namespace Kernel {
27 27
28SessionRequestHandler::SessionRequestHandler(KernelCore& kernel_, const char* service_name_, 28SessionRequestHandler::SessionRequestHandler(KernelCore& kernel_, const char* service_name_,
29 ServiceThreadType thread_type) 29 ServiceThreadType thread_type)
30 : kernel{kernel_} { 30 : kernel{kernel_}, service_thread{thread_type == ServiceThreadType::CreateNew
31 if (thread_type == ServiceThreadType::CreateNew) { 31 ? kernel.CreateServiceThread(service_name_)
32 service_thread = kernel.CreateServiceThread(service_name_); 32 : kernel.GetDefaultServiceThread()} {}
33 } else {
34 service_thread = kernel.GetDefaultServiceThread();
35 }
36}
37 33
38SessionRequestHandler::~SessionRequestHandler() { 34SessionRequestHandler::~SessionRequestHandler() {
39 kernel.ReleaseServiceThread(service_thread.lock()); 35 kernel.ReleaseServiceThread(service_thread);
40} 36}
41 37
42void SessionRequestHandler::AcceptSession(KServerPort* server_port) { 38void SessionRequestHandler::AcceptSession(KServerPort* server_port) {
@@ -49,7 +45,7 @@ void SessionRequestHandler::AcceptSession(KServerPort* server_port) {
49void SessionRequestHandler::RegisterSession(KServerSession* server_session, 45void SessionRequestHandler::RegisterSession(KServerSession* server_session,
50 std::shared_ptr<SessionRequestManager> manager) { 46 std::shared_ptr<SessionRequestManager> manager) {
51 manager->SetSessionHandler(shared_from_this()); 47 manager->SetSessionHandler(shared_from_this());
52 service_thread.lock()->RegisterServerSession(server_session, manager); 48 service_thread.RegisterServerSession(server_session, manager);
53 server_session->Close(); 49 server_session->Close();
54} 50}
55 51
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h
index 67da8e7e1..d87be72d6 100644
--- a/src/core/hle/kernel/hle_ipc.h
+++ b/src/core/hle/kernel/hle_ipc.h
@@ -82,13 +82,13 @@ public:
82 void RegisterSession(KServerSession* server_session, 82 void RegisterSession(KServerSession* server_session,
83 std::shared_ptr<SessionRequestManager> manager); 83 std::shared_ptr<SessionRequestManager> manager);
84 84
85 std::weak_ptr<ServiceThread> GetServiceThread() const { 85 ServiceThread& GetServiceThread() const {
86 return service_thread; 86 return service_thread;
87 } 87 }
88 88
89protected: 89protected:
90 KernelCore& kernel; 90 KernelCore& kernel;
91 std::weak_ptr<ServiceThread> service_thread; 91 ServiceThread& service_thread;
92}; 92};
93 93
94using SessionRequestHandlerWeakPtr = std::weak_ptr<SessionRequestHandler>; 94using SessionRequestHandlerWeakPtr = std::weak_ptr<SessionRequestHandler>;
@@ -154,7 +154,7 @@ public:
154 session_handler = std::move(handler); 154 session_handler = std::move(handler);
155 } 155 }
156 156
157 std::weak_ptr<ServiceThread> GetServiceThread() const { 157 ServiceThread& GetServiceThread() const {
158 return session_handler->GetServiceThread(); 158 return session_handler->GetServiceThread();
159 } 159 }
160 160
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 47b760a9c..abff14079 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -93,7 +93,7 @@ struct KernelCore::Impl {
93 93
94 RegisterHostThread(); 94 RegisterHostThread();
95 95
96 default_service_thread = CreateServiceThread(kernel, "DefaultServiceThread"); 96 default_service_thread = &CreateServiceThread(kernel, "DefaultServiceThread");
97 } 97 }
98 98
99 void InitializeCores() { 99 void InitializeCores() {
@@ -779,33 +779,31 @@ struct KernelCore::Impl {
779 search->second(system.ServiceManager(), server_port); 779 search->second(system.ServiceManager(), server_port);
780 } 780 }
781 781
782 std::weak_ptr<Kernel::ServiceThread> CreateServiceThread(KernelCore& kernel, 782 Kernel::ServiceThread& CreateServiceThread(KernelCore& kernel, const std::string& name) {
783 const std::string& name) { 783 auto* ptr = new ServiceThread(kernel, name);
784 auto service_thread = std::make_shared<Kernel::ServiceThread>(kernel, name);
785 784
786 service_threads_manager.QueueWork( 785 service_threads_manager.QueueWork(
787 [this, service_thread]() { service_threads.emplace(service_thread); }); 786 [this, ptr]() { service_threads.emplace(ptr, std::unique_ptr<ServiceThread>(ptr)); });
788 787
789 return service_thread; 788 return *ptr;
790 } 789 }
791 790
792 void ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread) { 791 void ReleaseServiceThread(Kernel::ServiceThread& service_thread) {
793 if (auto strong_ptr = service_thread.lock()) { 792 auto* ptr = &service_thread;
794 if (strong_ptr == default_service_thread.lock()) {
795 // Nothing to do here, the service is using default_service_thread, which will be
796 // released on shutdown.
797 return;
798 }
799 793
800 service_threads_manager.QueueWork( 794 if (ptr == default_service_thread) {
801 [this, strong_ptr{std::move(strong_ptr)}]() { service_threads.erase(strong_ptr); }); 795 // Nothing to do here, the service is using default_service_thread, which will be
796 // released on shutdown.
797 return;
802 } 798 }
799
800 service_threads_manager.QueueWork([this, ptr]() { service_threads.erase(ptr); });
803 } 801 }
804 802
805 void ClearServiceThreads() { 803 void ClearServiceThreads() {
806 service_threads_manager.QueueWork([this] { 804 service_threads_manager.QueueWork([this] {
807 service_threads.clear(); 805 service_threads.clear();
808 default_service_thread.reset(); 806 default_service_thread = nullptr;
809 service_thread_barrier.Sync(); 807 service_thread_barrier.Sync();
810 }); 808 });
811 service_thread_barrier.Sync(); 809 service_thread_barrier.Sync();
@@ -881,8 +879,8 @@ struct KernelCore::Impl {
881 std::unique_ptr<KMemoryLayout> memory_layout; 879 std::unique_ptr<KMemoryLayout> memory_layout;
882 880
883 // Threads used for services 881 // Threads used for services
884 std::unordered_set<std::shared_ptr<ServiceThread>> service_threads; 882 std::unordered_map<ServiceThread*, std::unique_ptr<ServiceThread>> service_threads;
885 std::weak_ptr<ServiceThread> default_service_thread; 883 ServiceThread* default_service_thread{};
886 Common::ThreadWorker service_threads_manager; 884 Common::ThreadWorker service_threads_manager;
887 Common::Barrier service_thread_barrier; 885 Common::Barrier service_thread_barrier;
888 886
@@ -1239,15 +1237,15 @@ void KernelCore::ExitSVCProfile() {
1239 MicroProfileLeave(MICROPROFILE_TOKEN(Kernel_SVC), impl->svc_ticks[CurrentPhysicalCoreIndex()]); 1237 MicroProfileLeave(MICROPROFILE_TOKEN(Kernel_SVC), impl->svc_ticks[CurrentPhysicalCoreIndex()]);
1240} 1238}
1241 1239
1242std::weak_ptr<Kernel::ServiceThread> KernelCore::CreateServiceThread(const std::string& name) { 1240Kernel::ServiceThread& KernelCore::CreateServiceThread(const std::string& name) {
1243 return impl->CreateServiceThread(*this, name); 1241 return impl->CreateServiceThread(*this, name);
1244} 1242}
1245 1243
1246std::weak_ptr<Kernel::ServiceThread> KernelCore::GetDefaultServiceThread() const { 1244Kernel::ServiceThread& KernelCore::GetDefaultServiceThread() const {
1247 return impl->default_service_thread; 1245 return *impl->default_service_thread;
1248} 1246}
1249 1247
1250void KernelCore::ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread) { 1248void KernelCore::ReleaseServiceThread(Kernel::ServiceThread& service_thread) {
1251 impl->ReleaseServiceThread(service_thread); 1249 impl->ReleaseServiceThread(service_thread);
1252} 1250}
1253 1251
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index caca60586..29617d736 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -309,24 +309,24 @@ public:
309 * See GetDefaultServiceThread. 309 * See GetDefaultServiceThread.
310 * @param name String name for the ServerSession creating this thread, used for debug 310 * @param name String name for the ServerSession creating this thread, used for debug
311 * purposes. 311 * purposes.
312 * @returns The a weak pointer newly created service thread. 312 * @returns A reference to the newly created service thread.
313 */ 313 */
314 std::weak_ptr<Kernel::ServiceThread> CreateServiceThread(const std::string& name); 314 Kernel::ServiceThread& CreateServiceThread(const std::string& name);
315 315
316 /** 316 /**
317 * Gets the default host service thread, which executes HLE service requests. Unless service 317 * Gets the default host service thread, which executes HLE service requests. Unless service
318 * requests need to block on the host, the default service thread should be used in favor of 318 * requests need to block on the host, the default service thread should be used in favor of
319 * creating a new service thread. 319 * creating a new service thread.
320 * @returns The a weak pointer for the default service thread. 320 * @returns A reference to the default service thread.
321 */ 321 */
322 std::weak_ptr<Kernel::ServiceThread> GetDefaultServiceThread() const; 322 Kernel::ServiceThread& GetDefaultServiceThread() const;
323 323
324 /** 324 /**
325 * Releases a HLE service thread, instructing KernelCore to free it. This should be called when 325 * Releases a HLE service thread, instructing KernelCore to free it. This should be called when
326 * the ServerSession associated with the thread is destroyed. 326 * the ServerSession associated with the thread is destroyed.
327 * @param service_thread Service thread to release. 327 * @param service_thread Service thread to release.
328 */ 328 */
329 void ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread); 329 void ReleaseServiceThread(Kernel::ServiceThread& service_thread);
330 330
331 /// Workaround for single-core mode when preempting threads while idle. 331 /// Workaround for single-core mode when preempting threads while idle.
332 bool IsPhantomModeForSingleCore() const; 332 bool IsPhantomModeForSingleCore() const;