Refactor out the wakeup_callback function pointer

This commit is contained in:
Hamish Milne
2020-01-06 20:03:40 +00:00
committed by zhupengfei
parent 7019561fd5
commit 116d22d562
24 changed files with 533 additions and 295 deletions

View File

@ -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)