mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-14 18:58:36 +12:00
sys_spinlock fixed
This commit is contained in:
parent
1f64087a3b
commit
fe49046a96
2 changed files with 31 additions and 30 deletions
|
@ -4,53 +4,59 @@
|
||||||
#include "Emu/System.h"
|
#include "Emu/System.h"
|
||||||
#include "Emu/Cell/PPUThread.h"
|
#include "Emu/Cell/PPUThread.h"
|
||||||
#include "Emu/SysCalls/SysCalls.h"
|
#include "Emu/SysCalls/SysCalls.h"
|
||||||
|
|
||||||
#include "sys_spinlock.h"
|
#include "sys_spinlock.h"
|
||||||
|
|
||||||
SysCallBase sys_spinlock("sys_spinlock");
|
SysCallBase sys_spinlock("sys_spinlock");
|
||||||
|
|
||||||
void sys_spinlock_initialize(mem_ptr_t<spinlock> lock)
|
void sys_spinlock_initialize(mem_ptr_t<std::atomic<be_t<u32>>> lock)
|
||||||
{
|
{
|
||||||
sys_spinlock.Log("sys_spinlock_initialize(lock_addr=0x%x)", lock.GetAddr());
|
sys_spinlock.Log("sys_spinlock_initialize(lock_addr=0x%x)", lock.GetAddr());
|
||||||
|
|
||||||
lock->mutex.initialize();
|
// prx: set 0 and sync
|
||||||
|
*lock = be_t<u32>::MakeFromBE(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sys_spinlock_lock(mem_ptr_t<spinlock> lock)
|
void sys_spinlock_lock(mem_ptr_t<std::atomic<be_t<u32>>> lock)
|
||||||
{
|
{
|
||||||
sys_spinlock.Log("sys_spinlock_lock(lock_addr=0x%x)", lock.GetAddr());
|
sys_spinlock.Log("sys_spinlock_lock(lock_addr=0x%x)", lock.GetAddr());
|
||||||
|
|
||||||
be_t<u32> tid = be_t<u32>::MakeFromLE(GetCurrentPPUThread().GetId());
|
// prx: exchange with 0xabadcafe, repeat until exchanged with 0
|
||||||
switch (lock->mutex.lock(tid))
|
while (lock->exchange(be_t<u32>::MakeFromBE(se32(0xabadcafe))).ToBE())
|
||||||
{
|
{
|
||||||
case SMR_ABORT: LOG_WARNING(HLE, "sys_spinlock_lock(0x%x) aborted", lock.GetAddr()); break;
|
while (lock->load(std::memory_order_relaxed).ToBE())
|
||||||
case SMR_DEADLOCK: LOG_ERROR(HLE, "sys_spinlock_lock(0x%x) reached deadlock", lock.GetAddr()); break; // ???
|
{
|
||||||
default: break;
|
if (Emu.IsStopped())
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Emu.IsStopped())
|
||||||
|
{
|
||||||
|
LOG_WARNING(HLE, "sys_spinlock_lock(0x%x) aborted", lock.GetAddr());
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 sys_spinlock_trylock(mem_ptr_t<spinlock> lock)
|
s32 sys_spinlock_trylock(mem_ptr_t<std::atomic<be_t<u32>>> lock)
|
||||||
{
|
{
|
||||||
sys_spinlock.Log("sys_spinlock_trylock(lock_addr=0x%x)", lock.GetAddr());
|
sys_spinlock.Log("sys_spinlock_trylock(lock_addr=0x%x)", lock.GetAddr());
|
||||||
|
|
||||||
be_t<u32> tid = be_t<u32>::MakeFromLE(GetCurrentPPUThread().GetId());
|
// prx: exchange with 0xabadcafe, translate exchanged value
|
||||||
switch (lock->mutex.trylock(tid))
|
if (lock->exchange(be_t<u32>::MakeFromBE(se32(0xabadcafe))).ToBE())
|
||||||
{
|
{
|
||||||
case SMR_FAILED: return CELL_EBUSY;
|
return CELL_EBUSY;
|
||||||
case SMR_ABORT: LOG_WARNING(HLE, "sys_spinlock_trylock(0x%x) aborted", lock.GetAddr()); break;
|
|
||||||
case SMR_DEADLOCK: LOG_ERROR(HLE, "sys_spinlock_trylock(0x%x) reached deadlock", lock.GetAddr()); break;
|
|
||||||
default: break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sys_spinlock_unlock(mem_ptr_t<spinlock> lock)
|
void sys_spinlock_unlock(mem_ptr_t<std::atomic<be_t<u32>>> lock)
|
||||||
{
|
{
|
||||||
sys_spinlock.Log("sys_spinlock_unlock(lock_addr=0x%x)", lock.GetAddr());
|
sys_spinlock.Log("sys_spinlock_unlock(lock_addr=0x%x)", lock.GetAddr());
|
||||||
|
|
||||||
while(true)
|
// prx: sync and set 0
|
||||||
{
|
*lock = be_t<u32>::MakeFromBE(0);
|
||||||
if (lock->mutex.unlock(lock->mutex.GetOwner()) != SMR_PERMITTED)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,12 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
struct spinlock
|
|
||||||
{
|
|
||||||
SMutexBE mutex;
|
|
||||||
};
|
|
||||||
|
|
||||||
// SysCalls
|
// SysCalls
|
||||||
void sys_spinlock_initialize(mem_ptr_t<spinlock> lock);
|
void sys_spinlock_initialize(mem_ptr_t<std::atomic<be_t<u32>>> lock);
|
||||||
void sys_spinlock_lock(mem_ptr_t<spinlock> lock);
|
void sys_spinlock_lock(mem_ptr_t<std::atomic<be_t<u32>>> lock);
|
||||||
s32 sys_spinlock_trylock(mem_ptr_t<spinlock> lock);
|
s32 sys_spinlock_trylock(mem_ptr_t<std::atomic<be_t<u32>>> lock);
|
||||||
void sys_spinlock_unlock(mem_ptr_t<spinlock> lock);
|
void sys_spinlock_unlock(mem_ptr_t<std::atomic<be_t<u32>>> lock);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue