HLE/IPC: HLEContext can memorize the client thread and use it for SleepClientThread

This reduces the boilerplate that services have to write out the current thread explicitly. Using current thread instead of client thread is also semantically incorrect, and will be a problem when we implement multicore (at which time there will be multiple current threads)
merge-requests/60/head
Weiyi Wang 2019-04-02 12:30:03 +07:00 committed by fearlessTobi
parent fb85d5670d
commit 8d6342384b
4 changed files with 10 additions and 9 deletions

@ -43,7 +43,7 @@ void SessionRequestHandler::ClientDisconnected(const SharedPtr<ServerSession>& s
} }
SharedPtr<WritableEvent> HLERequestContext::SleepClientThread( SharedPtr<WritableEvent> HLERequestContext::SleepClientThread(
SharedPtr<Thread> thread, const std::string& reason, u64 timeout, WakeupCallback&& callback, const std::string& reason, u64 timeout, WakeupCallback&& callback,
SharedPtr<WritableEvent> writable_event) { SharedPtr<WritableEvent> writable_event) {
// 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.
thread->SetWakeupCallback([context = *this, callback]( thread->SetWakeupCallback([context = *this, callback](
@ -76,8 +76,9 @@ SharedPtr<WritableEvent> HLERequestContext::SleepClientThread(
return writable_event; return writable_event;
} }
HLERequestContext::HLERequestContext(SharedPtr<Kernel::ServerSession> server_session) HLERequestContext::HLERequestContext(SharedPtr<Kernel::ServerSession> server_session,
: server_session(std::move(server_session)) { SharedPtr<Thread> thread)
: server_session(std::move(server_session)), thread(thread) {
cmd_buf[0] = 0; cmd_buf[0] = 0;
} }

@ -97,7 +97,7 @@ protected:
*/ */
class HLERequestContext { class HLERequestContext {
public: public:
explicit HLERequestContext(SharedPtr<ServerSession> session); explicit HLERequestContext(SharedPtr<ServerSession> session, SharedPtr<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.
@ -119,7 +119,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.
@ -130,8 +129,8 @@ public:
* created. * created.
* @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.
*/ */
SharedPtr<WritableEvent> SleepClientThread(SharedPtr<Thread> thread, const std::string& reason, SharedPtr<WritableEvent> SleepClientThread(const std::string& reason, u64 timeout,
u64 timeout, WakeupCallback&& callback, WakeupCallback&& callback,
SharedPtr<WritableEvent> writable_event = nullptr); SharedPtr<WritableEvent> writable_event = nullptr);
/// Populates this context with data from the requesting process/thread. /// Populates this context with data from the requesting process/thread.
@ -268,6 +267,7 @@ private:
std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf; std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf;
SharedPtr<Kernel::ServerSession> server_session; SharedPtr<Kernel::ServerSession> server_session;
SharedPtr<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<SharedPtr<Object>, 8> move_objects; boost::container::small_vector<SharedPtr<Object>, 8> move_objects;
boost::container::small_vector<SharedPtr<Object>, 8> copy_objects; boost::container::small_vector<SharedPtr<Object>, 8> copy_objects;

@ -130,7 +130,7 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr<Thread> thread) {
// The ServerSession received a sync request, this means that there's new data available // The ServerSession received a sync request, this means that there's new data available
// from its ClientSession, so wake up any threads that may be waiting on a svcReplyAndReceive or // from its ClientSession, so wake up any threads that may be waiting on a svcReplyAndReceive or
// similar. // similar.
Kernel::HLERequestContext context(this); Kernel::HLERequestContext context(this, thread);
u32* cmd_buf = (u32*)Memory::GetPointer(thread->GetTLSAddress()); u32* cmd_buf = (u32*)Memory::GetPointer(thread->GetTLSAddress());
context.PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf); context.PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf);

@ -556,7 +556,7 @@ private:
} else { } else {
// Wait the current thread until a buffer becomes available // Wait the current thread until a buffer becomes available
ctx.SleepClientThread( ctx.SleepClientThread(
Kernel::GetCurrentThread(), "IHOSBinderDriver::DequeueBuffer", -1, "IHOSBinderDriver::DequeueBuffer", -1,
[=](Kernel::SharedPtr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx, [=](Kernel::SharedPtr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx,
Kernel::ThreadWakeupReason reason) { Kernel::ThreadWakeupReason reason) {
// Repeat TransactParcel DequeueBuffer when a buffer is available // Repeat TransactParcel DequeueBuffer when a buffer is available