1
0
Fork 1
forked from suyu/suyu

Kernel: Change WaitObject to Synchronization object. In order to better reflect RE.

This commit is contained in:
Fernando Sahmkow 2020-02-11 10:46:25 -04:00
parent 84ea9c2b42
commit c5aefe42aa
22 changed files with 110 additions and 98 deletions

View file

@ -181,14 +181,14 @@ add_library(core STATIC
hle/kernel/svc.cpp hle/kernel/svc.cpp
hle/kernel/svc.h hle/kernel/svc.h
hle/kernel/svc_wrap.h hle/kernel/svc_wrap.h
hle/kernel/synchronization_object.cpp
hle/kernel/synchronization_object.h
hle/kernel/thread.cpp hle/kernel/thread.cpp
hle/kernel/thread.h hle/kernel/thread.h
hle/kernel/transfer_memory.cpp hle/kernel/transfer_memory.cpp
hle/kernel/transfer_memory.h hle/kernel/transfer_memory.h
hle/kernel/vm_manager.cpp hle/kernel/vm_manager.cpp
hle/kernel/vm_manager.h hle/kernel/vm_manager.h
hle/kernel/wait_object.cpp
hle/kernel/wait_object.h
hle/kernel/writable_event.cpp hle/kernel/writable_event.cpp
hle/kernel/writable_event.h hle/kernel/writable_event.h
hle/lock.cpp hle/lock.cpp

View file

@ -12,7 +12,7 @@
namespace Kernel { namespace Kernel {
ClientSession::ClientSession(KernelCore& kernel) : WaitObject{kernel} {} ClientSession::ClientSession(KernelCore& kernel) : SynchronizationObject{kernel} {}
ClientSession::~ClientSession() { ClientSession::~ClientSession() {
// This destructor will be called automatically when the last ClientSession handle is closed by // This destructor will be called automatically when the last ClientSession handle is closed by

View file

@ -7,7 +7,7 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include "core/hle/kernel/wait_object.h" #include "core/hle/kernel/synchronization_object.h"
#include "core/hle/result.h" #include "core/hle/result.h"
union ResultCode; union ResultCode;
@ -22,7 +22,7 @@ class KernelCore;
class Session; class Session;
class Thread; class Thread;
class ClientSession final : public WaitObject { class ClientSession final : public SynchronizationObject {
public: public:
explicit ClientSession(KernelCore& kernel); explicit ClientSession(KernelCore& kernel);
~ClientSession() override; ~ClientSession() override;

View file

@ -47,15 +47,15 @@ std::shared_ptr<WritableEvent> HLERequestContext::SleepClientThread(
const std::string& reason, u64 timeout, WakeupCallback&& callback, const std::string& reason, u64 timeout, WakeupCallback&& callback,
std::shared_ptr<WritableEvent> writable_event) { std::shared_ptr<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](ThreadWakeupReason reason, thread->SetWakeupCallback(
std::shared_ptr<Thread> thread, [context = *this, callback](ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
std::shared_ptr<WaitObject> object, std::shared_ptr<SynchronizationObject> object,
std::size_t index) mutable -> bool { std::size_t index) mutable -> bool {
ASSERT(thread->GetStatus() == ThreadStatus::WaitHLEEvent); ASSERT(thread->GetStatus() == ThreadStatus::WaitHLEEvent);
callback(thread, context, reason); callback(thread, context, reason);
context.WriteToOutgoingCommandBuffer(*thread); context.WriteToOutgoingCommandBuffer(*thread);
return true; return true;
}); });
auto& kernel = Core::System::GetInstance().Kernel(); auto& kernel = Core::System::GetInstance().Kernel();
if (!writable_event) { if (!writable_event) {
@ -67,7 +67,7 @@ std::shared_ptr<WritableEvent> HLERequestContext::SleepClientThread(
const auto readable_event{writable_event->GetReadableEvent()}; const auto readable_event{writable_event->GetReadableEvent()};
writable_event->Clear(); writable_event->Clear();
thread->SetStatus(ThreadStatus::WaitHLEEvent); thread->SetStatus(ThreadStatus::WaitHLEEvent);
thread->SetWaitObjects({readable_event}); thread->SetSynchronizationObjects({readable_event});
readable_event->AddWaitingThread(thread); readable_event->AddWaitingThread(thread);
if (timeout > 0) { if (timeout > 0) {

View file

@ -54,10 +54,10 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] s64 cycles_
if (thread->GetStatus() == ThreadStatus::WaitSynch || if (thread->GetStatus() == ThreadStatus::WaitSynch ||
thread->GetStatus() == ThreadStatus::WaitHLEEvent) { thread->GetStatus() == ThreadStatus::WaitHLEEvent) {
// Remove the thread from each of its waiting objects' waitlists // Remove the thread from each of its waiting objects' waitlists
for (const auto& object : thread->GetWaitObjects()) { for (const auto& object : thread->GetSynchronizationObjects()) {
object->RemoveWaitingThread(thread); object->RemoveWaitingThread(thread);
} }
thread->ClearWaitObjects(); thread->ClearSynchronizationObjects();
// Invoke the wakeup callback before clearing the wait objects // Invoke the wakeup callback before clearing the wait objects
if (thread->HasWakeupCallback()) { if (thread->HasWakeupCallback()) {

View file

@ -337,7 +337,7 @@ void Process::LoadModule(CodeSet module_, VAddr base_addr) {
} }
Process::Process(Core::System& system) Process::Process(Core::System& system)
: WaitObject{system.Kernel()}, vm_manager{system}, : SynchronizationObject{system.Kernel()}, vm_manager{system},
address_arbiter{system}, mutex{system}, system{system} {} address_arbiter{system}, mutex{system}, system{system} {}
Process::~Process() = default; Process::~Process() = default;

View file

@ -15,8 +15,8 @@
#include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/mutex.h" #include "core/hle/kernel/mutex.h"
#include "core/hle/kernel/process_capability.h" #include "core/hle/kernel/process_capability.h"
#include "core/hle/kernel/synchronization_object.h"
#include "core/hle/kernel/vm_manager.h" #include "core/hle/kernel/vm_manager.h"
#include "core/hle/kernel/wait_object.h"
#include "core/hle/result.h" #include "core/hle/result.h"
namespace Core { namespace Core {
@ -60,7 +60,7 @@ enum class ProcessStatus {
DebugBreak, DebugBreak,
}; };
class Process final : public WaitObject { class Process final : public SynchronizationObject {
public: public:
explicit Process(Core::System& system); explicit Process(Core::System& system);
~Process() override; ~Process() override;

View file

@ -11,7 +11,7 @@
namespace Kernel { namespace Kernel {
ReadableEvent::ReadableEvent(KernelCore& kernel) : WaitObject{kernel} {} ReadableEvent::ReadableEvent(KernelCore& kernel) : SynchronizationObject{kernel} {}
ReadableEvent::~ReadableEvent() = default; ReadableEvent::~ReadableEvent() = default;
bool ReadableEvent::ShouldWait(const Thread* thread) const { bool ReadableEvent::ShouldWait(const Thread* thread) const {

View file

@ -5,7 +5,7 @@
#pragma once #pragma once
#include "core/hle/kernel/object.h" #include "core/hle/kernel/object.h"
#include "core/hle/kernel/wait_object.h" #include "core/hle/kernel/synchronization_object.h"
union ResultCode; union ResultCode;
@ -14,7 +14,7 @@ namespace Kernel {
class KernelCore; class KernelCore;
class WritableEvent; class WritableEvent;
class ReadableEvent final : public WaitObject { class ReadableEvent final : public SynchronizationObject {
friend class WritableEvent; friend class WritableEvent;
public: public:

View file

@ -13,7 +13,7 @@
namespace Kernel { namespace Kernel {
ServerPort::ServerPort(KernelCore& kernel) : WaitObject{kernel} {} ServerPort::ServerPort(KernelCore& kernel) : SynchronizationObject{kernel} {}
ServerPort::~ServerPort() = default; ServerPort::~ServerPort() = default;
ResultVal<std::shared_ptr<ServerSession>> ServerPort::Accept() { ResultVal<std::shared_ptr<ServerSession>> ServerPort::Accept() {

View file

@ -10,7 +10,7 @@
#include <vector> #include <vector>
#include "common/common_types.h" #include "common/common_types.h"
#include "core/hle/kernel/object.h" #include "core/hle/kernel/object.h"
#include "core/hle/kernel/wait_object.h" #include "core/hle/kernel/synchronization_object.h"
#include "core/hle/result.h" #include "core/hle/result.h"
namespace Kernel { namespace Kernel {
@ -20,7 +20,7 @@ class KernelCore;
class ServerSession; class ServerSession;
class SessionRequestHandler; class SessionRequestHandler;
class ServerPort final : public WaitObject { class ServerPort final : public SynchronizationObject {
public: public:
explicit ServerPort(KernelCore& kernel); explicit ServerPort(KernelCore& kernel);
~ServerPort() override; ~ServerPort() override;

View file

@ -24,7 +24,7 @@
namespace Kernel { namespace Kernel {
ServerSession::ServerSession(KernelCore& kernel) : WaitObject{kernel} {} ServerSession::ServerSession(KernelCore& kernel) : SynchronizationObject{kernel} {}
ServerSession::~ServerSession() = default; ServerSession::~ServerSession() = default;
ResultVal<std::shared_ptr<ServerSession>> ServerSession::Create(KernelCore& kernel, ResultVal<std::shared_ptr<ServerSession>> ServerSession::Create(KernelCore& kernel,

View file

@ -10,7 +10,7 @@
#include <vector> #include <vector>
#include "common/threadsafe_queue.h" #include "common/threadsafe_queue.h"
#include "core/hle/kernel/wait_object.h" #include "core/hle/kernel/synchronization_object.h"
#include "core/hle/result.h" #include "core/hle/result.h"
namespace Memory { namespace Memory {
@ -41,7 +41,7 @@ class Thread;
* After the server replies to the request, the response is marshalled back to the caller's * After the server replies to the request, the response is marshalled back to the caller's
* TLS buffer and control is transferred back to it. * TLS buffer and control is transferred back to it.
*/ */
class ServerSession final : public WaitObject { class ServerSession final : public SynchronizationObject {
public: public:
explicit ServerSession(KernelCore& kernel); explicit ServerSession(KernelCore& kernel);
~ServerSession() override; ~ServerSession() override;

View file

@ -9,7 +9,7 @@
namespace Kernel { namespace Kernel {
Session::Session(KernelCore& kernel) : WaitObject{kernel} {} Session::Session(KernelCore& kernel) : SynchronizationObject{kernel} {}
Session::~Session() = default; Session::~Session() = default;
Session::SessionPair Session::Create(KernelCore& kernel, std::string name) { Session::SessionPair Session::Create(KernelCore& kernel, std::string name) {

View file

@ -8,7 +8,7 @@
#include <string> #include <string>
#include <utility> #include <utility>
#include "core/hle/kernel/wait_object.h" #include "core/hle/kernel/synchronization_object.h"
namespace Kernel { namespace Kernel {
@ -19,7 +19,7 @@ class ServerSession;
* Parent structure to link the client and server endpoints of a session with their associated * Parent structure to link the client and server endpoints of a session with their associated
* client port. * client port.
*/ */
class Session final : public WaitObject { class Session final : public SynchronizationObject {
public: public:
explicit Session(KernelCore& kernel); explicit Session(KernelCore& kernel);
~Session() override; ~Session() override;

View file

@ -435,7 +435,8 @@ static ResultCode GetProcessId(Core::System& system, u64* process_id, Handle han
/// Default thread wakeup callback for WaitSynchronization /// Default thread wakeup callback for WaitSynchronization
static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
std::shared_ptr<WaitObject> object, std::size_t index) { std::shared_ptr<SynchronizationObject> object,
std::size_t index) {
ASSERT(thread->GetStatus() == ThreadStatus::WaitSynch); ASSERT(thread->GetStatus() == ThreadStatus::WaitSynch);
if (reason == ThreadWakeupReason::Timeout) { if (reason == ThreadWakeupReason::Timeout) {
@ -473,13 +474,13 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr
auto* const thread = system.CurrentScheduler().GetCurrentThread(); auto* const thread = system.CurrentScheduler().GetCurrentThread();
using ObjectPtr = Thread::ThreadWaitObjects::value_type; using ObjectPtr = Thread::ThreadSynchronizationObjects::value_type;
Thread::ThreadWaitObjects objects(handle_count); Thread::ThreadSynchronizationObjects objects(handle_count);
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
for (u64 i = 0; i < handle_count; ++i) { for (u64 i = 0; i < handle_count; ++i) {
const Handle handle = memory.Read32(handles_address + i * sizeof(Handle)); const Handle handle = memory.Read32(handles_address + i * sizeof(Handle));
const auto object = handle_table.Get<WaitObject>(handle); const auto object = handle_table.Get<SynchronizationObject>(handle);
if (object == nullptr) { if (object == nullptr) {
LOG_ERROR(Kernel_SVC, "Object is a nullptr"); LOG_ERROR(Kernel_SVC, "Object is a nullptr");
@ -496,7 +497,7 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr
if (itr != objects.end()) { if (itr != objects.end()) {
// We found a ready object, acquire it and set the result value // We found a ready object, acquire it and set the result value
WaitObject* object = itr->get(); SynchronizationObject* object = itr->get();
object->Acquire(thread); object->Acquire(thread);
*index = static_cast<s32>(std::distance(objects.begin(), itr)); *index = static_cast<s32>(std::distance(objects.begin(), itr));
return RESULT_SUCCESS; return RESULT_SUCCESS;
@ -519,7 +520,7 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr
object->AddWaitingThread(SharedFrom(thread)); object->AddWaitingThread(SharedFrom(thread));
} }
thread->SetWaitObjects(std::move(objects)); thread->SetSynchronizationObjects(std::move(objects));
thread->SetStatus(ThreadStatus::WaitSynch); thread->SetStatus(ThreadStatus::WaitSynch);
// Create an event to wake the thread up after the specified nanosecond delay has passed // Create an event to wake the thread up after the specified nanosecond delay has passed

View file

@ -10,20 +10,21 @@
#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/object.h" #include "core/hle/kernel/object.h"
#include "core/hle/kernel/process.h" #include "core/hle/kernel/process.h"
#include "core/hle/kernel/synchronization_object.h"
#include "core/hle/kernel/thread.h" #include "core/hle/kernel/thread.h"
namespace Kernel { namespace Kernel {
WaitObject::WaitObject(KernelCore& kernel) : Object{kernel} {} SynchronizationObject::SynchronizationObject(KernelCore& kernel) : Object{kernel} {}
WaitObject::~WaitObject() = default; SynchronizationObject::~SynchronizationObject() = default;
void WaitObject::AddWaitingThread(std::shared_ptr<Thread> thread) { void SynchronizationObject::AddWaitingThread(std::shared_ptr<Thread> thread) {
auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread); auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread);
if (itr == waiting_threads.end()) if (itr == waiting_threads.end())
waiting_threads.push_back(std::move(thread)); waiting_threads.push_back(std::move(thread));
} }
void WaitObject::RemoveWaitingThread(std::shared_ptr<Thread> thread) { void SynchronizationObject::RemoveWaitingThread(std::shared_ptr<Thread> thread) {
auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread); auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread);
// If a thread passed multiple handles to the same object, // If a thread passed multiple handles to the same object,
// the kernel might attempt to remove the thread from the object's // the kernel might attempt to remove the thread from the object's
@ -32,7 +33,7 @@ void WaitObject::RemoveWaitingThread(std::shared_ptr<Thread> thread) {
waiting_threads.erase(itr); waiting_threads.erase(itr);
} }
std::shared_ptr<Thread> WaitObject::GetHighestPriorityReadyThread() const { std::shared_ptr<Thread> SynchronizationObject::GetHighestPriorityReadyThread() const {
Thread* candidate = nullptr; Thread* candidate = nullptr;
u32 candidate_priority = THREADPRIO_LOWEST + 1; u32 candidate_priority = THREADPRIO_LOWEST + 1;
@ -57,7 +58,7 @@ std::shared_ptr<Thread> WaitObject::GetHighestPriorityReadyThread() const {
return SharedFrom(candidate); return SharedFrom(candidate);
} }
void WaitObject::WakeupWaitingThread(std::shared_ptr<Thread> thread) { void SynchronizationObject::WakeupWaitingThread(std::shared_ptr<Thread> thread) {
ASSERT(!ShouldWait(thread.get())); ASSERT(!ShouldWait(thread.get()));
if (!thread) { if (!thread) {
@ -65,7 +66,7 @@ void WaitObject::WakeupWaitingThread(std::shared_ptr<Thread> thread) {
} }
if (thread->IsSleepingOnWait()) { if (thread->IsSleepingOnWait()) {
for (const auto& object : thread->GetWaitObjects()) { for (const auto& object : thread->GetSynchronizationObjects()) {
ASSERT(!object->ShouldWait(thread.get())); ASSERT(!object->ShouldWait(thread.get()));
object->Acquire(thread.get()); object->Acquire(thread.get());
} }
@ -73,9 +74,9 @@ void WaitObject::WakeupWaitingThread(std::shared_ptr<Thread> thread) {
Acquire(thread.get()); Acquire(thread.get());
} }
const std::size_t index = thread->GetWaitObjectIndex(SharedFrom(this)); const std::size_t index = thread->GetSynchronizationObjectIndex(SharedFrom(this));
thread->ClearWaitObjects(); thread->ClearSynchronizationObjects();
thread->CancelWakeupTimer(); thread->CancelWakeupTimer();
@ -90,13 +91,13 @@ void WaitObject::WakeupWaitingThread(std::shared_ptr<Thread> thread) {
} }
} }
void WaitObject::WakeupAllWaitingThreads() { void SynchronizationObject::WakeupAllWaitingThreads() {
while (auto thread = GetHighestPriorityReadyThread()) { while (auto thread = GetHighestPriorityReadyThread()) {
WakeupWaitingThread(thread); WakeupWaitingThread(thread);
} }
} }
const std::vector<std::shared_ptr<Thread>>& WaitObject::GetWaitingThreads() const { const std::vector<std::shared_ptr<Thread>>& SynchronizationObject::GetWaitingThreads() const {
return waiting_threads; return waiting_threads;
} }

View file

@ -15,10 +15,10 @@ class KernelCore;
class Thread; class Thread;
/// Class that represents a Kernel object that a thread can be waiting on /// Class that represents a Kernel object that a thread can be waiting on
class WaitObject : public Object { class SynchronizationObject : public Object {
public: public:
explicit WaitObject(KernelCore& kernel); explicit SynchronizationObject(KernelCore& kernel);
~WaitObject() override; ~SynchronizationObject() override;
/** /**
* Check if the specified thread should wait until the object is available * Check if the specified thread should wait until the object is available
@ -65,11 +65,12 @@ private:
std::vector<std::shared_ptr<Thread>> waiting_threads; std::vector<std::shared_ptr<Thread>> waiting_threads;
}; };
// Specialization of DynamicObjectCast for WaitObjects // Specialization of DynamicObjectCast for SynchronizationObjects
template <> template <>
inline std::shared_ptr<WaitObject> DynamicObjectCast<WaitObject>(std::shared_ptr<Object> object) { inline std::shared_ptr<SynchronizationObject> DynamicObjectCast<SynchronizationObject>(
std::shared_ptr<Object> object) {
if (object != nullptr && object->IsWaitable()) { if (object != nullptr && object->IsWaitable()) {
return std::static_pointer_cast<WaitObject>(object); return std::static_pointer_cast<SynchronizationObject>(object);
} }
return nullptr; return nullptr;
} }

View file

@ -35,7 +35,7 @@ void Thread::Acquire(Thread* thread) {
ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); ASSERT_MSG(!ShouldWait(thread), "object unavailable!");
} }
Thread::Thread(KernelCore& kernel) : WaitObject{kernel} {} Thread::Thread(KernelCore& kernel) : SynchronizationObject{kernel} {}
Thread::~Thread() = default; Thread::~Thread() = default;
void Thread::Stop() { void Thread::Stop() {
@ -215,7 +215,7 @@ void Thread::SetWaitSynchronizationOutput(s32 output) {
context.cpu_registers[1] = output; context.cpu_registers[1] = output;
} }
s32 Thread::GetWaitObjectIndex(std::shared_ptr<WaitObject> object) const { s32 Thread::GetSynchronizationObjectIndex(std::shared_ptr<SynchronizationObject> object) const {
ASSERT_MSG(!wait_objects.empty(), "Thread is not waiting for anything"); ASSERT_MSG(!wait_objects.empty(), "Thread is not waiting for anything");
const auto match = std::find(wait_objects.rbegin(), wait_objects.rend(), object); const auto match = std::find(wait_objects.rbegin(), wait_objects.rend(), object);
return static_cast<s32>(std::distance(match, wait_objects.rend()) - 1); return static_cast<s32>(std::distance(match, wait_objects.rend()) - 1);
@ -336,14 +336,16 @@ void Thread::ChangeCore(u32 core, u64 mask) {
SetCoreAndAffinityMask(core, mask); SetCoreAndAffinityMask(core, mask);
} }
bool Thread::AllWaitObjectsReady() const { bool Thread::AllSynchronizationObjectsReady() const {
return std::none_of( return std::none_of(wait_objects.begin(), wait_objects.end(),
wait_objects.begin(), wait_objects.end(), [this](const std::shared_ptr<SynchronizationObject>& object) {
[this](const std::shared_ptr<WaitObject>& object) { return object->ShouldWait(this); }); return object->ShouldWait(this);
});
} }
bool Thread::InvokeWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, bool Thread::InvokeWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
std::shared_ptr<WaitObject> object, std::size_t index) { std::shared_ptr<SynchronizationObject> object,
std::size_t index) {
ASSERT(wakeup_callback); ASSERT(wakeup_callback);
return wakeup_callback(reason, std::move(thread), std::move(object), index); return wakeup_callback(reason, std::move(thread), std::move(object), index);
} }

View file

@ -11,7 +11,7 @@
#include "common/common_types.h" #include "common/common_types.h"
#include "core/arm/arm_interface.h" #include "core/arm/arm_interface.h"
#include "core/hle/kernel/object.h" #include "core/hle/kernel/object.h"
#include "core/hle/kernel/wait_object.h" #include "core/hle/kernel/synchronization_object.h"
#include "core/hle/result.h" #include "core/hle/result.h"
namespace Kernel { namespace Kernel {
@ -95,7 +95,7 @@ enum class ThreadSchedMasks : u32 {
ForcePauseMask = 0x0070, ForcePauseMask = 0x0070,
}; };
class Thread final : public WaitObject { class Thread final : public SynchronizationObject {
public: public:
explicit Thread(KernelCore& kernel); explicit Thread(KernelCore& kernel);
~Thread() override; ~Thread() override;
@ -104,11 +104,11 @@ public:
using ThreadContext = Core::ARM_Interface::ThreadContext; using ThreadContext = Core::ARM_Interface::ThreadContext;
using ThreadWaitObjects = std::vector<std::shared_ptr<WaitObject>>; using ThreadSynchronizationObjects = std::vector<std::shared_ptr<SynchronizationObject>>;
using WakeupCallback = using WakeupCallback =
std::function<bool(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, std::function<bool(ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
std::shared_ptr<WaitObject> object, std::size_t index)>; std::shared_ptr<SynchronizationObject> object, std::size_t index)>;
/** /**
* Creates and returns a new thread. The new thread is immediately scheduled * Creates and returns a new thread. The new thread is immediately scheduled
@ -233,7 +233,7 @@ public:
* *
* @param object Object to query the index of. * @param object Object to query the index of.
*/ */
s32 GetWaitObjectIndex(std::shared_ptr<WaitObject> object) const; s32 GetSynchronizationObjectIndex(std::shared_ptr<SynchronizationObject> object) const;
/** /**
* Stops a thread, invalidating it from further use * Stops a thread, invalidating it from further use
@ -314,15 +314,15 @@ public:
return owner_process; return owner_process;
} }
const ThreadWaitObjects& GetWaitObjects() const { const ThreadSynchronizationObjects& GetSynchronizationObjects() const {
return wait_objects; return wait_objects;
} }
void SetWaitObjects(ThreadWaitObjects objects) { void SetSynchronizationObjects(ThreadSynchronizationObjects objects) {
wait_objects = std::move(objects); wait_objects = std::move(objects);
} }
void ClearWaitObjects() { void ClearSynchronizationObjects() {
for (const auto& waiting_object : wait_objects) { for (const auto& waiting_object : wait_objects) {
waiting_object->RemoveWaitingThread(SharedFrom(this)); waiting_object->RemoveWaitingThread(SharedFrom(this));
} }
@ -330,7 +330,7 @@ public:
} }
/// Determines whether all the objects this thread is waiting on are ready. /// Determines whether all the objects this thread is waiting on are ready.
bool AllWaitObjectsReady() const; bool AllSynchronizationObjectsReady() const;
const MutexWaitingThreads& GetMutexWaitingThreads() const { const MutexWaitingThreads& GetMutexWaitingThreads() const {
return wait_mutex_threads; return wait_mutex_threads;
@ -395,7 +395,7 @@ public:
* will cause an assertion to trigger. * will cause an assertion to trigger.
*/ */
bool InvokeWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, bool InvokeWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
std::shared_ptr<WaitObject> object, std::size_t index); std::shared_ptr<SynchronizationObject> object, std::size_t index);
u32 GetIdealCore() const { u32 GetIdealCore() const {
return ideal_core; return ideal_core;
@ -494,7 +494,7 @@ private:
/// Objects that the thread is waiting on, in the same order as they were /// Objects that the thread is waiting on, in the same order as they were
/// passed to WaitSynchronization. /// passed to WaitSynchronization.
ThreadWaitObjects wait_objects; ThreadSynchronizationObjects wait_objects;
/// List of threads that are waiting for a mutex that is held by this thread. /// List of threads that are waiting for a mutex that is held by this thread.
MutexWaitingThreads wait_mutex_threads; MutexWaitingThreads wait_mutex_threads;

View file

@ -12,8 +12,8 @@
#include "core/hle/kernel/process.h" #include "core/hle/kernel/process.h"
#include "core/hle/kernel/readable_event.h" #include "core/hle/kernel/readable_event.h"
#include "core/hle/kernel/scheduler.h" #include "core/hle/kernel/scheduler.h"
#include "core/hle/kernel/synchronization_object.h"
#include "core/hle/kernel/thread.h" #include "core/hle/kernel/thread.h"
#include "core/hle/kernel/wait_object.h"
#include "core/memory.h" #include "core/memory.h"
WaitTreeItem::WaitTreeItem() = default; WaitTreeItem::WaitTreeItem() = default;
@ -133,8 +133,9 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeCallstack::GetChildren() cons
return list; return list;
} }
WaitTreeWaitObject::WaitTreeWaitObject(const Kernel::WaitObject& o) : object(o) {} WaitTreeSynchronizationObject::WaitTreeSynchronizationObject(const Kernel::SynchronizationObject& o)
WaitTreeWaitObject::~WaitTreeWaitObject() = default; : object(o) {}
WaitTreeSynchronizationObject::~WaitTreeSynchronizationObject() = default;
WaitTreeExpandableItem::WaitTreeExpandableItem() = default; WaitTreeExpandableItem::WaitTreeExpandableItem() = default;
WaitTreeExpandableItem::~WaitTreeExpandableItem() = default; WaitTreeExpandableItem::~WaitTreeExpandableItem() = default;
@ -143,25 +144,26 @@ bool WaitTreeExpandableItem::IsExpandable() const {
return true; return true;
} }
QString WaitTreeWaitObject::GetText() const { QString WaitTreeSynchronizationObject::GetText() const {
return tr("[%1]%2 %3") return tr("[%1]%2 %3")
.arg(object.GetObjectId()) .arg(object.GetObjectId())
.arg(QString::fromStdString(object.GetTypeName()), .arg(QString::fromStdString(object.GetTypeName()),
QString::fromStdString(object.GetName())); QString::fromStdString(object.GetName()));
} }
std::unique_ptr<WaitTreeWaitObject> WaitTreeWaitObject::make(const Kernel::WaitObject& object) { std::unique_ptr<WaitTreeSynchronizationObject> WaitTreeSynchronizationObject::make(
const Kernel::SynchronizationObject& object) {
switch (object.GetHandleType()) { switch (object.GetHandleType()) {
case Kernel::HandleType::ReadableEvent: case Kernel::HandleType::ReadableEvent:
return std::make_unique<WaitTreeEvent>(static_cast<const Kernel::ReadableEvent&>(object)); return std::make_unique<WaitTreeEvent>(static_cast<const Kernel::ReadableEvent&>(object));
case Kernel::HandleType::Thread: case Kernel::HandleType::Thread:
return std::make_unique<WaitTreeThread>(static_cast<const Kernel::Thread&>(object)); return std::make_unique<WaitTreeThread>(static_cast<const Kernel::Thread&>(object));
default: default:
return std::make_unique<WaitTreeWaitObject>(object); return std::make_unique<WaitTreeSynchronizationObject>(object);
} }
} }
std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeWaitObject::GetChildren() const { std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeSynchronizationObject::GetChildren() const {
std::vector<std::unique_ptr<WaitTreeItem>> list; std::vector<std::unique_ptr<WaitTreeItem>> list;
const auto& threads = object.GetWaitingThreads(); const auto& threads = object.GetWaitingThreads();
@ -173,8 +175,8 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeWaitObject::GetChildren() con
return list; return list;
} }
WaitTreeObjectList::WaitTreeObjectList(const std::vector<std::shared_ptr<Kernel::WaitObject>>& list, WaitTreeObjectList::WaitTreeObjectList(
bool w_all) const std::vector<std::shared_ptr<Kernel::SynchronizationObject>>& list, bool w_all)
: object_list(list), wait_all(w_all) {} : object_list(list), wait_all(w_all) {}
WaitTreeObjectList::~WaitTreeObjectList() = default; WaitTreeObjectList::~WaitTreeObjectList() = default;
@ -188,11 +190,12 @@ QString WaitTreeObjectList::GetText() const {
std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeObjectList::GetChildren() const { std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeObjectList::GetChildren() const {
std::vector<std::unique_ptr<WaitTreeItem>> list(object_list.size()); std::vector<std::unique_ptr<WaitTreeItem>> list(object_list.size());
std::transform(object_list.begin(), object_list.end(), list.begin(), std::transform(object_list.begin(), object_list.end(), list.begin(),
[](const auto& t) { return WaitTreeWaitObject::make(*t); }); [](const auto& t) { return WaitTreeSynchronizationObject::make(*t); });
return list; return list;
} }
WaitTreeThread::WaitTreeThread(const Kernel::Thread& thread) : WaitTreeWaitObject(thread) {} WaitTreeThread::WaitTreeThread(const Kernel::Thread& thread)
: WaitTreeSynchronizationObject(thread) {}
WaitTreeThread::~WaitTreeThread() = default; WaitTreeThread::~WaitTreeThread() = default;
QString WaitTreeThread::GetText() const { QString WaitTreeThread::GetText() const {
@ -241,7 +244,8 @@ QString WaitTreeThread::GetText() const {
const QString pc_info = tr(" PC = 0x%1 LR = 0x%2") const QString pc_info = tr(" PC = 0x%1 LR = 0x%2")
.arg(context.pc, 8, 16, QLatin1Char{'0'}) .arg(context.pc, 8, 16, QLatin1Char{'0'})
.arg(context.cpu_registers[30], 8, 16, QLatin1Char{'0'}); .arg(context.cpu_registers[30], 8, 16, QLatin1Char{'0'});
return QStringLiteral("%1%2 (%3) ").arg(WaitTreeWaitObject::GetText(), pc_info, status); return QStringLiteral("%1%2 (%3) ")
.arg(WaitTreeSynchronizationObject::GetText(), pc_info, status);
} }
QColor WaitTreeThread::GetColor() const { QColor WaitTreeThread::GetColor() const {
@ -273,7 +277,7 @@ QColor WaitTreeThread::GetColor() const {
} }
std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const { std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const {
std::vector<std::unique_ptr<WaitTreeItem>> list(WaitTreeWaitObject::GetChildren()); std::vector<std::unique_ptr<WaitTreeItem>> list(WaitTreeSynchronizationObject::GetChildren());
const auto& thread = static_cast<const Kernel::Thread&>(object); const auto& thread = static_cast<const Kernel::Thread&>(object);
@ -314,7 +318,7 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const {
} }
if (thread.GetStatus() == Kernel::ThreadStatus::WaitSynch) { if (thread.GetStatus() == Kernel::ThreadStatus::WaitSynch) {
list.push_back(std::make_unique<WaitTreeObjectList>(thread.GetWaitObjects(), list.push_back(std::make_unique<WaitTreeObjectList>(thread.GetSynchronizationObjects(),
thread.IsSleepingOnWait())); thread.IsSleepingOnWait()));
} }
@ -323,7 +327,8 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const {
return list; return list;
} }
WaitTreeEvent::WaitTreeEvent(const Kernel::ReadableEvent& object) : WaitTreeWaitObject(object) {} WaitTreeEvent::WaitTreeEvent(const Kernel::ReadableEvent& object)
: WaitTreeSynchronizationObject(object) {}
WaitTreeEvent::~WaitTreeEvent() = default; WaitTreeEvent::~WaitTreeEvent() = default;
WaitTreeThreadList::WaitTreeThreadList(const std::vector<std::shared_ptr<Kernel::Thread>>& list) WaitTreeThreadList::WaitTreeThreadList(const std::vector<std::shared_ptr<Kernel::Thread>>& list)

View file

@ -19,7 +19,7 @@ class EmuThread;
namespace Kernel { namespace Kernel {
class HandleTable; class HandleTable;
class ReadableEvent; class ReadableEvent;
class WaitObject; class SynchronizationObject;
class Thread; class Thread;
} // namespace Kernel } // namespace Kernel
@ -99,35 +99,37 @@ private:
const Kernel::Thread& thread; const Kernel::Thread& thread;
}; };
class WaitTreeWaitObject : public WaitTreeExpandableItem { class WaitTreeSynchronizationObject : public WaitTreeExpandableItem {
Q_OBJECT Q_OBJECT
public: public:
explicit WaitTreeWaitObject(const Kernel::WaitObject& object); explicit WaitTreeSynchronizationObject(const Kernel::SynchronizationObject& object);
~WaitTreeWaitObject() override; ~WaitTreeSynchronizationObject() override;
static std::unique_ptr<WaitTreeWaitObject> make(const Kernel::WaitObject& object); static std::unique_ptr<WaitTreeSynchronizationObject> make(
const Kernel::SynchronizationObject& object);
QString GetText() const override; QString GetText() const override;
std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
protected: protected:
const Kernel::WaitObject& object; const Kernel::SynchronizationObject& object;
}; };
class WaitTreeObjectList : public WaitTreeExpandableItem { class WaitTreeObjectList : public WaitTreeExpandableItem {
Q_OBJECT Q_OBJECT
public: public:
WaitTreeObjectList(const std::vector<std::shared_ptr<Kernel::WaitObject>>& list, bool wait_all); WaitTreeObjectList(const std::vector<std::shared_ptr<Kernel::SynchronizationObject>>& list,
bool wait_all);
~WaitTreeObjectList() override; ~WaitTreeObjectList() override;
QString GetText() const override; QString GetText() const override;
std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
private: private:
const std::vector<std::shared_ptr<Kernel::WaitObject>>& object_list; const std::vector<std::shared_ptr<Kernel::SynchronizationObject>>& object_list;
bool wait_all; bool wait_all;
}; };
class WaitTreeThread : public WaitTreeWaitObject { class WaitTreeThread : public WaitTreeSynchronizationObject {
Q_OBJECT Q_OBJECT
public: public:
explicit WaitTreeThread(const Kernel::Thread& thread); explicit WaitTreeThread(const Kernel::Thread& thread);
@ -138,7 +140,7 @@ public:
std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
}; };
class WaitTreeEvent : public WaitTreeWaitObject { class WaitTreeEvent : public WaitTreeSynchronizationObject {
Q_OBJECT Q_OBJECT
public: public:
explicit WaitTreeEvent(const Kernel::ReadableEvent& object); explicit WaitTreeEvent(const Kernel::ReadableEvent& object);