diff options
-rw-r--r-- | src/core/hle/kernel/kernel.h | 4 | ||||
-rw-r--r-- | src/core/hle/service/nvflinger/buffer_queue.cpp | 6 | ||||
-rw-r--r-- | src/core/hle/service/nvflinger/buffer_queue.h | 6 | ||||
-rw-r--r-- | src/yuzu/debugger/wait_tree.cpp | 86 | ||||
-rw-r--r-- | src/yuzu/debugger/wait_tree.h | 43 |
5 files changed, 55 insertions, 90 deletions
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 053bf4e17..402ae900f 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -18,12 +18,10 @@ using Handle = u32; enum class HandleType : u32 { Unknown, Event, - Mutex, SharedMemory, Thread, Process, AddressArbiter, - ConditionVariable, Timer, ResourceLimit, CodeSet, @@ -63,9 +61,7 @@ public: bool IsWaitable() const { switch (GetHandleType()) { case HandleType::Event: - case HandleType::Mutex: case HandleType::Thread: - case HandleType::ConditionVariable: case HandleType::Timer: case HandleType::ServerPort: case HandleType::ServerSession: diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index 03a4fed59..e4ff2e267 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp @@ -9,7 +9,8 @@ #include "core/core_timing.h" #include "core/hle/service/nvflinger/buffer_queue.h" -namespace Service::NVFlinger { +namespace Service { +namespace NVFlinger { BufferQueue::BufferQueue(u32 id, u64 layer_id) : id(id), layer_id(layer_id) { native_handle = Kernel::Event::Create(Kernel::ResetType::OneShot, "BufferQueue NativeHandle"); @@ -110,4 +111,5 @@ void BufferQueue::SetBufferWaitEvent(Kernel::SharedPtr<Kernel::Event>&& wait_eve buffer_wait_event = std::move(wait_event); } -} // namespace Service::NVFlinger +} // namespace NVFlinger +} // namespace Service diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h index 95adc4706..1de5767cb 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.h +++ b/src/core/hle/service/nvflinger/buffer_queue.h @@ -13,7 +13,8 @@ namespace CoreTiming { struct EventType; } -namespace Service::NVFlinger { +namespace Service { +namespace NVFlinger { struct IGBPBuffer { u32_le magic; @@ -97,4 +98,5 @@ private: Kernel::SharedPtr<Kernel::Event> buffer_wait_event; }; -} // namespace Service::NVFlinger +} // namespace NVFlinger +} // namespace Service diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index cae2864e5..acc4c2e0b 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp @@ -6,8 +6,8 @@ #include "yuzu/util/util.h" #include "core/core.h" -#include "core/hle/kernel/condition_variable.h" #include "core/hle/kernel/event.h" +#include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/mutex.h" #include "core/hle/kernel/thread.h" #include "core/hle/kernel/timer.h" @@ -67,6 +67,29 @@ QString WaitTreeText::GetText() const { return text; } +WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address) : mutex_address(mutex_address) { + mutex_value = Memory::Read32(mutex_address); + owner_handle = static_cast<Kernel::Handle>(mutex_value & Kernel::Mutex::MutexOwnerMask); + owner = Kernel::g_handle_table.Get<Kernel::Thread>(owner_handle); +} + +QString WaitTreeMutexInfo::GetText() const { + return tr("waiting for mutex 0x%1").arg(mutex_address, 16, 16, QLatin1Char('0')); +} + +std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeMutexInfo::GetChildren() const { + std::vector<std::unique_ptr<WaitTreeItem>> list; + + bool has_waiters = (mutex_value & Kernel::Mutex::MutexHasWaitersFlag) != 0; + + list.push_back(std::make_unique<WaitTreeText>(tr("has waiters: %1").arg(has_waiters))); + list.push_back(std::make_unique<WaitTreeText>( + tr("owner handle: 0x%1").arg(owner_handle, 8, 16, QLatin1Char('0')))); + if (owner != nullptr) + list.push_back(std::make_unique<WaitTreeThread>(*owner)); + return list; +} + WaitTreeWaitObject::WaitTreeWaitObject(const Kernel::WaitObject& o) : object(o) {} bool WaitTreeExpandableItem::IsExpandable() const { @@ -84,11 +107,6 @@ std::unique_ptr<WaitTreeWaitObject> WaitTreeWaitObject::make(const Kernel::WaitO switch (object.GetHandleType()) { case Kernel::HandleType::Event: return std::make_unique<WaitTreeEvent>(static_cast<const Kernel::Event&>(object)); - case Kernel::HandleType::Mutex: - return std::make_unique<WaitTreeMutex>(static_cast<const Kernel::Mutex&>(object)); - case Kernel::HandleType::ConditionVariable: - return std::make_unique<WaitTreeConditionVariable>( - static_cast<const Kernel::ConditionVariable&>(object)); case Kernel::HandleType::Timer: return std::make_unique<WaitTreeTimer>(static_cast<const Kernel::Timer&>(object)); case Kernel::HandleType::Thread: @@ -160,6 +178,9 @@ QString WaitTreeThread::GetText() const { case THREADSTATUS_WAIT_SYNCH_ANY: status = tr("waiting for objects"); break; + case THREADSTATUS_WAIT_MUTEX: + status = tr("waiting for mutex"); + break; case THREADSTATUS_DORMANT: status = tr("dormant"); break; @@ -186,6 +207,7 @@ QColor WaitTreeThread::GetColor() const { return QColor(Qt::GlobalColor::darkYellow); case THREADSTATUS_WAIT_SYNCH_ALL: case THREADSTATUS_WAIT_SYNCH_ANY: + case THREADSTATUS_WAIT_MUTEX: return QColor(Qt::GlobalColor::red); case THREADSTATUS_DORMANT: return QColor(Qt::GlobalColor::darkCyan); @@ -225,11 +247,11 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const { list.push_back(std::make_unique<WaitTreeText>( tr("last running ticks = %1").arg(thread.last_running_ticks))); - if (thread.held_mutexes.empty()) { - list.push_back(std::make_unique<WaitTreeText>(tr("not holding mutex"))); - } else { - list.push_back(std::make_unique<WaitTreeMutexList>(thread.held_mutexes)); - } + if (thread.mutex_wait_address != 0) + list.push_back(std::make_unique<WaitTreeMutexInfo>(thread.mutex_wait_address)); + else + list.push_back(std::make_unique<WaitTreeText>(tr("not waiting for mutex"))); + if (thread.status == THREADSTATUS_WAIT_SYNCH_ANY || thread.status == THREADSTATUS_WAIT_SYNCH_ALL) { list.push_back(std::make_unique<WaitTreeObjectList>(thread.wait_objects, @@ -250,33 +272,6 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeEvent::GetChildren() const { return list; } -WaitTreeMutex::WaitTreeMutex(const Kernel::Mutex& object) : WaitTreeWaitObject(object) {} - -std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeMutex::GetChildren() const { - std::vector<std::unique_ptr<WaitTreeItem>> list(WaitTreeWaitObject::GetChildren()); - - const auto& mutex = static_cast<const Kernel::Mutex&>(object); - if (mutex.GetHasWaiters()) { - list.push_back(std::make_unique<WaitTreeText>(tr("locked by thread:"))); - list.push_back(std::make_unique<WaitTreeThread>(*mutex.GetHoldingThread())); - } else { - list.push_back(std::make_unique<WaitTreeText>(tr("free"))); - } - return list; -} - -WaitTreeConditionVariable::WaitTreeConditionVariable(const Kernel::ConditionVariable& object) - : WaitTreeWaitObject(object) {} - -std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeConditionVariable::GetChildren() const { - std::vector<std::unique_ptr<WaitTreeItem>> list(WaitTreeWaitObject::GetChildren()); - - const auto& condition_variable = static_cast<const Kernel::ConditionVariable&>(object); - list.push_back(std::make_unique<WaitTreeText>( - tr("available count = %1").arg(condition_variable.GetAvailableCount()))); - return list; -} - WaitTreeTimer::WaitTreeTimer(const Kernel::Timer& object) : WaitTreeWaitObject(object) {} std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeTimer::GetChildren() const { @@ -293,21 +288,6 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeTimer::GetChildren() const { return list; } -WaitTreeMutexList::WaitTreeMutexList( - const boost::container::flat_set<Kernel::SharedPtr<Kernel::Mutex>>& list) - : mutex_list(list) {} - -QString WaitTreeMutexList::GetText() const { - return tr("holding mutexes"); -} - -std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeMutexList::GetChildren() const { - std::vector<std::unique_ptr<WaitTreeItem>> list(mutex_list.size()); - std::transform(mutex_list.begin(), mutex_list.end(), list.begin(), - [](const auto& t) { return std::make_unique<WaitTreeMutex>(*t); }); - return list; -} - WaitTreeThreadList::WaitTreeThreadList(const std::vector<Kernel::SharedPtr<Kernel::Thread>>& list) : thread_list(list) {} diff --git a/src/yuzu/debugger/wait_tree.h b/src/yuzu/debugger/wait_tree.h index e538174eb..300ba9ae4 100644 --- a/src/yuzu/debugger/wait_tree.h +++ b/src/yuzu/debugger/wait_tree.h @@ -16,8 +16,6 @@ class EmuThread; namespace Kernel { class WaitObject; class Event; -class Mutex; -class ConditionVariable; class Thread; class Timer; } // namespace Kernel @@ -61,6 +59,20 @@ public: bool IsExpandable() const override; }; +class WaitTreeMutexInfo : public WaitTreeExpandableItem { + Q_OBJECT +public: + explicit WaitTreeMutexInfo(VAddr mutex_address); + QString GetText() const override; + std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; + +private: + VAddr mutex_address; + u32 mutex_value; + Kernel::Handle owner_handle; + Kernel::SharedPtr<Kernel::Thread> owner; +}; + class WaitTreeWaitObject : public WaitTreeExpandableItem { Q_OBJECT public: @@ -104,20 +116,6 @@ public: std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; }; -class WaitTreeMutex : public WaitTreeWaitObject { - Q_OBJECT -public: - explicit WaitTreeMutex(const Kernel::Mutex& object); - std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; -}; - -class WaitTreeConditionVariable : public WaitTreeWaitObject { - Q_OBJECT -public: - explicit WaitTreeConditionVariable(const Kernel::ConditionVariable& object); - std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; -}; - class WaitTreeTimer : public WaitTreeWaitObject { Q_OBJECT public: @@ -125,19 +123,6 @@ public: std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; }; -class WaitTreeMutexList : public WaitTreeExpandableItem { - Q_OBJECT -public: - explicit WaitTreeMutexList( - const boost::container::flat_set<Kernel::SharedPtr<Kernel::Mutex>>& list); - - QString GetText() const override; - std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; - -private: - const boost::container::flat_set<Kernel::SharedPtr<Kernel::Mutex>>& mutex_list; -}; - class WaitTreeThreadList : public WaitTreeExpandableItem { Q_OBJECT public: |