mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-10 08:51:28 +12:00
cellSync: global mutex avoided
cellAudio: level bug fixed
This commit is contained in:
parent
b6d8f1e028
commit
1e02598903
7 changed files with 450 additions and 422 deletions
|
@ -25,11 +25,13 @@ enum
|
|||
|
||||
#pragma pack(push, 1)
|
||||
struct CellSyncMutex {
|
||||
be_t<u16> m_freed;
|
||||
be_t<u16> m_order;
|
||||
volatile u32& m_data(){
|
||||
return *reinterpret_cast<u32*>(this);
|
||||
};
|
||||
be_t<u16> m_freed;
|
||||
be_t<u16> m_order;
|
||||
|
||||
volatile u32& m_data()
|
||||
{
|
||||
return *reinterpret_cast<u32*>(this);
|
||||
};
|
||||
/*
|
||||
(???) Initialize: set zeros
|
||||
(???) Lock: increase m_order and wait until m_freed == old m_order
|
||||
|
@ -52,16 +54,8 @@ int cellSyncMutexInitialize(mem_ptr_t<CellSyncMutex> mutex)
|
|||
return CELL_SYNC_ERROR_ALIGN;
|
||||
}
|
||||
|
||||
{
|
||||
SMutexLocker lock(reservation.mutex);
|
||||
if ((reservation.addr + reservation.size > mutex.GetAddr() && reservation.addr <= mutex.GetAddr() + 4) ||
|
||||
(mutex.GetAddr() + 4 > reservation.addr && mutex.GetAddr() <= reservation.addr + reservation.size))
|
||||
{
|
||||
reservation.clear();
|
||||
}
|
||||
mutex->m_data() = 0;
|
||||
return CELL_OK;
|
||||
}
|
||||
mutex->m_data() = 0;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSyncMutexLock(mem_ptr_t<CellSyncMutex> mutex)
|
||||
|
@ -78,22 +72,18 @@ int cellSyncMutexLock(mem_ptr_t<CellSyncMutex> mutex)
|
|||
}
|
||||
|
||||
be_t<u16> old_order;
|
||||
while (true)
|
||||
{
|
||||
SMutexLocker lock(reservation.mutex);
|
||||
if ((reservation.addr + reservation.size > mutex.GetAddr() && reservation.addr <= mutex.GetAddr() + 4) ||
|
||||
(mutex.GetAddr() + 4 > reservation.addr && mutex.GetAddr() <= reservation.addr + reservation.size))
|
||||
{
|
||||
reservation.clear();
|
||||
}
|
||||
old_order = mutex->m_order;
|
||||
mutex->m_order = mutex->m_order + 1;
|
||||
if (old_order == mutex->m_freed)
|
||||
{
|
||||
return CELL_OK;
|
||||
}
|
||||
const u32 old_data = mutex->m_data();
|
||||
CellSyncMutex new_mutex;
|
||||
new_mutex.m_data() = old_data;
|
||||
|
||||
old_order = new_mutex.m_order;
|
||||
new_mutex.m_order++;
|
||||
if (InterlockedCompareExchange(&mutex->m_data(), new_mutex.m_data(), old_data) == old_data) break;
|
||||
}
|
||||
|
||||
while (old_order != Memory.Read16(mutex.GetAddr()))
|
||||
while (old_order != mutex->m_freed)
|
||||
{
|
||||
Sleep(1);
|
||||
if (Emu.IsStopped())
|
||||
|
@ -118,20 +108,28 @@ int cellSyncMutexTryLock(mem_ptr_t<CellSyncMutex> mutex)
|
|||
{
|
||||
return CELL_SYNC_ERROR_ALIGN;
|
||||
}
|
||||
|
||||
int res;
|
||||
|
||||
while (true)
|
||||
{
|
||||
SMutexLocker lock(reservation.mutex);
|
||||
if ((reservation.addr + reservation.size > mutex.GetAddr() && reservation.addr <= mutex.GetAddr() + 4) ||
|
||||
(mutex.GetAddr() + 4 > reservation.addr && mutex.GetAddr() <= reservation.addr + reservation.size))
|
||||
const u32 old_data = mutex->m_data();
|
||||
CellSyncMutex new_mutex;
|
||||
new_mutex.m_data() = old_data;
|
||||
|
||||
if (new_mutex.m_order != new_mutex.m_freed)
|
||||
{
|
||||
reservation.clear();
|
||||
res = CELL_SYNC_ERROR_BUSY;
|
||||
}
|
||||
if (mutex->m_order != mutex->m_freed)
|
||||
else
|
||||
{
|
||||
return CELL_SYNC_ERROR_BUSY;
|
||||
new_mutex.m_order++;
|
||||
res = CELL_OK;
|
||||
}
|
||||
mutex->m_order = mutex->m_order + 1;
|
||||
return CELL_OK;
|
||||
if (InterlockedCompareExchange(&mutex->m_data(), new_mutex.m_data(), old_data) == old_data) break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int cellSyncMutexUnlock(mem_ptr_t<CellSyncMutex> mutex)
|
||||
|
@ -147,16 +145,17 @@ int cellSyncMutexUnlock(mem_ptr_t<CellSyncMutex> mutex)
|
|||
return CELL_SYNC_ERROR_ALIGN;
|
||||
}
|
||||
|
||||
{ /* global mutex */
|
||||
SMutexLocker lock(reservation.mutex);
|
||||
if ((reservation.addr + reservation.size > mutex.GetAddr() && reservation.addr <= mutex.GetAddr() + 4) ||
|
||||
(mutex.GetAddr() + 4 > reservation.addr && mutex.GetAddr() <= reservation.addr + reservation.size))
|
||||
{
|
||||
reservation.clear();
|
||||
}
|
||||
mutex->m_freed = mutex->m_freed + 1;
|
||||
return CELL_OK;
|
||||
while (true)
|
||||
{
|
||||
const u32 old_data = mutex->m_data();
|
||||
CellSyncMutex new_mutex;
|
||||
new_mutex.m_data() = old_data;
|
||||
|
||||
new_mutex.m_freed++;
|
||||
if (InterlockedCompareExchange(&mutex->m_data(), new_mutex.m_data(), old_data) == old_data) break;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
void cellSync_init()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue