private int hleKernelLockLwMutex( int uid, int count, int timeout_addr, boolean wait, boolean doCallbacks) { SceKernelLwMutexInfo info = lwMutexMap.get(uid); if (info == null) { log.warn( String.format( "hleKernelLockLwMutex uid=%d, count=%d, timeout_addr=0x%08X, wait=%b, doCallbacks=%b - - unknown UID", uid, count, timeout_addr, wait, doCallbacks)); return ERROR_KERNEL_LWMUTEX_NOT_FOUND; } ThreadManForUser threadMan = Modules.ThreadManForUserModule; SceKernelThreadInfo currentThread = threadMan.getCurrentThread(); if (!tryLockLwMutex(info, count, currentThread)) { if (log.isDebugEnabled()) { log.debug( String.format( "hleKernelLockLwMutex %s, count=%d, timeout_addr=0x%08X, wait=%b, doCallbacks=%b - fast check failed", info.toString(), count, timeout_addr, wait, doCallbacks)); } if (wait && info.threadid != currentThread.uid) { // Failed, but it's ok, just wait a little info.numWaitThreads++; // Wait on a specific lwmutex currentThread.wait.LwMutex_id = uid; currentThread.wait.LwMutex_count = count; threadMan.hleKernelThreadEnterWaitState( PSP_WAIT_LWMUTEX, uid, lwMutexWaitStateChecker, timeout_addr, doCallbacks); } else { if ((info.attr & PSP_LWMUTEX_ATTR_ALLOW_RECURSIVE) != PSP_LWMUTEX_ATTR_ALLOW_RECURSIVE) { return ERROR_KERNEL_LWMUTEX_RECURSIVE_NOT_ALLOWED; } return ERROR_KERNEL_LWMUTEX_LOCKED; } } else { // Success, do not reschedule the current thread. if (log.isDebugEnabled()) { log.debug( String.format( "hleKernelLockLwMutex %s, count=%d, timeout_addr=0x%08X, wait=%b, doCallbacks=%b - fast check succeeded", info.toString(), count, timeout_addr, wait, doCallbacks)); } } return 0; }