int sceKernelUnlockLwMutex(u32 workareaPtr, int count) { VERBOSE_LOG(HLE, "sceKernelUnlockLwMutex(%08x, %i)", workareaPtr, count); auto workarea = Memory::GetStruct<NativeLwMutexWorkarea>(workareaPtr); if (workarea->uid == -1) return PSP_LWMUTEX_ERROR_NO_SUCH_LWMUTEX; else if (count <= 0) return SCE_KERNEL_ERROR_ILLEGAL_COUNT; else if ((workarea->attr & PSP_MUTEX_ATTR_ALLOW_RECURSIVE) == 0 && count > 1) return SCE_KERNEL_ERROR_ILLEGAL_COUNT; else if (workarea->lockLevel == 0 || workarea->lockThread != __KernelGetCurThread()) return PSP_LWMUTEX_ERROR_NOT_LOCKED; else if (workarea->lockLevel < count) return PSP_LWMUTEX_ERROR_UNLOCK_UNDERFLOW; workarea->lockLevel -= count; if (workarea->lockLevel == 0) { u32 error; if (__KernelUnlockLwMutex(workarea, error)) hleReSchedule("lwmutex unlocked"); } return 0; }
void sceKernelUnlockLwMutex(u32 workareaPtr, int count) { DEBUG_LOG(HLE,"sceKernelUnlockLwMutex(%08x, %i)", workareaPtr, count); NativeLwMutexWorkarea workarea; Memory::ReadStruct(workareaPtr, &workarea); u32 error = 0; if (workarea.uid == -1) error = PSP_LWMUTEX_ERROR_NO_SUCH_LWMUTEX; else if (count <= 0) error = SCE_KERNEL_ERROR_ILLEGAL_COUNT; else if ((workarea.attr & PSP_MUTEX_ATTR_ALLOW_RECURSIVE) == 0 && count > 1) error = SCE_KERNEL_ERROR_ILLEGAL_COUNT; else if (workarea.lockLevel == 0 || workarea.lockThread != __KernelGetCurThread()) error = PSP_LWMUTEX_ERROR_NOT_LOCKED; else if (workarea.lockLevel < count) error = PSP_LWMUTEX_ERROR_UNLOCK_UNDERFLOW; if (error) { RETURN(error); return; } workarea.lockLevel -= count; RETURN(0); if (workarea.lockLevel == 0) { __KernelUnlockLwMutex(workarea, error); Memory::WriteStruct(workareaPtr, &workarea); __KernelReSchedule("mutex unlocked"); } else Memory::WriteStruct(workareaPtr, &workarea); }