diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/kernel/hle_ipc.cpp | 14 | ||||
| -rw-r--r-- | src/core/hle/kernel/hle_ipc.h | 6 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 42 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 10 |
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 | ||
| 28 | SessionRequestHandler::SessionRequestHandler(KernelCore& kernel_, const char* service_name_, | 28 | SessionRequestHandler::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 | ||
| 38 | SessionRequestHandler::~SessionRequestHandler() { | 34 | SessionRequestHandler::~SessionRequestHandler() { |
| 39 | kernel.ReleaseServiceThread(service_thread.lock()); | 35 | kernel.ReleaseServiceThread(service_thread); |
| 40 | } | 36 | } |
| 41 | 37 | ||
| 42 | void SessionRequestHandler::AcceptSession(KServerPort* server_port) { | 38 | void SessionRequestHandler::AcceptSession(KServerPort* server_port) { |
| @@ -49,7 +45,7 @@ void SessionRequestHandler::AcceptSession(KServerPort* server_port) { | |||
| 49 | void SessionRequestHandler::RegisterSession(KServerSession* server_session, | 45 | void 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 | ||
| 89 | protected: | 89 | protected: |
| 90 | KernelCore& kernel; | 90 | KernelCore& kernel; |
| 91 | std::weak_ptr<ServiceThread> service_thread; | 91 | ServiceThread& service_thread; |
| 92 | }; | 92 | }; |
| 93 | 93 | ||
| 94 | using SessionRequestHandlerWeakPtr = std::weak_ptr<SessionRequestHandler>; | 94 | using 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 | ||
| 1242 | std::weak_ptr<Kernel::ServiceThread> KernelCore::CreateServiceThread(const std::string& name) { | 1240 | Kernel::ServiceThread& KernelCore::CreateServiceThread(const std::string& name) { |
| 1243 | return impl->CreateServiceThread(*this, name); | 1241 | return impl->CreateServiceThread(*this, name); |
| 1244 | } | 1242 | } |
| 1245 | 1243 | ||
| 1246 | std::weak_ptr<Kernel::ServiceThread> KernelCore::GetDefaultServiceThread() const { | 1244 | Kernel::ServiceThread& KernelCore::GetDefaultServiceThread() const { |
| 1247 | return impl->default_service_thread; | 1245 | return *impl->default_service_thread; |
| 1248 | } | 1246 | } |
| 1249 | 1247 | ||
| 1250 | void KernelCore::ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread) { | 1248 | void 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; |