mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-11 15:40:51 +00:00
Bugfix
This commit is contained in:
parent
11b409907e
commit
a62eeaaecc
@ -211,9 +211,9 @@ template<typename T> inline static typename std::enable_if<std::is_arithmetic<T>
|
||||
|
||||
template<typename T> inline static typename std::enable_if<std::is_arithmetic<T>::value, T>::type operator --(_atomic_base<be_t<T>>& left, int)
|
||||
{
|
||||
u64 result;
|
||||
T result;
|
||||
|
||||
left.atomic_op([&result](be_t<u64>& value)
|
||||
left.atomic_op([&result](be_t<T>& value)
|
||||
{
|
||||
result = value--;
|
||||
});
|
||||
|
@ -25,13 +25,13 @@ s32 syncMutexInitialize(vm::ptr<CellSyncMutex> mutex)
|
||||
{
|
||||
return CELL_SYNC_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
if (mutex.addr() % 4)
|
||||
{
|
||||
return CELL_SYNC_ERROR_ALIGN;
|
||||
}
|
||||
|
||||
// prx: set zero and sync
|
||||
mutex->data.exchange({});
|
||||
mutex->sync_var.exchange({});
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -51,26 +51,22 @@ s32 cellSyncMutexLock(vm::ptr<CellSyncMutex> mutex)
|
||||
{
|
||||
return CELL_SYNC_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
if (mutex.addr() % 4)
|
||||
{
|
||||
return CELL_SYNC_ERROR_ALIGN;
|
||||
}
|
||||
|
||||
// prx: increase m_acq and remember its old value
|
||||
be_t<u16> order;
|
||||
mutex->data.atomic_op([&order](CellSyncMutex::data_t& mutex)
|
||||
{
|
||||
order = mutex.m_acq++;
|
||||
});
|
||||
// prx: increase acquire_count and remember its old value
|
||||
const be_t<u16> order = be_t<u16>::make(mutex->acquire_count++);
|
||||
|
||||
// prx: wait until this old value is equal to m_rel
|
||||
// prx: wait until release_count is equal to old acquire_count
|
||||
g_sync_mutex_wm.wait_op(mutex.addr(), [mutex, order]()
|
||||
{
|
||||
return order == mutex->data.read_relaxed().m_rel;
|
||||
return order == mutex->release_count.read_relaxed();
|
||||
});
|
||||
|
||||
// prx: sync
|
||||
mutex->data.read_sync();
|
||||
mutex->sync_var.read_sync();
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -83,19 +79,16 @@ s32 cellSyncMutexTryLock(vm::ptr<CellSyncMutex> mutex)
|
||||
{
|
||||
return CELL_SYNC_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
if (mutex.addr() % 4)
|
||||
{
|
||||
return CELL_SYNC_ERROR_ALIGN;
|
||||
}
|
||||
|
||||
// prx: exit if m_acq and m_rel are not equal, increase m_acq
|
||||
return mutex->data.atomic_op(CELL_OK, [](CellSyncMutex::data_t& mutex) -> s32
|
||||
// prx: lock only if acquire_count and release_count are equal
|
||||
return mutex->sync_var.atomic_op(CELL_OK, [](CellSyncMutex::sync_t& mutex) -> s32
|
||||
{
|
||||
if (mutex.m_acq++ != mutex.m_rel)
|
||||
{
|
||||
return CELL_SYNC_ERROR_BUSY;
|
||||
}
|
||||
return CELL_OK;
|
||||
return (mutex.acquire_count++ != mutex.release_count) ? CELL_SYNC_ERROR_BUSY : CELL_OK;
|
||||
});
|
||||
}
|
||||
|
||||
@ -112,10 +105,8 @@ s32 cellSyncMutexUnlock(vm::ptr<CellSyncMutex> mutex)
|
||||
return CELL_SYNC_ERROR_ALIGN;
|
||||
}
|
||||
|
||||
mutex->data.atomic_op_sync([](CellSyncMutex::data_t& mutex)
|
||||
{
|
||||
mutex.m_rel++;
|
||||
});
|
||||
// prx: increase release count
|
||||
mutex->release_count++;
|
||||
|
||||
g_sync_mutex_wm.notify(mutex.addr());
|
||||
|
||||
|
@ -29,15 +29,21 @@ enum
|
||||
CELL_SYNC_ERROR_NO_SPU_CONTEXT_STORAGE = 0x80410114, // ???
|
||||
};
|
||||
|
||||
struct CellSyncMutex
|
||||
union CellSyncMutex
|
||||
{
|
||||
struct data_t
|
||||
struct sync_t
|
||||
{
|
||||
be_t<u16> m_rel; // release order (increased when mutex is unlocked)
|
||||
be_t<u16> m_acq; // acquire order (increased when mutex is locked)
|
||||
be_t<u16> release_count; // increased when mutex is unlocked
|
||||
be_t<u16> acquire_count; // increased when mutex is locked
|
||||
};
|
||||
|
||||
atomic_t<data_t> data;
|
||||
struct
|
||||
{
|
||||
atomic_t<u16> release_count;
|
||||
atomic_t<u16> acquire_count;
|
||||
};
|
||||
|
||||
atomic_t<sync_t> sync_var;
|
||||
};
|
||||
|
||||
static_assert(sizeof(CellSyncMutex) == 4, "CellSyncMutex: wrong size");
|
||||
|
Loading…
x
Reference in New Issue
Block a user