private void onLwMutexDeleted(int lwmid) {
    ThreadManForUser threadMan = Modules.ThreadManForUserModule;
    boolean reschedule = false;

    for (Iterator<SceKernelThreadInfo> it = threadMan.iterator(); it.hasNext(); ) {
      SceKernelThreadInfo thread = it.next();
      if (thread.isWaitingForType(PSP_WAIT_LWMUTEX) && thread.wait.LwMutex_id == lwmid) {
        thread.cpuContext.gpr[2] = ERROR_KERNEL_WAIT_DELETE;
        threadMan.hleChangeThreadState(thread, PSP_THREAD_READY);
        reschedule = true;
      }
    }
    // Reschedule only if threads waked up.
    if (reschedule) {
      threadMan.hleRescheduleCurrentThread();
    }
  }
  private void onLwMutexModified(SceKernelLwMutexInfo info) {
    ThreadManForUser threadMan = Modules.ThreadManForUserModule;
    boolean reschedule = false;

    if ((info.attr & PSP_LWMUTEX_ATTR_PRIORITY) == PSP_LWMUTEX_ATTR_FIFO) {
      for (Iterator<SceKernelThreadInfo> it = Modules.ThreadManForUserModule.iterator();
          it.hasNext(); ) {
        SceKernelThreadInfo thread = it.next();
        if (thread.isWaitingForType(PSP_WAIT_LWMUTEX)
            && thread.wait.LwMutex_id == info.uid
            && tryLockLwMutex(info, thread.wait.LwMutex_count, thread)) {
          // New thread is taking control of LwMutex.
          info.threadid = thread.uid;
          // Update numWaitThreads
          info.numWaitThreads--;
          // Return success or failure
          thread.cpuContext.gpr[2] = 0;
          // Wakeup
          threadMan.hleChangeThreadState(thread, PSP_THREAD_READY);
          reschedule = true;
        }
      }
    } else if ((info.attr & PSP_LWMUTEX_ATTR_PRIORITY) == PSP_LWMUTEX_ATTR_PRIORITY) {
      for (Iterator<SceKernelThreadInfo> it = Modules.ThreadManForUserModule.iteratorByPriority();
          it.hasNext(); ) {
        SceKernelThreadInfo thread = it.next();
        if (thread.isWaitingForType(PSP_WAIT_LWMUTEX)
            && thread.wait.LwMutex_id == info.uid
            && tryLockLwMutex(info, thread.wait.LwMutex_count, thread)) {
          // New thread is taking control of LwMutex.
          info.threadid = thread.uid;
          // Update numWaitThreads
          info.numWaitThreads--;
          // Return success or failure
          thread.cpuContext.gpr[2] = 0;
          // Wakeup
          threadMan.hleChangeThreadState(thread, PSP_THREAD_READY);
          reschedule = true;
        }
      }
    }
    // Reschedule only if threads waked up.
    if (reschedule) {
      Modules.ThreadManForUserModule.hleRescheduleCurrentThread();
    }
  }
 public void onThreadDeleted(SceKernelThreadInfo thread) {
   if (thread.isWaitingForType(PSP_WAIT_LWMUTEX)) {
     // decrement numWaitThreads
     removeWaitingThread(thread);
   }
 }