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…
Reference in a new issue