Refactor out the wakeup_callback function pointer
This commit is contained in:
parent
7019561fd5
commit
116d22d562
24 changed files with 533 additions and 295 deletions
|
@ -282,7 +282,7 @@ void SVC::ExitProcess() {
|
|||
// Stop all the process threads that are currently waiting for objects.
|
||||
auto& thread_list = kernel.GetThreadManager().GetThreadList();
|
||||
for (auto& thread : thread_list) {
|
||||
if (thread->owner_process != current_process.get())
|
||||
if (thread->owner_process != current_process)
|
||||
continue;
|
||||
|
||||
if (thread.get() == kernel.GetThreadManager().GetCurrentThread())
|
||||
|
@ -403,6 +403,73 @@ ResultCode SVC::CloseHandle(Handle handle) {
|
|||
return kernel.GetCurrentProcess()->handle_table.Close(handle);
|
||||
}
|
||||
|
||||
static ResultCode ReceiveIPCRequest(Kernel::KernelSystem& kernel, Memory::MemorySystem& memory,
|
||||
std::shared_ptr<ServerSession> server_session,
|
||||
std::shared_ptr<Thread> thread);
|
||||
|
||||
class SVC_SyncCallback : public Kernel::WakeupCallback {
|
||||
public:
|
||||
SVC_SyncCallback(bool do_output_) : do_output(do_output_) {}
|
||||
void WakeUp(ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
|
||||
std::shared_ptr<WaitObject> object) {
|
||||
|
||||
if (reason == ThreadWakeupReason::Timeout) {
|
||||
thread->SetWaitSynchronizationResult(RESULT_TIMEOUT);
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT(reason == ThreadWakeupReason::Signal);
|
||||
|
||||
thread->SetWaitSynchronizationResult(RESULT_SUCCESS);
|
||||
|
||||
// The wait_all case does not update the output index.
|
||||
if (do_output) {
|
||||
thread->SetWaitSynchronizationOutput(thread->GetWaitObjectIndex(object.get()));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool do_output;
|
||||
|
||||
SVC_SyncCallback() = default;
|
||||
template <class Archive>
|
||||
void serialize(Archive& ar, const unsigned int) {
|
||||
ar& do_output;
|
||||
}
|
||||
friend class boost::serialization::access;
|
||||
};
|
||||
|
||||
class SVC_IPCCallback : public Kernel::WakeupCallback {
|
||||
public:
|
||||
SVC_IPCCallback(Core::System& system_) : system(system_) {}
|
||||
|
||||
void WakeUp(ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
|
||||
std::shared_ptr<WaitObject> object) {
|
||||
|
||||
ASSERT(thread->status == ThreadStatus::WaitSynchAny);
|
||||
ASSERT(reason == ThreadWakeupReason::Signal);
|
||||
|
||||
ResultCode result = RESULT_SUCCESS;
|
||||
|
||||
if (object->GetHandleType() == HandleType::ServerSession) {
|
||||
auto server_session = DynamicObjectCast<ServerSession>(object);
|
||||
result = ReceiveIPCRequest(system.Kernel(), system.Memory(), server_session, thread);
|
||||
}
|
||||
|
||||
thread->SetWaitSynchronizationResult(result);
|
||||
thread->SetWaitSynchronizationOutput(thread->GetWaitObjectIndex(object.get()));
|
||||
}
|
||||
|
||||
private:
|
||||
Core::System& system;
|
||||
|
||||
SVC_IPCCallback() : system(Core::Global<Core::System>()) {}
|
||||
|
||||
template <class Archive>
|
||||
void serialize(Archive& ar, const unsigned int) {}
|
||||
friend class boost::serialization::access;
|
||||
};
|
||||
|
||||
/// Wait for a handle to synchronize, timeout after the specified nanoseconds
|
||||
ResultCode SVC::WaitSynchronization1(Handle handle, s64 nano_seconds) {
|
||||
auto object = kernel.GetCurrentProcess()->handle_table.Get<WaitObject>(handle);
|
||||
|
@ -426,21 +493,7 @@ ResultCode SVC::WaitSynchronization1(Handle handle, s64 nano_seconds) {
|
|||
// Create an event to wake the thread up after the specified nanosecond delay has passed
|
||||
thread->WakeAfterDelay(nano_seconds);
|
||||
|
||||
thread->wakeup_callback = [](ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
|
||||
std::shared_ptr<WaitObject> object) {
|
||||
ASSERT(thread->status == ThreadStatus::WaitSynchAny);
|
||||
|
||||
if (reason == ThreadWakeupReason::Timeout) {
|
||||
thread->SetWaitSynchronizationResult(RESULT_TIMEOUT);
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT(reason == ThreadWakeupReason::Signal);
|
||||
thread->SetWaitSynchronizationResult(RESULT_SUCCESS);
|
||||
|
||||
// WaitSynchronization1 doesn't have an output index like WaitSynchronizationN, so we
|
||||
// don't have to do anything else here.
|
||||
};
|
||||
thread->wakeup_callback = std::make_shared<SVC_SyncCallback>(false);
|
||||
|
||||
system.PrepareReschedule();
|
||||
|
||||
|
@ -515,20 +568,7 @@ ResultCode SVC::WaitSynchronizationN(s32* out, VAddr handles_address, s32 handle
|
|||
// Create an event to wake the thread up after the specified nanosecond delay has passed
|
||||
thread->WakeAfterDelay(nano_seconds);
|
||||
|
||||
thread->wakeup_callback = [](ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
|
||||
std::shared_ptr<WaitObject> object) {
|
||||
ASSERT(thread->status == ThreadStatus::WaitSynchAll);
|
||||
|
||||
if (reason == ThreadWakeupReason::Timeout) {
|
||||
thread->SetWaitSynchronizationResult(RESULT_TIMEOUT);
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT(reason == ThreadWakeupReason::Signal);
|
||||
|
||||
thread->SetWaitSynchronizationResult(RESULT_SUCCESS);
|
||||
// The wait_all case does not update the output index.
|
||||
};
|
||||
thread->wakeup_callback = std::make_shared<SVC_SyncCallback>(false);
|
||||
|
||||
system.PrepareReschedule();
|
||||
|
||||
|
@ -575,20 +615,7 @@ ResultCode SVC::WaitSynchronizationN(s32* out, VAddr handles_address, s32 handle
|
|||
// Create an event to wake the thread up after the specified nanosecond delay has passed
|
||||
thread->WakeAfterDelay(nano_seconds);
|
||||
|
||||
thread->wakeup_callback = [](ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
|
||||
std::shared_ptr<WaitObject> object) {
|
||||
ASSERT(thread->status == ThreadStatus::WaitSynchAny);
|
||||
|
||||
if (reason == ThreadWakeupReason::Timeout) {
|
||||
thread->SetWaitSynchronizationResult(RESULT_TIMEOUT);
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT(reason == ThreadWakeupReason::Signal);
|
||||
|
||||
thread->SetWaitSynchronizationResult(RESULT_SUCCESS);
|
||||
thread->SetWaitSynchronizationOutput(thread->GetWaitObjectIndex(object.get()));
|
||||
};
|
||||
thread->wakeup_callback = std::make_shared<SVC_SyncCallback>(true);
|
||||
|
||||
system.PrepareReschedule();
|
||||
|
||||
|
@ -730,22 +757,7 @@ ResultCode SVC::ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_co
|
|||
|
||||
thread->wait_objects = std::move(objects);
|
||||
|
||||
thread->wakeup_callback = [& kernel = this->kernel, &memory = this->memory](
|
||||
ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
|
||||
std::shared_ptr<WaitObject> object) {
|
||||
ASSERT(thread->status == ThreadStatus::WaitSynchAny);
|
||||
ASSERT(reason == ThreadWakeupReason::Signal);
|
||||
|
||||
ResultCode result = RESULT_SUCCESS;
|
||||
|
||||
if (object->GetHandleType() == HandleType::ServerSession) {
|
||||
auto server_session = DynamicObjectCast<ServerSession>(object);
|
||||
result = ReceiveIPCRequest(kernel, memory, server_session, thread);
|
||||
}
|
||||
|
||||
thread->SetWaitSynchronizationResult(result);
|
||||
thread->SetWaitSynchronizationOutput(thread->GetWaitObjectIndex(object.get()));
|
||||
};
|
||||
thread->wakeup_callback = std::make_shared<SVC_IPCCallback>(system);
|
||||
|
||||
system.PrepareReschedule();
|
||||
|
||||
|
@ -911,7 +923,7 @@ ResultCode SVC::CreateThread(Handle* out_handle, u32 entry_point, u32 arg, VAddr
|
|||
|
||||
CASCADE_RESULT(std::shared_ptr<Thread> thread,
|
||||
kernel.CreateThread(name, entry_point, priority, arg, processor_id, stack_top,
|
||||
*current_process));
|
||||
current_process));
|
||||
|
||||
thread->context->SetFpscr(FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO |
|
||||
FPSCR_ROUND_TOZERO); // 0x03C00000
|
||||
|
@ -1020,7 +1032,7 @@ ResultCode SVC::GetProcessIdOfThread(u32* process_id, Handle thread_handle) {
|
|||
if (thread == nullptr)
|
||||
return ERR_INVALID_HANDLE;
|
||||
|
||||
const std::shared_ptr<Process> process = SharedFrom(thread->owner_process);
|
||||
const std::shared_ptr<Process> process = thread->owner_process;
|
||||
|
||||
ASSERT_MSG(process != nullptr, "Invalid parent process for thread={:#010X}", thread_handle);
|
||||
|
||||
|
@ -1611,3 +1623,6 @@ void SVCContext::CallSVC(u32 immediate) {
|
|||
}
|
||||
|
||||
} // namespace Kernel
|
||||
|
||||
SERIALIZE_EXPORT_IMPL(Kernel::SVC_SyncCallback)
|
||||
SERIALIZE_EXPORT_IMPL(Kernel::SVC_IPCCallback)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue