mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-01-27 02:44:36 +01:00
Very bugfix
I reverted cellSaveData changes since they were relying on the uninitialized local variable `save_entry` and thus were almost completely wrong.
This commit is contained in:
parent
5bd83516ba
commit
9913c9059c
|
|
@ -86,7 +86,10 @@ bool CPUThread::IsPaused() const
|
|||
|
||||
void CPUThread::DumpInformation() const
|
||||
{
|
||||
LOG_WARNING(GENERAL, RegsToString());
|
||||
if (!Emu.IsStopped())
|
||||
{
|
||||
LOG_NOTICE(GENERAL, RegsToString());
|
||||
}
|
||||
}
|
||||
|
||||
void CPUThread::Run()
|
||||
|
|
|
|||
|
|
@ -219,6 +219,9 @@ namespace vm
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// clear predicate
|
||||
pred = nullptr;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
|
@ -233,16 +236,13 @@ namespace vm
|
|||
// dummy return value
|
||||
return true;
|
||||
};
|
||||
|
||||
// signal unconditionally (may be already signaled)
|
||||
thread->Signal();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// clear predicate and signal
|
||||
pred = nullptr;
|
||||
// set addr and mask to invalid values to prevent further polling
|
||||
addr = 0;
|
||||
mask = ~0;
|
||||
|
||||
// signal thread (must not be signaled yet)
|
||||
if (!thread->Signal())
|
||||
{
|
||||
throw EXCEPTION("Thread already signaled");
|
||||
|
|
@ -271,10 +271,10 @@ namespace vm
|
|||
m_waiter->thread->cv.wait(m_lock);
|
||||
}
|
||||
|
||||
// if another thread called pred(), it must be removed
|
||||
// if another thread successfully called pred(), it must be set to null
|
||||
if (m_waiter->pred)
|
||||
{
|
||||
// pred() should rethrow exception caught by another thread
|
||||
// if pred() called by another thread threw an exception, rethrow it
|
||||
m_waiter->pred();
|
||||
|
||||
throw EXCEPTION("Unexpected");
|
||||
|
|
@ -283,7 +283,9 @@ namespace vm
|
|||
|
||||
waiter_lock_t::~waiter_lock_t()
|
||||
{
|
||||
// remove predicate to avoid excessive signaling
|
||||
// reset some data to avoid excessive signaling
|
||||
m_waiter->addr = 0;
|
||||
m_waiter->mask = ~0;
|
||||
m_waiter->pred = nullptr;
|
||||
|
||||
// unlock thread's mutex to avoid deadlock with g_waiter_list_mutex
|
||||
|
|
@ -302,7 +304,8 @@ namespace vm
|
|||
{
|
||||
waiter_t& waiter = g_waiter_list[i];
|
||||
|
||||
if (((waiter.addr ^ addr) & (mask & waiter.mask)) == 0 && waiter.thread && waiter.pred)
|
||||
// check address range overlapping using masks generated from size (power of 2)
|
||||
if (waiter.thread && ((waiter.addr ^ addr) & (mask & waiter.mask)) == 0)
|
||||
{
|
||||
waiter.try_notify();
|
||||
}
|
||||
|
|
@ -323,24 +326,28 @@ namespace vm
|
|||
|
||||
bool notify_all()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(g_waiter_list_mutex, std::try_to_lock);
|
||||
std::unique_lock<std::mutex> lock(g_waiter_list_mutex);
|
||||
|
||||
if (lock)
|
||||
std::size_t waiters = 0;
|
||||
std::size_t signaled = 0;
|
||||
|
||||
for (std::size_t i = 0; i < g_waiter_max; i++)
|
||||
{
|
||||
for (std::size_t i = 0; i < g_waiter_max; i++)
|
||||
{
|
||||
waiter_t& waiter = g_waiter_list[i];
|
||||
waiter_t& waiter = g_waiter_list[i];
|
||||
|
||||
if (waiter.thread && waiter.pred)
|
||||
if (waiter.thread && waiter.addr)
|
||||
{
|
||||
waiters++;
|
||||
|
||||
if (waiter.try_notify())
|
||||
{
|
||||
waiter.try_notify();
|
||||
signaled++;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
// return true if waiter list is empty or all available waiters were signaled
|
||||
return waiters == signaled;
|
||||
}
|
||||
|
||||
void start()
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ namespace vm
|
|||
struct waiter_t
|
||||
{
|
||||
u32 addr = 0;
|
||||
u32 mask = 0;
|
||||
u32 mask = ~0;
|
||||
CPUThread* thread = nullptr;
|
||||
|
||||
std::function<bool()> pred;
|
||||
|
|
|
|||
|
|
@ -57,7 +57,6 @@ never_inline s32 savedata_op(
|
|||
|
||||
if (!lock)
|
||||
{
|
||||
cellSysutil.Error("savedata_op(): failed to lock the mutex.");
|
||||
return CELL_SAVEDATA_ERROR_BUSY;
|
||||
}
|
||||
|
||||
|
|
@ -192,7 +191,6 @@ never_inline s32 savedata_op(
|
|||
|
||||
if (result->result < 0)
|
||||
{
|
||||
cellSysutil.Error("savedata_op(): funcList returned result < 0.");
|
||||
return CELL_SAVEDATA_ERROR_CBRESULT;
|
||||
}
|
||||
|
||||
|
|
@ -304,7 +302,6 @@ never_inline s32 savedata_op(
|
|||
|
||||
if (result->result < 0)
|
||||
{
|
||||
cellSysutil.Error("savedata_op(): funcFixed returned result < 0.");
|
||||
return CELL_SAVEDATA_ERROR_CBRESULT;
|
||||
}
|
||||
|
||||
|
|
@ -346,31 +343,10 @@ never_inline s32 savedata_op(
|
|||
|
||||
PSFLoader psf;
|
||||
|
||||
// Create save directory if necessary
|
||||
if (save_entry.isNew)
|
||||
{
|
||||
if (!Emu.GetVFS().ExistsDir(dir_path) && !Emu.GetVFS().CreateDir(dir_path))
|
||||
{
|
||||
cellSysutil.Error("savedata_op(): Savedata directory creation failed.");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Is loading the PARAM.SFO really necessary? Setting empty stuff seems to fix a couple games.
|
||||
psf.SetInteger("ATTRIBUTE", 0);
|
||||
psf.SetString("TITLE", "");
|
||||
psf.SetString("SUB_TITLE", "");
|
||||
psf.SetString("DETAIL", "");
|
||||
psf.SetString("SAVEDATA_LIST_PARAM", "");
|
||||
}
|
||||
}
|
||||
|
||||
// Load PARAM.SFO
|
||||
{
|
||||
if (!save_entry.isNew)
|
||||
{
|
||||
vfsFile f(sfo_path);
|
||||
psf.Load(f);
|
||||
}
|
||||
vfsFile f(sfo_path);
|
||||
psf.Load(f);
|
||||
}
|
||||
|
||||
// Get save stats
|
||||
|
|
@ -460,7 +436,6 @@ never_inline s32 savedata_op(
|
|||
|
||||
if (result->result < 0)
|
||||
{
|
||||
cellSysutil.Error("savedata_op(): funcStat returned result < 0.");
|
||||
return CELL_SAVEDATA_ERROR_CBRESULT;
|
||||
}
|
||||
|
||||
|
|
@ -510,6 +485,12 @@ never_inline s32 savedata_op(
|
|||
}
|
||||
}
|
||||
|
||||
// Create save directory if necessary
|
||||
if (psf && save_entry.isNew && !Emu.GetVFS().CreateDir(dir_path))
|
||||
{
|
||||
// Let's ignore this error for now
|
||||
}
|
||||
|
||||
// Enter the loop where the save files are read/created/deleted
|
||||
vm::stackvar<CellSaveDataFileGet> fileGet(CPU);
|
||||
vm::stackvar<CellSaveDataFileSet> fileSet(CPU);
|
||||
|
|
@ -523,7 +504,6 @@ never_inline s32 savedata_op(
|
|||
|
||||
if (result->result < 0)
|
||||
{
|
||||
cellSysutil.Error("savedata_op(): funcFile returned result < 0.");
|
||||
return CELL_SAVEDATA_ERROR_CBRESULT;
|
||||
}
|
||||
|
||||
|
|
@ -772,7 +752,7 @@ s32 cellSaveDataListAutoLoad(
|
|||
}
|
||||
|
||||
s32 cellSaveDataDelete2(u32 container)
|
||||
{
|
||||
{
|
||||
cellSysutil.Todo("cellSaveDataDelete2(container=0x%x)", container);
|
||||
|
||||
return CELL_SAVEDATA_RET_CANCEL;
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ namespace ppu_func_detail
|
|||
static force_inline T get_arg(PPUThread& CPU)
|
||||
{
|
||||
// TODO: check stack argument displacement
|
||||
const u64 res = CPU.GetStackArg(8 + std::max<u32>(g_count - 8, 0) + std::max<u32>(f_count - 13, 0) + std::max<u32>(v_count - 12, 0));
|
||||
const u64 res = CPU.GetStackArg(8 + std::max<s32>(g_count - 8, 0) + std::max<s32>(f_count - 13, 0) + std::max<s32>(v_count - 12, 0));
|
||||
return cast_from_ppu_gpr<T>(res);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue