mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Merge pull request #4716 from wwylele/client-is-known
HLE/IPC: HLEContext can memorize the client thread and use it for SleepClientThread
This commit is contained in:
		
						commit
						11754778bb
					
				
					 8 changed files with 16 additions and 22 deletions
				
			
		|  | @ -32,8 +32,7 @@ void SessionRequestHandler::ClientDisconnected(std::shared_ptr<ServerSession> se | ||||||
|         connected_sessions.end()); |         connected_sessions.end()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::shared_ptr<Event> HLERequestContext::SleepClientThread(std::shared_ptr<Thread> thread, | std::shared_ptr<Event> HLERequestContext::SleepClientThread(const std::string& reason, | ||||||
|                                                             const std::string& reason, |  | ||||||
|                                                             std::chrono::nanoseconds timeout, |                                                             std::chrono::nanoseconds timeout, | ||||||
|                                                             WakeupCallback&& callback) { |                                                             WakeupCallback&& callback) { | ||||||
|     // Put the client thread to sleep until the wait event is signaled or the timeout expires.
 |     // Put the client thread to sleep until the wait event is signaled or the timeout expires.
 | ||||||
|  | @ -60,7 +59,7 @@ std::shared_ptr<Event> HLERequestContext::SleepClientThread(std::shared_ptr<Thre | ||||||
|     auto event = kernel.CreateEvent(Kernel::ResetType::OneShot, "HLE Pause Event: " + reason); |     auto event = kernel.CreateEvent(Kernel::ResetType::OneShot, "HLE Pause Event: " + reason); | ||||||
|     thread->status = ThreadStatus::WaitHleEvent; |     thread->status = ThreadStatus::WaitHleEvent; | ||||||
|     thread->wait_objects = {event}; |     thread->wait_objects = {event}; | ||||||
|     event->AddWaitingThread(thread); |     event->AddWaitingThread(SharedFrom(thread)); | ||||||
| 
 | 
 | ||||||
|     if (timeout.count() > 0) |     if (timeout.count() > 0) | ||||||
|         thread->WakeAfterDelay(timeout.count()); |         thread->WakeAfterDelay(timeout.count()); | ||||||
|  | @ -68,8 +67,9 @@ std::shared_ptr<Event> HLERequestContext::SleepClientThread(std::shared_ptr<Thre | ||||||
|     return event; |     return event; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| HLERequestContext::HLERequestContext(KernelSystem& kernel, std::shared_ptr<ServerSession> session) | HLERequestContext::HLERequestContext(KernelSystem& kernel, std::shared_ptr<ServerSession> session, | ||||||
|     : kernel(kernel), session(std::move(session)) { |                                      Thread* thread) | ||||||
|  |     : kernel(kernel), session(std::move(session)), thread(thread) { | ||||||
|     cmd_buf[0] = 0; |     cmd_buf[0] = 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -158,7 +158,7 @@ private: | ||||||
|  */ |  */ | ||||||
| class HLERequestContext { | class HLERequestContext { | ||||||
| public: | public: | ||||||
|     HLERequestContext(KernelSystem& kernel, std::shared_ptr<ServerSession> session); |     HLERequestContext(KernelSystem& kernel, std::shared_ptr<ServerSession> session, Thread* thread); | ||||||
|     ~HLERequestContext(); |     ~HLERequestContext(); | ||||||
| 
 | 
 | ||||||
|     /// Returns a pointer to the IPC command buffer for this request.
 |     /// Returns a pointer to the IPC command buffer for this request.
 | ||||||
|  | @ -180,7 +180,6 @@ public: | ||||||
|     /**
 |     /**
 | ||||||
|      * Puts the specified guest thread to sleep until the returned event is signaled or until the |      * Puts the specified guest thread to sleep until the returned event is signaled or until the | ||||||
|      * specified timeout expires. |      * specified timeout expires. | ||||||
|      * @param thread Thread to be put to sleep. |  | ||||||
|      * @param reason Reason for pausing the thread, to be used for debugging purposes. |      * @param reason Reason for pausing the thread, to be used for debugging purposes. | ||||||
|      * @param timeout Timeout in nanoseconds after which the thread will be awoken and the callback |      * @param timeout Timeout in nanoseconds after which the thread will be awoken and the callback | ||||||
|      * invoked with a Timeout reason. |      * invoked with a Timeout reason. | ||||||
|  | @ -189,8 +188,7 @@ public: | ||||||
|      * was called. |      * was called. | ||||||
|      * @returns Event that when signaled will resume the thread and call the callback function. |      * @returns Event that when signaled will resume the thread and call the callback function. | ||||||
|      */ |      */ | ||||||
|     std::shared_ptr<Event> SleepClientThread(std::shared_ptr<Thread> thread, |     std::shared_ptr<Event> SleepClientThread(const std::string& reason, | ||||||
|                                              const std::string& reason, |  | ||||||
|                                              std::chrono::nanoseconds timeout, |                                              std::chrono::nanoseconds timeout, | ||||||
|                                              WakeupCallback&& callback); |                                              WakeupCallback&& callback); | ||||||
| 
 | 
 | ||||||
|  | @ -240,6 +238,7 @@ private: | ||||||
|     KernelSystem& kernel; |     KernelSystem& kernel; | ||||||
|     std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf; |     std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf; | ||||||
|     std::shared_ptr<ServerSession> session; |     std::shared_ptr<ServerSession> session; | ||||||
|  |     Thread* thread; | ||||||
|     // TODO(yuriks): Check common usage of this and optimize size accordingly
 |     // TODO(yuriks): Check common usage of this and optimize size accordingly
 | ||||||
|     boost::container::small_vector<std::shared_ptr<Object>, 8> request_handles; |     boost::container::small_vector<std::shared_ptr<Object>, 8> request_handles; | ||||||
|     // The static buffers will be created when the IPC request is translated.
 |     // The static buffers will be created when the IPC request is translated.
 | ||||||
|  |  | ||||||
|  | @ -72,7 +72,7 @@ ResultCode ServerSession::HandleSyncRequest(std::shared_ptr<Thread> thread) { | ||||||
|         kernel.memory.ReadBlock(*current_process, thread->GetCommandBufferAddress(), cmd_buf.data(), |         kernel.memory.ReadBlock(*current_process, thread->GetCommandBufferAddress(), cmd_buf.data(), | ||||||
|                                 cmd_buf.size() * sizeof(u32)); |                                 cmd_buf.size() * sizeof(u32)); | ||||||
| 
 | 
 | ||||||
|         Kernel::HLERequestContext context(kernel, SharedFrom(this)); |         Kernel::HLERequestContext context(kernel, SharedFrom(this), thread.get()); | ||||||
|         context.PopulateFromIncomingCommandBuffer(cmd_buf.data(), *current_process); |         context.PopulateFromIncomingCommandBuffer(cmd_buf.data(), *current_process); | ||||||
| 
 | 
 | ||||||
|         hle_handler->HandleSyncRequest(context); |         hle_handler->HandleSyncRequest(context); | ||||||
|  |  | ||||||
|  | @ -71,8 +71,7 @@ void File::Read(Kernel::HLERequestContext& ctx) { | ||||||
|     rb.PushMappedBuffer(buffer); |     rb.PushMappedBuffer(buffer); | ||||||
| 
 | 
 | ||||||
|     std::chrono::nanoseconds read_timeout_ns{backend->GetReadDelayNs(length)}; |     std::chrono::nanoseconds read_timeout_ns{backend->GetReadDelayNs(length)}; | ||||||
|     ctx.SleepClientThread(Kernel::SharedFrom(system.Kernel().GetThreadManager().GetCurrentThread()), |     ctx.SleepClientThread("file::read", read_timeout_ns, | ||||||
|                           "file::read", read_timeout_ns, |  | ||||||
|                           [](std::shared_ptr<Kernel::Thread> /*thread*/, |                           [](std::shared_ptr<Kernel::Thread> /*thread*/, | ||||||
|                              Kernel::HLERequestContext& /*ctx*/, |                              Kernel::HLERequestContext& /*ctx*/, | ||||||
|                              Kernel::ThreadWakeupReason /*reason*/) { |                              Kernel::ThreadWakeupReason /*reason*/) { | ||||||
|  |  | ||||||
|  | @ -71,8 +71,7 @@ void FS_USER::OpenFile(Kernel::HLERequestContext& ctx) { | ||||||
|         LOG_ERROR(Service_FS, "failed to get a handle for file {}", file_path.DebugStr()); |         LOG_ERROR(Service_FS, "failed to get a handle for file {}", file_path.DebugStr()); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     ctx.SleepClientThread(Kernel::SharedFrom(system.Kernel().GetThreadManager().GetCurrentThread()), |     ctx.SleepClientThread("fs_user::open", open_timeout_ns, | ||||||
|                           "fs_user::open", open_timeout_ns, |  | ||||||
|                           [](std::shared_ptr<Kernel::Thread> /*thread*/, |                           [](std::shared_ptr<Kernel::Thread> /*thread*/, | ||||||
|                              Kernel::HLERequestContext& /*ctx*/, |                              Kernel::HLERequestContext& /*ctx*/, | ||||||
|                              Kernel::ThreadWakeupReason /*reason*/) { |                              Kernel::ThreadWakeupReason /*reason*/) { | ||||||
|  | @ -130,8 +129,7 @@ void FS_USER::OpenFileDirectly(Kernel::HLERequestContext& ctx) { | ||||||
|                   file_path.DebugStr(), mode.hex, attributes); |                   file_path.DebugStr(), mode.hex, attributes); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     ctx.SleepClientThread(Kernel::SharedFrom(system.Kernel().GetThreadManager().GetCurrentThread()), |     ctx.SleepClientThread("fs_user::open_directly", open_timeout_ns, | ||||||
|                           "fs_user::open_directly", open_timeout_ns, |  | ||||||
|                           [](std::shared_ptr<Kernel::Thread> /*thread*/, |                           [](std::shared_ptr<Kernel::Thread> /*thread*/, | ||||||
|                              Kernel::HLERequestContext& /*ctx*/, |                              Kernel::HLERequestContext& /*ctx*/, | ||||||
|                              Kernel::ThreadWakeupReason /*reason*/) { |                              Kernel::ThreadWakeupReason /*reason*/) { | ||||||
|  |  | ||||||
|  | @ -1179,7 +1179,6 @@ void NWM_UDS::ConnectToNetwork(Kernel::HLERequestContext& ctx, u16 command_id, | ||||||
|     static constexpr std::chrono::nanoseconds UDSConnectionTimeout{300000000}; |     static constexpr std::chrono::nanoseconds UDSConnectionTimeout{300000000}; | ||||||
| 
 | 
 | ||||||
|     connection_event = ctx.SleepClientThread( |     connection_event = ctx.SleepClientThread( | ||||||
|         Kernel::SharedFrom(system.Kernel().GetThreadManager().GetCurrentThread()), |  | ||||||
|         "uds::ConnectToNetwork", UDSConnectionTimeout, |         "uds::ConnectToNetwork", UDSConnectionTimeout, | ||||||
|         [command_id](std::shared_ptr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx, |         [command_id](std::shared_ptr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx, | ||||||
|                      Kernel::ThreadWakeupReason reason) { |                      Kernel::ThreadWakeupReason reason) { | ||||||
|  |  | ||||||
|  | @ -127,9 +127,8 @@ void SRV::GetServiceHandle(Kernel::HLERequestContext& ctx) { | ||||||
|     if (client_port.Failed()) { |     if (client_port.Failed()) { | ||||||
|         if (wait_until_available && client_port.Code() == ERR_SERVICE_NOT_REGISTERED) { |         if (wait_until_available && client_port.Code() == ERR_SERVICE_NOT_REGISTERED) { | ||||||
|             LOG_INFO(Service_SRV, "called service={} delayed", name); |             LOG_INFO(Service_SRV, "called service={} delayed", name); | ||||||
|             std::shared_ptr<Kernel::Event> get_service_handle_event = ctx.SleepClientThread( |             std::shared_ptr<Kernel::Event> get_service_handle_event = | ||||||
|                 Kernel::SharedFrom(system.Kernel().GetThreadManager().GetCurrentThread()), |                 ctx.SleepClientThread("GetServiceHandle", std::chrono::nanoseconds(-1), get_handle); | ||||||
|                 "GetServiceHandle", std::chrono::nanoseconds(-1), get_handle); |  | ||||||
|             get_service_handle_delayed_map[name] = std::move(get_service_handle_event); |             get_service_handle_delayed_map[name] = std::move(get_service_handle_event); | ||||||
|             return; |             return; | ||||||
|         } else { |         } else { | ||||||
|  |  | ||||||
|  | @ -25,7 +25,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel | ||||||
|     Memory::MemorySystem memory; |     Memory::MemorySystem memory; | ||||||
|     Kernel::KernelSystem kernel(memory, timing, [] {}, 0); |     Kernel::KernelSystem kernel(memory, timing, [] {}, 0); | ||||||
|     auto session = std::get<std::shared_ptr<ServerSession>>(kernel.CreateSessionPair()); |     auto session = std::get<std::shared_ptr<ServerSession>>(kernel.CreateSessionPair()); | ||||||
|     HLERequestContext context(kernel, std::move(session)); |     HLERequestContext context(kernel, std::move(session), nullptr); | ||||||
| 
 | 
 | ||||||
|     auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); |     auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); | ||||||
| 
 | 
 | ||||||
|  | @ -237,7 +237,7 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { | ||||||
|     Memory::MemorySystem memory; |     Memory::MemorySystem memory; | ||||||
|     Kernel::KernelSystem kernel(memory, timing, [] {}, 0); |     Kernel::KernelSystem kernel(memory, timing, [] {}, 0); | ||||||
|     auto session = std::get<std::shared_ptr<ServerSession>>(kernel.CreateSessionPair()); |     auto session = std::get<std::shared_ptr<ServerSession>>(kernel.CreateSessionPair()); | ||||||
|     HLERequestContext context(kernel, std::move(session)); |     HLERequestContext context(kernel, std::move(session), nullptr); | ||||||
| 
 | 
 | ||||||
|     auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); |     auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); | ||||||
|     auto* input = context.CommandBuffer(); |     auto* input = context.CommandBuffer(); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue