Refactor out the wakeup_callback function pointer
This commit is contained in:
@ -16,6 +16,46 @@
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
class HLERequestContext::ThreadCallback : public Kernel::WakeupCallback {
|
||||
|
||||
public:
|
||||
ThreadCallback(std::shared_ptr<HLERequestContext> context_,
|
||||
std::shared_ptr<HLERequestContext::WakeupCallback> callback_)
|
||||
: context(context_), callback(callback_) {}
|
||||
void WakeUp(ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
|
||||
std::shared_ptr<WaitObject> object) {
|
||||
ASSERT(thread->status == ThreadStatus::WaitHleEvent);
|
||||
if (callback) {
|
||||
callback->WakeUp(thread, *context, reason);
|
||||
}
|
||||
|
||||
auto& process = thread->owner_process;
|
||||
// We must copy the entire command buffer *plus* the entire static buffers area, since
|
||||
// the translation might need to read from it in order to retrieve the StaticBuffer
|
||||
// target addresses.
|
||||
std::array<u32_le, IPC::COMMAND_BUFFER_LENGTH + 2 * IPC::MAX_STATIC_BUFFERS> cmd_buff;
|
||||
Memory::MemorySystem& memory = context->kernel.memory;
|
||||
memory.ReadBlock(*process, thread->GetCommandBufferAddress(), cmd_buff.data(),
|
||||
cmd_buff.size() * sizeof(u32));
|
||||
context->WriteToOutgoingCommandBuffer(cmd_buff.data(), *process);
|
||||
// Copy the translated command buffer back into the thread's command buffer area.
|
||||
memory.WriteBlock(*process, thread->GetCommandBufferAddress(), cmd_buff.data(),
|
||||
cmd_buff.size() * sizeof(u32));
|
||||
}
|
||||
|
||||
private:
|
||||
ThreadCallback() = default;
|
||||
std::shared_ptr<HLERequestContext::WakeupCallback> callback{};
|
||||
std::shared_ptr<HLERequestContext> context{};
|
||||
|
||||
template <class Archive>
|
||||
void serialize(Archive& ar, const unsigned int) {
|
||||
ar& callback;
|
||||
ar& context;
|
||||
}
|
||||
friend class boost::serialization::access;
|
||||
};
|
||||
|
||||
SessionRequestHandler::SessionInfo::SessionInfo(std::shared_ptr<ServerSession> session,
|
||||
std::unique_ptr<SessionDataBase> data)
|
||||
: session(std::move(session)), data(std::move(data)) {}
|
||||
@ -33,34 +73,16 @@ void SessionRequestHandler::ClientDisconnected(std::shared_ptr<ServerSession> se
|
||||
connected_sessions.end());
|
||||
}
|
||||
|
||||
std::shared_ptr<Event> HLERequestContext::SleepClientThread(const std::string& reason,
|
||||
std::chrono::nanoseconds timeout,
|
||||
WakeupCallback&& callback) {
|
||||
std::shared_ptr<Event> HLERequestContext::SleepClientThread(
|
||||
const std::string& reason, std::chrono::nanoseconds timeout,
|
||||
std::shared_ptr<WakeupCallback> callback) {
|
||||
// Put the client thread to sleep until the wait event is signaled or the timeout expires.
|
||||
thread->wakeup_callback = [context = *this,
|
||||
callback](ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
|
||||
std::shared_ptr<WaitObject> object) mutable {
|
||||
ASSERT(thread->status == ThreadStatus::WaitHleEvent);
|
||||
callback(thread, context, reason);
|
||||
|
||||
auto& process = thread->owner_process;
|
||||
// We must copy the entire command buffer *plus* the entire static buffers area, since
|
||||
// the translation might need to read from it in order to retrieve the StaticBuffer
|
||||
// target addresses.
|
||||
std::array<u32_le, IPC::COMMAND_BUFFER_LENGTH + 2 * IPC::MAX_STATIC_BUFFERS> cmd_buff;
|
||||
Memory::MemorySystem& memory = context.kernel.memory;
|
||||
memory.ReadBlock(*process, thread->GetCommandBufferAddress(), cmd_buff.data(),
|
||||
cmd_buff.size() * sizeof(u32));
|
||||
context.WriteToOutgoingCommandBuffer(cmd_buff.data(), *process);
|
||||
// Copy the translated command buffer back into the thread's command buffer area.
|
||||
memory.WriteBlock(*process, thread->GetCommandBufferAddress(), cmd_buff.data(),
|
||||
cmd_buff.size() * sizeof(u32));
|
||||
};
|
||||
thread->wakeup_callback = std::make_shared<ThreadCallback>(shared_from_this(), callback);
|
||||
|
||||
auto event = kernel.CreateEvent(Kernel::ResetType::OneShot, "HLE Pause Event: " + reason);
|
||||
thread->status = ThreadStatus::WaitHleEvent;
|
||||
thread->wait_objects = {event};
|
||||
event->AddWaitingThread(SharedFrom(thread));
|
||||
event->AddWaitingThread(thread);
|
||||
|
||||
if (timeout.count() > 0)
|
||||
thread->WakeAfterDelay(timeout.count());
|
||||
@ -68,8 +90,10 @@ std::shared_ptr<Event> HLERequestContext::SleepClientThread(const std::string& r
|
||||
return event;
|
||||
}
|
||||
|
||||
HLERequestContext::HLERequestContext() : kernel(Core::Global<KernelSystem>()) {}
|
||||
|
||||
HLERequestContext::HLERequestContext(KernelSystem& kernel, std::shared_ptr<ServerSession> session,
|
||||
Thread* thread)
|
||||
std::shared_ptr<Thread> thread)
|
||||
: kernel(kernel), session(std::move(session)), thread(thread) {
|
||||
cmd_buf[0] = 0;
|
||||
}
|
||||
@ -98,8 +122,9 @@ void HLERequestContext::AddStaticBuffer(u8 buffer_id, std::vector<u8> data) {
|
||||
static_buffers[buffer_id] = std::move(data);
|
||||
}
|
||||
|
||||
ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* src_cmdbuf,
|
||||
Process& src_process) {
|
||||
ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(
|
||||
const u32_le* src_cmdbuf, std::shared_ptr<Process> src_process_) {
|
||||
auto& src_process = *src_process_;
|
||||
IPC::Header header{src_cmdbuf[0]};
|
||||
|
||||
std::size_t untranslated_size = 1u + header.normal_params_size;
|
||||
@ -158,7 +183,7 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* sr
|
||||
}
|
||||
case IPC::DescriptorType::MappedBuffer: {
|
||||
u32 next_id = static_cast<u32>(request_mapped_buffers.size());
|
||||
request_mapped_buffers.emplace_back(kernel.memory, src_process, descriptor,
|
||||
request_mapped_buffers.emplace_back(kernel.memory, src_process_, descriptor,
|
||||
src_cmdbuf[i], next_id);
|
||||
cmd_buf[i++] = next_id;
|
||||
break;
|
||||
@ -170,7 +195,7 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* sr
|
||||
|
||||
if (should_record) {
|
||||
std::vector<u32> translated_cmdbuf{cmd_buf.begin(), cmd_buf.begin() + command_size};
|
||||
kernel.GetIPCRecorder().SetRequestInfo(SharedFrom(thread), std::move(untranslated_cmdbuf),
|
||||
kernel.GetIPCRecorder().SetRequestInfo(thread, std::move(untranslated_cmdbuf),
|
||||
std::move(translated_cmdbuf));
|
||||
}
|
||||
|
||||
@ -248,7 +273,7 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf,
|
||||
|
||||
if (should_record) {
|
||||
std::vector<u32> translated_cmdbuf{dst_cmdbuf, dst_cmdbuf + command_size};
|
||||
kernel.GetIPCRecorder().SetReplyInfo(SharedFrom(thread), std::move(untranslated_cmdbuf),
|
||||
kernel.GetIPCRecorder().SetReplyInfo(thread, std::move(untranslated_cmdbuf),
|
||||
std::move(translated_cmdbuf));
|
||||
}
|
||||
|
||||
@ -262,13 +287,15 @@ MappedBuffer& HLERequestContext::GetMappedBuffer(u32 id_from_cmdbuf) {
|
||||
|
||||
void HLERequestContext::ReportUnimplemented() const {
|
||||
if (kernel.GetIPCRecorder().IsEnabled()) {
|
||||
kernel.GetIPCRecorder().SetHLEUnimplemented(SharedFrom(thread));
|
||||
kernel.GetIPCRecorder().SetHLEUnimplemented(thread);
|
||||
}
|
||||
}
|
||||
|
||||
MappedBuffer::MappedBuffer(Memory::MemorySystem& memory, const Process& process, u32 descriptor,
|
||||
VAddr address, u32 id)
|
||||
: memory(&memory), id(id), address(address), process(&process) {
|
||||
MappedBuffer::MappedBuffer() : memory(&Core::Global<Core::System>().Memory()) {}
|
||||
|
||||
MappedBuffer::MappedBuffer(Memory::MemorySystem& memory, std::shared_ptr<Process> process,
|
||||
u32 descriptor, VAddr address, u32 id)
|
||||
: memory(&memory), id(id), address(address), process(process) {
|
||||
IPC::MappedBufferDescInfo desc{descriptor};
|
||||
size = desc.size;
|
||||
perms = desc.perms;
|
||||
@ -287,3 +314,5 @@ void MappedBuffer::Write(const void* src_buffer, std::size_t offset, std::size_t
|
||||
}
|
||||
|
||||
} // namespace Kernel
|
||||
|
||||
SERIALIZE_EXPORT_IMPL(Kernel::HLERequestContext::ThreadCallback)
|
||||
|
Reference in New Issue
Block a user