MTVU: Purge pxThread

This commit is contained in:
Connor McLaughlin 2022-05-05 07:55:16 +10:00 committed by refractionpcsx2
parent 0ae17ddb1a
commit 599626b709
5 changed files with 68 additions and 45 deletions

View File

@ -18,8 +18,9 @@
#include "MTVU.h"
#include "newVif.h"
#include "Gif_Unit.h"
#include <thread>
VU_Thread vu1Thread(CpuVU1, VU1);
VU_Thread vu1Thread;
#define MTVU_ALWAYS_KICK 0
#define MTVU_SYNC_MODE 0
@ -86,21 +87,35 @@ void SaveStateBase::mtvuFreeze()
Freeze(vu1Thread.vuCycleIdx);
}
VU_Thread::VU_Thread(BaseVUmicroCPU*& _vuCPU, VURegs& _vuRegs)
: vuCPU(_vuCPU)
, vuRegs(_vuRegs)
VU_Thread::VU_Thread()
{
m_name = L"MTVU";
Reset();
}
VU_Thread::~VU_Thread()
{
try
{
pxThread::Cancel();
}
DESTRUCTOR_CATCHALL
Close();
}
void VU_Thread::Open()
{
if (m_thread.joinable())
return;
Reset();
semaEvent.Reset();
m_shutdown_flag.store(false, std::memory_order_release);
m_thread = std::thread(&VU_Thread::ExecuteRingBuffer, this);
}
void VU_Thread::Close()
{
if (!m_thread.joinable())
return;
m_shutdown_flag.store(true, std::memory_order_release);
semaEvent.NotifyOfWork();
m_thread.join();
}
void VU_Thread::Reset()
@ -117,20 +132,17 @@ void VU_Thread::Reset()
vu1Thread.mtvuInterrupts = 0;
}
void VU_Thread::ExecuteTaskInThread()
{
PCSX2_PAGEFAULT_PROTECT
{
ExecuteRingBuffer();
}
PCSX2_PAGEFAULT_EXCEPT;
}
void VU_Thread::ExecuteRingBuffer()
{
m_thread_handle = Threading::ThreadHandle::GetForCallingThread();
Threading::SetNameOfCurrentThread("MTVU");
for (;;)
{
semaEvent.WaitForWork();
if (m_shutdown_flag.load(std::memory_order_acquire))
break;
while (m_ato_read_pos.load(std::memory_order_relaxed) != GetWritePos())
{
u32 tag = Read();
@ -138,18 +150,18 @@ void VU_Thread::ExecuteRingBuffer()
{
case MTVU_VU_EXECUTE:
{
vuRegs.cycle = 0;
VU1.cycle = 0;
s32 addr = Read();
vifRegs.top = Read();
vifRegs.itop = Read();
vuFBRST = Read();
if (addr != -1)
vuRegs.VI[REG_TPC].UL = addr & 0x7FF;
vuCPU->SetStartPC(vuRegs.VI[REG_TPC].UL << 3);
vuCPU->Execute(vu1RunCycles);
VU1.VI[REG_TPC].UL = addr & 0x7FF;
CpuVU1->SetStartPC(VU1.VI[REG_TPC].UL << 3);
CpuVU1->Execute(vu1RunCycles);
gifUnit.gifPath[GIF_PATH_1].FinishGSPacketMTVU();
semaXGkick.Post(); // Tell MTGS a path1 packet is complete
vuCycles[vuCycleIdx].store(vuRegs.cycle, std::memory_order_release);
vuCycles[vuCycleIdx].store(VU1.cycle, std::memory_order_release);
vuCycleIdx = (vuCycleIdx + 1) & 3;
break;
}
@ -157,22 +169,22 @@ void VU_Thread::ExecuteRingBuffer()
{
u32 vu_micro_addr = Read();
u32 size = Read();
vuCPU->Clear(vu_micro_addr, size);
Read(&vuRegs.Micro[vu_micro_addr], size);
CpuVU1->Clear(vu_micro_addr, size);
Read(&VU1.Micro[vu_micro_addr], size);
break;
}
case MTVU_VU_WRITE_DATA:
{
u32 vu_data_addr = Read();
u32 size = Read();
Read(&vuRegs.Mem[vu_data_addr], size);
Read(&VU1.Mem[vu_data_addr], size);
break;
}
case MTVU_VU_WRITE_VIREGS:
Read(&vuRegs.VI, size_u32(32));
Read(&VU1.VI, size_u32(32));
break;
case MTVU_VU_WRITE_VFREGS:
Read(&vuRegs.VF, size_u32(4*32));
Read(&VU1.VF, size_u32(4*32));
break;
case MTVU_VIF_WRITE_COL:
Read(&vif.MaskCol, sizeof(vif.MaskCol));
@ -199,6 +211,9 @@ void VU_Thread::ExecuteRingBuffer()
CommitReadPos();
}
}
m_thread_handle = {};
semaEvent.Kill();
}

View File

@ -14,11 +14,13 @@
*/
#pragma once
#include "System/SysThreads.h"
#include "common/Threading.h"
#include "Vif.h"
#include "Vif_Dma.h"
#include "VUmicro.h"
#include <thread>
#define MTVU_LOG(...) do{} while(0)
//#define MTVU_LOG DevCon.WriteLn
@ -26,7 +28,7 @@
// - This class should only be accessed from the EE thread...
// - buffer_size must be power of 2
// - ring-buffer has no complete pending packets when read_pos==write_pos
class VU_Thread : public pxThread {
class VU_Thread final {
static const s32 buffer_size = (_1mb * 16) / sizeof(s32);
u32 buffer[buffer_size];
@ -35,14 +37,16 @@ class VU_Thread : public pxThread {
alignas(64) std::atomic<int> m_ato_write_pos; // Only modified by EE thread
alignas(64) int m_read_pos; // temporary read pos (local to the VU thread)
int m_write_pos; // temporary write pos (local to the EE thread)
WorkSema semaEvent;
BaseVUmicroCPU*& vuCPU;
VURegs& vuRegs;
Threading::WorkSema semaEvent;
std::atomic_bool m_shutdown_flag{false};
std::thread m_thread;
Threading::ThreadHandle m_thread_handle;
public:
alignas(16) vifStruct vif;
alignas(16) VIFregisters vifRegs;
Semaphore semaXGkick;
Threading::Semaphore semaXGkick;
std::atomic<unsigned int> vuCycles[4]; // Used for VU cycle stealing hack
u32 vuCycleIdx; // Used for VU cycle stealing hack
u32 vuFBRST;
@ -59,8 +63,16 @@ public:
std::atomic<u64> gsLabel; // Used for GS Label command
std::atomic<u64> gsSignal; // Used for GS Signal command
VU_Thread(BaseVUmicroCPU*& _vuCPU, VURegs& _vuRegs);
virtual ~VU_Thread();
VU_Thread();
~VU_Thread();
__fi const Threading::ThreadHandle& GetThreadHandle() const { return m_thread_handle; }
/// Ensures the VU thread is started.
void Open();
/// Shuts down the VU thread if it is currently running.
void Close();
void Reset();
@ -93,9 +105,6 @@ public:
void WriteRow(vifStruct& _vif);
protected:
void ExecuteTaskInThread();
private:
void ExecuteRingBuffer();

View File

@ -119,7 +119,7 @@ void PerformanceMetrics::Reset()
s_last_cpu_time = s_cpu_thread_handle.GetCPUTime();
s_last_gs_time = GetMTGS().GetCpuTime();
s_last_vu_time = THREAD_VU1 ? vu1Thread.GetCpuTime() : 0;
s_last_vu_time = THREAD_VU1 ? vu1Thread.GetThreadHandle().GetCPUTime() : 0;
s_last_ticks = GetCPUTicks();
for (GSSWThreadStats& stat : s_gs_sw_threads)
@ -184,7 +184,7 @@ void PerformanceMetrics::Update(bool gs_register_write, bool fb_blit)
const u64 cpu_time = s_cpu_thread_handle.GetCPUTime();
const u64 gs_time = GetMTGS().GetCpuTime();
const u64 vu_time = THREAD_VU1 ? vu1Thread.GetCpuTime() : 0;
const u64 vu_time = THREAD_VU1 ? vu1Thread.GetThreadHandle().GetCPUTime() : 0;
const u64 cpu_delta = cpu_time - s_last_cpu_time;
const u64 gs_delta = gs_time - s_last_gs_time;

View File

@ -368,8 +368,7 @@ void SysCoreThread::OnCleanupInThread()
m_resetVirtualMachine = true;
R3000A::ioman::reset();
// FIXME: temporary workaround for deadlock on exit, which actually should be a crash
vu1Thread.WaitVU();
vu1Thread.Close();
USBclose();
SPU2close();
PADclose();

View File

@ -371,7 +371,7 @@ void recMicroVU1::Reserve()
if (m_Reserved.exchange(1) == 0)
{
mVUinit(microVU1, 1);
vu1Thread.Start();
vu1Thread.Open();
}
}