mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-23 03:02:53 +01:00
Update sys_lwmutex_lock and sys_lwmutex_unlock (liblv2 HLE)
Implement missing SYS_SYNC_RETRY logic Following #5680
This commit is contained in:
parent
986c750fdc
commit
4ea76def7c
@ -85,7 +85,7 @@ error_code sys_lwmutex_destroy(ppu_thread& ppu, vm::ptr<sys_lwmutex_t> lwmutex)
|
||||
}
|
||||
|
||||
// deleting succeeded
|
||||
lwmutex->vars.owner.exchange(lwmutex_dead);
|
||||
lwmutex->vars.owner.release(lwmutex_dead);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -184,8 +184,57 @@ error_code sys_lwmutex_lock(ppu_thread& ppu, vm::ptr<sys_lwmutex_t> lwmutex, u64
|
||||
|
||||
if (res == CELL_EBUSY && lwmutex->attribute & SYS_SYNC_RETRY)
|
||||
{
|
||||
// TODO (protocol is ignored in current implementation)
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
while (true)
|
||||
{
|
||||
for (u32 i = 0; i < 10; i++)
|
||||
{
|
||||
busy_wait();
|
||||
|
||||
if (lwmutex->vars.owner.load() == lwmutex_free)
|
||||
{
|
||||
if (lwmutex->vars.owner.compare_and_swap_test(lwmutex_free, tid))
|
||||
{
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lwmutex->all_info++;
|
||||
|
||||
if (lwmutex->vars.owner.compare_and_swap_test(lwmutex_free, tid))
|
||||
{
|
||||
lwmutex->all_info--;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
const u64 time0 = timeout ? get_system_time() : 0;
|
||||
|
||||
const error_code res_ = _sys_lwmutex_lock(ppu, lwmutex->sleep_queue, timeout);
|
||||
|
||||
if (res_ == CELL_OK)
|
||||
{
|
||||
lwmutex->vars.owner.release(tid);
|
||||
}
|
||||
else if (timeout && res_ != CELL_ETIMEDOUT)
|
||||
{
|
||||
const u64 time_diff = get_system_time() - time0;
|
||||
|
||||
if (timeout <= time_diff)
|
||||
{
|
||||
lwmutex->all_info--;
|
||||
return not_an_error(CELL_ETIMEDOUT);
|
||||
}
|
||||
|
||||
timeout -= time_diff;
|
||||
}
|
||||
|
||||
lwmutex->all_info--;
|
||||
|
||||
if (res_ != CELL_EBUSY)
|
||||
{
|
||||
return res_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
@ -297,11 +346,19 @@ error_code sys_lwmutex_unlock(ppu_thread& ppu, vm::ptr<sys_lwmutex_t> lwmutex)
|
||||
|
||||
if (lwmutex->attribute & SYS_SYNC_RETRY)
|
||||
{
|
||||
// TODO (protocol is ignored in current implementation)
|
||||
lwmutex->vars.owner.release(lwmutex_free);
|
||||
|
||||
// Call the alternative syscall
|
||||
if (_sys_lwmutex_unlock2(lwmutex->sleep_queue) == CELL_ESRCH)
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
// set special value
|
||||
lwmutex->vars.owner.exchange(lwmutex_reserved);
|
||||
lwmutex->vars.owner.release(lwmutex_reserved);
|
||||
|
||||
// call the syscall
|
||||
if (_sys_lwmutex_unlock(ppu, lwmutex->sleep_queue) == CELL_ESRCH)
|
||||
|
Loading…
Reference in New Issue
Block a user