diff options
| author | 2022-10-30 22:22:14 -0400 | |
|---|---|---|
| committer | 2022-10-31 17:47:39 -0400 | |
| commit | 77b74f5d95626422f59b508cd2b355135ed256ca (patch) | |
| tree | cde636e3e2241941d13e66964d2fd3154e0002fa | |
| parent | kernel: fix single core for service threads (diff) | |
| download | yuzu-77b74f5d95626422f59b508cd2b355135ed256ca.tar.gz yuzu-77b74f5d95626422f59b508cd2b355135ed256ca.tar.xz yuzu-77b74f5d95626422f59b508cd2b355135ed256ca.zip | |
sm:: avoid excessive port recreation
| -rw-r--r-- | src/core/hle/service/service.cpp | 10 | ||||
| -rw-r--r-- | src/core/hle/service/sm/sm.cpp | 31 | ||||
| -rw-r--r-- | src/core/hle/service/sm/sm.h | 1 |
3 files changed, 24 insertions, 18 deletions
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 6a64c6005..5ab41c0c4 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp | |||
| @@ -119,12 +119,14 @@ void ServiceFrameworkBase::InstallAsService(SM::ServiceManager& service_manager) | |||
| 119 | Kernel::KClientPort& ServiceFrameworkBase::CreatePort() { | 119 | Kernel::KClientPort& ServiceFrameworkBase::CreatePort() { |
| 120 | const auto guard = LockService(); | 120 | const auto guard = LockService(); |
| 121 | 121 | ||
| 122 | ASSERT(!service_registered); | 122 | if (named_port == nullptr) { |
| 123 | ASSERT(!service_registered); | ||
| 123 | 124 | ||
| 124 | named_port = Kernel::KPort::Create(kernel); | 125 | named_port = Kernel::KPort::Create(kernel); |
| 125 | named_port->Initialize(max_sessions, false, service_name); | 126 | named_port->Initialize(max_sessions, false, service_name); |
| 126 | 127 | ||
| 127 | service_registered = true; | 128 | service_registered = true; |
| 129 | } | ||
| 128 | 130 | ||
| 129 | return named_port->GetClientPort(); | 131 | return named_port->GetClientPort(); |
| 130 | } | 132 | } |
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index c1f535d71..84720094f 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp | |||
| @@ -23,7 +23,13 @@ constexpr Result ERR_INVALID_NAME(ErrorModule::SM, 6); | |||
| 23 | constexpr Result ERR_SERVICE_NOT_REGISTERED(ErrorModule::SM, 7); | 23 | constexpr Result ERR_SERVICE_NOT_REGISTERED(ErrorModule::SM, 7); |
| 24 | 24 | ||
| 25 | ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} {} | 25 | ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} {} |
| 26 | ServiceManager::~ServiceManager() = default; | 26 | |
| 27 | ServiceManager::~ServiceManager() { | ||
| 28 | for (auto& [name, port] : service_ports) { | ||
| 29 | port->GetClientPort().Close(); | ||
| 30 | port->GetServerPort().Close(); | ||
| 31 | } | ||
| 32 | } | ||
| 27 | 33 | ||
| 28 | void ServiceManager::InvokeControlRequest(Kernel::HLERequestContext& context) { | 34 | void ServiceManager::InvokeControlRequest(Kernel::HLERequestContext& context) { |
| 29 | controller_interface->InvokeRequest(context); | 35 | controller_interface->InvokeRequest(context); |
| @@ -57,7 +63,11 @@ Result ServiceManager::RegisterService(std::string name, u32 max_sessions, | |||
| 57 | return ERR_ALREADY_REGISTERED; | 63 | return ERR_ALREADY_REGISTERED; |
| 58 | } | 64 | } |
| 59 | 65 | ||
| 60 | registered_services.emplace(std::move(name), handler); | 66 | auto* port = Kernel::KPort::Create(kernel); |
| 67 | port->Initialize(ServerSessionCountMax, false, name); | ||
| 68 | |||
| 69 | service_ports.emplace(name, port); | ||
| 70 | registered_services.emplace(name, handler); | ||
| 61 | 71 | ||
| 62 | return ResultSuccess; | 72 | return ResultSuccess; |
| 63 | } | 73 | } |
| @@ -72,23 +82,20 @@ Result ServiceManager::UnregisterService(const std::string& name) { | |||
| 72 | } | 82 | } |
| 73 | 83 | ||
| 74 | registered_services.erase(iter); | 84 | registered_services.erase(iter); |
| 85 | service_ports.erase(name); | ||
| 86 | |||
| 75 | return ResultSuccess; | 87 | return ResultSuccess; |
| 76 | } | 88 | } |
| 77 | 89 | ||
| 78 | ResultVal<Kernel::KPort*> ServiceManager::GetServicePort(const std::string& name) { | 90 | ResultVal<Kernel::KPort*> ServiceManager::GetServicePort(const std::string& name) { |
| 79 | CASCADE_CODE(ValidateServiceName(name)); | 91 | CASCADE_CODE(ValidateServiceName(name)); |
| 80 | auto it = registered_services.find(name); | 92 | auto it = service_ports.find(name); |
| 81 | if (it == registered_services.end()) { | 93 | if (it == service_ports.end()) { |
| 82 | LOG_ERROR(Service_SM, "Server is not registered! service={}", name); | 94 | LOG_ERROR(Service_SM, "Server is not registered! service={}", name); |
| 83 | return ERR_SERVICE_NOT_REGISTERED; | 95 | return ERR_SERVICE_NOT_REGISTERED; |
| 84 | } | 96 | } |
| 85 | 97 | ||
| 86 | auto* port = Kernel::KPort::Create(kernel); | 98 | return it->second; |
| 87 | |||
| 88 | port->Initialize(ServerSessionCountMax, false, name); | ||
| 89 | auto handler = it->second; | ||
| 90 | |||
| 91 | return port; | ||
| 92 | } | 99 | } |
| 93 | 100 | ||
| 94 | /** | 101 | /** |
| @@ -153,10 +160,6 @@ ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(Kernel::HLERequestContext& | |||
| 153 | return port_result.Code(); | 160 | return port_result.Code(); |
| 154 | } | 161 | } |
| 155 | auto& port = port_result.Unwrap(); | 162 | auto& port = port_result.Unwrap(); |
| 156 | SCOPE_EXIT({ | ||
| 157 | port->GetClientPort().Close(); | ||
| 158 | port->GetServerPort().Close(); | ||
| 159 | }); | ||
| 160 | 163 | ||
| 161 | // Create a new session. | 164 | // Create a new session. |
| 162 | Kernel::KClientSession* session{}; | 165 | Kernel::KClientSession* session{}; |
diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h index cfe370652..02a5dde9e 100644 --- a/src/core/hle/service/sm/sm.h +++ b/src/core/hle/service/sm/sm.h | |||
| @@ -79,6 +79,7 @@ private: | |||
| 79 | 79 | ||
| 80 | /// Map of registered services, retrieved using GetServicePort. | 80 | /// Map of registered services, retrieved using GetServicePort. |
| 81 | std::unordered_map<std::string, Kernel::SessionRequestHandlerPtr> registered_services; | 81 | std::unordered_map<std::string, Kernel::SessionRequestHandlerPtr> registered_services; |
| 82 | std::unordered_map<std::string, Kernel::KPort*> service_ports; | ||
| 82 | 83 | ||
| 83 | /// Kernel context | 84 | /// Kernel context |
| 84 | Kernel::KernelCore& kernel; | 85 | Kernel::KernelCore& kernel; |