Files
dolphin/Source/Core/Core/Debugger/OSThread.h
Lioncash 57534777d4 Common: Move OSThreads into core
Common shouldn't be depending on APIs in Core (in this, case depending
on the PowerPC namespace). Because of the poor separation here, this
moves OSThread functionality into core, so that it resolves the implicit
dependency on core.
2020-10-21 07:35:42 -04:00

155 lines
4.0 KiB
C++

// Copyright 2020 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
#include <array>
#include <string>
#include <type_traits>
#include "Common/CommonTypes.h"
#include "Common/Debug/Threads.h"
namespace Core::Debug
{
template <class C>
struct OSQueue
{
u32 head;
u32 tail;
};
template <class C>
struct OSLink
{
u32 next;
u32 prev;
};
struct OSMutex;
struct OSThread;
using OSThreadQueue = OSQueue<OSThread>;
using OSThreadLink = OSLink<OSThread>;
using OSMutexQueue = OSQueue<OSMutex>;
using OSMutexLink = OSLink<OSMutex>;
struct OSContext
{
enum class State : u16
{
HasFPU = 1,
HasException = 2,
};
std::array<u32, 32> gpr;
u32 cr;
u32 lr;
u32 ctr;
u32 xer;
std::array<double, 32> fpr;
u64 fpscr;
u32 srr0;
u32 srr1;
u16 dummy;
State state;
std::array<u32, 8> gqr;
u32 psf_padding;
std::array<double, 32> psf;
void Read(u32 addr);
};
static_assert(std::is_trivially_copyable_v<OSContext>);
static_assert(std::is_standard_layout_v<OSContext>);
static_assert(offsetof(OSContext, cr) == 0x80);
static_assert(offsetof(OSContext, fpscr) == 0x190);
static_assert(offsetof(OSContext, gqr) == 0x1a4);
static_assert(offsetof(OSContext, psf) == 0x1c8);
struct OSThread
{
OSContext context;
u16 state; // Thread state (ready, running, waiting, moribund)
u16 is_detached; // Is thread detached
s32 suspend; // Suspended if greater than zero
s32 effective_priority; // Effective priority
s32 base_priority; // Base priority
u32 exit_code_addr; // Exit value address
u32 queue_addr; // Address of the queue the thread is on
OSThreadLink queue_link; // Used to traverse the thread queue
// OSSleepThread uses it to insert the current thread at the end of the thread queue
OSThreadQueue join_queue; // Threads waiting to be joined
u32 mutex_addr; // Mutex waiting
OSMutexQueue mutex_queue; // Mutex owned
OSThreadLink thread_link; // Link containing all active threads
// The STACK_MAGIC is written at stack_end
u32 stack_addr;
u32 stack_end;
s32 error; // errno value
std::array<u32, 2> specific; // Pointers to data (can be used to store thread names)
static constexpr u32 STACK_MAGIC = 0xDEADBABE;
void Read(u32 addr);
bool IsValid() const;
};
static_assert(std::is_trivially_copyable_v<OSThread>);
static_assert(std::is_standard_layout_v<OSThread>);
static_assert(offsetof(OSThread, state) == 0x2c8);
static_assert(offsetof(OSThread, mutex_addr) == 0x2f0);
static_assert(offsetof(OSThread, stack_addr) == 0x304);
static_assert(offsetof(OSThread, specific) == 0x310);
struct OSMutex
{
OSThreadQueue thread_queue; // Threads waiting to own the mutex
u32 owner_addr; // Thread owning the mutex
s32 lock_count; // Mutex lock count
OSMutexLink link; // Used to traverse the thread's mutex queue
// OSLockMutex uses it to insert the acquired mutex at the end of the queue
void Read(u32 addr);
};
static_assert(std::is_trivially_copyable_v<OSMutex>);
static_assert(std::is_standard_layout_v<OSMutex>);
static_assert(offsetof(OSMutex, owner_addr) == 0x8);
static_assert(offsetof(OSMutex, link) == 0x10);
class OSThreadView : public Common::Debug::ThreadView
{
public:
explicit OSThreadView(u32 addr);
~OSThreadView() = default;
const OSThread& Data() const;
Common::Debug::PartialContext GetContext() const override;
u32 GetAddress() const override;
u16 GetState() const override;
bool IsSuspended() const override;
bool IsDetached() const override;
s32 GetBasePriority() const override;
s32 GetEffectivePriority() const override;
u32 GetStackStart() const override;
u32 GetStackEnd() const override;
std::size_t GetStackSize() const override;
s32 GetErrno() const override;
std::string GetSpecific() const override;
bool IsValid() const override;
private:
u32 m_address = 0;
OSThread m_thread;
};
} // namespace Core::Debug