mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-10 00:41:26 +12:00
Reservation global struct removed
It wasn't solving anything, unfortunately.
This commit is contained in:
parent
184007e1e0
commit
a169c5bcac
3 changed files with 61 additions and 75 deletions
|
@ -9,8 +9,6 @@
|
||||||
|
|
||||||
#include "CPUThread.h"
|
#include "CPUThread.h"
|
||||||
|
|
||||||
reservation_struct reservation;
|
|
||||||
|
|
||||||
CPUThread* GetCurrentCPUThread()
|
CPUThread* GetCurrentCPUThread()
|
||||||
{
|
{
|
||||||
return (CPUThread*)GetCurrentNamedThread();
|
return (CPUThread*)GetCurrentNamedThread();
|
||||||
|
|
|
@ -3,26 +3,6 @@
|
||||||
#include "Emu/CPU/CPUDecoder.h"
|
#include "Emu/CPU/CPUDecoder.h"
|
||||||
#include "Utilities/SMutex.h"
|
#include "Utilities/SMutex.h"
|
||||||
|
|
||||||
typedef SMutexBase<u32, 0, 0xffffffff, /* busy wait: specify nullptr */ SM_Sleep> SMutexR;
|
|
||||||
typedef SMutexLockerBase<SMutexR, u32, SM_GetCurrentCPUThreadId> SMutexLockerR;
|
|
||||||
|
|
||||||
struct reservation_struct
|
|
||||||
{
|
|
||||||
SMutexR mutex; // mutex for updating reservation_owner and data
|
|
||||||
// std::mutex doesn't work because it probably wakes up waiting threads in the most unwanted order
|
|
||||||
// and doesn't give a chance to finish some work before losing the reservation
|
|
||||||
u32 owner; // id of thread that got reservation
|
|
||||||
u64 addr;
|
|
||||||
u64 data[16];
|
|
||||||
|
|
||||||
__forceinline void clear()
|
|
||||||
{
|
|
||||||
owner = 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
extern reservation_struct reservation;
|
|
||||||
|
|
||||||
enum CPUThreadType :unsigned char
|
enum CPUThreadType :unsigned char
|
||||||
{
|
{
|
||||||
CPU_THREAD_PPU,
|
CPU_THREAD_PPU,
|
||||||
|
|
|
@ -309,9 +309,12 @@ union SPU_SNRConfig_hdr
|
||||||
class SPUThread : public PPCThread
|
class SPUThread : public PPCThread
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SPU_GPR_hdr GPR[128]; //General-Purpose Registers
|
SPU_GPR_hdr GPR[128]; // General-Purpose Registers
|
||||||
//FPSCR FPSCR;
|
//FPSCR FPSCR;
|
||||||
SPU_SNRConfig_hdr cfg; //Signal Notification Registers Configuration (OR-mode enabled: 0x1 for SNR1, 0x2 for SNR2)
|
SPU_SNRConfig_hdr cfg; // Signal Notification Registers Configuration (OR-mode enabled: 0x1 for SNR1, 0x2 for SNR2)
|
||||||
|
|
||||||
|
u64 R_ADDR; // reservation address
|
||||||
|
u64 R_DATA[16]; // lock line data (BE)
|
||||||
|
|
||||||
EventPort SPUPs[64]; // SPU Thread Event Ports
|
EventPort SPUPs[64]; // SPU Thread Event Ports
|
||||||
EventManager SPUQs; // SPU Queue Mapping
|
EventManager SPUQs; // SPU Queue Mapping
|
||||||
|
@ -796,83 +799,90 @@ public:
|
||||||
|
|
||||||
if (op == MFC_GETLLAR_CMD) // get reservation
|
if (op == MFC_GETLLAR_CMD) // get reservation
|
||||||
{
|
{
|
||||||
SMutexLockerR lock(reservation.mutex);
|
if (R_ADDR)
|
||||||
reservation.owner = lock.tid;
|
{
|
||||||
reservation.addr = ea;
|
m_events |= SPU_EVENT_LR;
|
||||||
|
}
|
||||||
|
|
||||||
|
R_ADDR = ea;
|
||||||
for (u32 i = 0; i < 16; i++)
|
for (u32 i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
reservation.data[i] = *(u64*)&Memory[(u32)ea + i * 8];
|
R_DATA[i] = *(u64*)&Memory[R_ADDR + i * 8];
|
||||||
*(u64*)&Memory[dmac.ls_offset + lsa + i * 8] = reservation.data[i];
|
*(u64*)&Memory[dmac.ls_offset + lsa + i * 8] = R_DATA[i];
|
||||||
}
|
}
|
||||||
MFCArgs.AtomicStat.PushUncond(MFC_GETLLAR_SUCCESS);
|
MFCArgs.AtomicStat.PushUncond(MFC_GETLLAR_SUCCESS);
|
||||||
}
|
}
|
||||||
else if (op == MFC_PUTLLC_CMD) // store conditional
|
else if (op == MFC_PUTLLC_CMD) // store conditional
|
||||||
{
|
{
|
||||||
SMutexLockerR lock(reservation.mutex);
|
|
||||||
MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS);
|
MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS);
|
||||||
|
|
||||||
if (reservation.owner == lock.tid) // succeeded
|
if (R_ADDR == ea)
|
||||||
{
|
{
|
||||||
if (reservation.addr == ea)
|
u32 changed = 0, mask = 0;
|
||||||
|
u64 buf[16];
|
||||||
|
for (u32 i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < 16; i++)
|
buf[i] = *(u64*)&Memory[dmac.ls_offset + lsa + i * 8];
|
||||||
|
if (buf[i] != R_DATA[i])
|
||||||
{
|
{
|
||||||
if (*(u64*)&Memory[reservation.addr + i * 8] != reservation.data[i])
|
changed++;
|
||||||
|
mask |= (0x3 << (i * 2));
|
||||||
|
if (*(u64*)&Memory[R_ADDR + i * 8] != R_DATA[i])
|
||||||
{
|
{
|
||||||
|
m_events |= SPU_EVENT_LR;
|
||||||
MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_FAILURE);
|
MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_FAILURE);
|
||||||
reservation.clear();
|
R_ADDR = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
u32 changed = 0, mask = 0;
|
for (u32 i = 0; i < 16; i++)
|
||||||
for (u32 i = 0; i < 16; i++)
|
{
|
||||||
|
if (buf[i] != R_DATA[i])
|
||||||
{
|
{
|
||||||
u64 buf = *(u64*)&Memory[dmac.ls_offset + lsa + i * 8];
|
if (InterlockedCompareExchange64((volatile long long*)(Memory + (ea + i * 8)), buf[i], R_DATA[i]) != R_DATA[i])
|
||||||
if (buf != reservation.data[i])
|
|
||||||
{
|
{
|
||||||
changed++;
|
m_events |= SPU_EVENT_LR;
|
||||||
mask |= (0x3 << (i * 2));
|
MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_FAILURE);
|
||||||
|
|
||||||
if (InterlockedCompareExchange64((volatile long long*)(Memory + ((u32)ea + i * 8)), buf, reservation.data[i]) != reservation.data[i])
|
if (changed > 1)
|
||||||
{
|
{
|
||||||
MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_FAILURE);
|
LOG_ERROR(Log::SPU, "MFC_PUTLLC_CMD: Memory corrupted (~x%d (mask=0x%x)) (opcode=0x%x, cmd=0x%x, lsa = 0x%x, ea = 0x%llx, tag = 0x%x, size = 0x%x)",
|
||||||
|
changed, mask, op, cmd, lsa, ea, tag, size);
|
||||||
if (changed > 1)
|
Emu.Pause();
|
||||||
{
|
|
||||||
LOG_ERROR(Log::SPU, "MFC_PUTLLC_CMD: Reservation Error: impossibru (~ 8x%d (mask=0x%x)) (opcode=0x%x, cmd=0x%x, lsa = 0x%x, ea = 0x%llx, tag = 0x%x, size = 0x%x)",
|
|
||||||
changed, mask, op, cmd, lsa, ea, tag, size);
|
|
||||||
Emu.Pause();
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (changed > 1)
|
||||||
{
|
{
|
||||||
MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_FAILURE);
|
LOG_WARNING(Log::SPU, "MFC_PUTLLC_CMD: Reservation impossibru (~x%d (mask=0x%x)) (opcode=0x%x, cmd=0x%x, lsa = 0x%x, ea = 0x%llx, tag = 0x%x, size = 0x%x)",
|
||||||
|
changed, mask, op, cmd, lsa, ea, tag, size);
|
||||||
}
|
}
|
||||||
reservation.clear();
|
|
||||||
}
|
}
|
||||||
else // failed
|
else
|
||||||
{
|
{
|
||||||
MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_FAILURE);
|
MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_FAILURE);
|
||||||
}
|
}
|
||||||
|
R_ADDR = 0;
|
||||||
}
|
}
|
||||||
else // store unconditional
|
else // store unconditional
|
||||||
{
|
{
|
||||||
SMutexLockerR lock(reservation.mutex);
|
if (R_ADDR)
|
||||||
|
{
|
||||||
|
m_events |= SPU_EVENT_LR;
|
||||||
|
}
|
||||||
|
|
||||||
ProcessCmd(MFC_PUT_CMD, tag, lsa, ea, 128);
|
ProcessCmd(MFC_PUT_CMD, tag, lsa, ea, 128);
|
||||||
if (op == MFC_PUTLLUC_CMD)
|
if (op == MFC_PUTLLUC_CMD)
|
||||||
{
|
{
|
||||||
MFCArgs.AtomicStat.PushUncond(MFC_PUTLLUC_SUCCESS);
|
MFCArgs.AtomicStat.PushUncond(MFC_PUTLLUC_SUCCESS);
|
||||||
}
|
}
|
||||||
if (reservation.addr == ea)
|
R_ADDR = 0;
|
||||||
{
|
|
||||||
reservation.clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -888,24 +898,15 @@ public:
|
||||||
{
|
{
|
||||||
// SPU_EVENT_LR:
|
// SPU_EVENT_LR:
|
||||||
{
|
{
|
||||||
SMutexLockerR lock(reservation.mutex);
|
for (u32 i = 0; i < 16; i++)
|
||||||
|
|
||||||
if (reservation.owner == lock.tid)
|
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < 16; i++)
|
if (*(u64*)&Memory[R_ADDR + i * 8] != R_DATA[i])
|
||||||
{
|
{
|
||||||
if (*(u64*)&Memory[reservation.addr + i * 8] != reservation.data[i])
|
m_events |= SPU_EVENT_LR;
|
||||||
{
|
R_ADDR = 0;
|
||||||
m_events |= SPU_EVENT_LR;
|
break;
|
||||||
reservation.clear(); // ???
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
m_events |= SPU_EVENT_LR; // ???
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (m_events & m_event_mask) != 0;
|
return (m_events & m_event_mask) != 0;
|
||||||
|
@ -1338,6 +1339,13 @@ public:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SPU_RdMachStat:
|
||||||
|
{
|
||||||
|
v = 1; // hack (not isolated, interrupts enabled)
|
||||||
|
// TODO: check value
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
LOG_ERROR(Log::SPU, "%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]);
|
LOG_ERROR(Log::SPU, "%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue