summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Liam2022-10-30 22:22:14 -0400
committerGravatar Liam2022-10-31 17:47:39 -0400
commit77b74f5d95626422f59b508cd2b355135ed256ca (patch)
treecde636e3e2241941d13e66964d2fd3154e0002fa
parentkernel: fix single core for service threads (diff)
downloadyuzu-77b74f5d95626422f59b508cd2b355135ed256ca.tar.gz
yuzu-77b74f5d95626422f59b508cd2b355135ed256ca.tar.xz
yuzu-77b74f5d95626422f59b508cd2b355135ed256ca.zip
sm:: avoid excessive port recreation
-rw-r--r--src/core/hle/service/service.cpp10
-rw-r--r--src/core/hle/service/sm/sm.cpp31
-rw-r--r--src/core/hle/service/sm/sm.h1
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)
119Kernel::KClientPort& ServiceFrameworkBase::CreatePort() { 119Kernel::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);
23constexpr Result ERR_SERVICE_NOT_REGISTERED(ErrorModule::SM, 7); 23constexpr Result ERR_SERVICE_NOT_REGISTERED(ErrorModule::SM, 7);
24 24
25ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} {} 25ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} {}
26ServiceManager::~ServiceManager() = default; 26
27ServiceManager::~ServiceManager() {
28 for (auto& [name, port] : service_ports) {
29 port->GetClientPort().Close();
30 port->GetServerPort().Close();
31 }
32}
27 33
28void ServiceManager::InvokeControlRequest(Kernel::HLERequestContext& context) { 34void 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
78ResultVal<Kernel::KPort*> ServiceManager::GetServicePort(const std::string& name) { 90ResultVal<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;