public int sceKernelCreateLwMutex(
      int workAreaAddr, int name_addr, int attr, int count, int option_addr) {
    Memory mem = Processor.memory;

    String name = Utilities.readStringNZ(mem, name_addr, 32);

    if (log.isDebugEnabled()) {
      log.debug(
          "sceKernelCreateLwMutex (workAreaAddr='"
              + Integer.toHexString(workAreaAddr)
              + "', name='"
              + name
              + "', attr=0x"
              + Integer.toHexString(attr)
              + ", count=0x"
              + Integer.toHexString(count)
              + ", option_addr=0x"
              + Integer.toHexString(option_addr)
              + ")");
    }

    SceKernelLwMutexInfo info = new SceKernelLwMutexInfo(workAreaAddr, name, count, attr);
    lwMutexMap.put(info.uid, info);

    // If the initial count is 0, the lwmutex is not acquired.
    if (count > 0) {
      info.threadid = Modules.ThreadManForUserModule.getCurrentThreadID();
    }

    // Return 0 in case of no error, do not return the UID of the created mutex
    return 0;
  }
  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();
    }
  }
예제 #3
0
  @HLEFunction(nid = 0xB287BD61, version = 150)
  public int sceGeDrawSync(@CheckArgument("checkMode") int mode) {
    if (mode == 0 && IntrManager.getInstance().isInsideInterrupt()) {
      log.debug("sceGeDrawSync (mode==0) cannot be called inside an interrupt handler!");
      return SceKernelErrors.ERROR_KERNEL_CANNOT_BE_CALLED_FROM_INTERRUPT;
    }

    // no synchronization on "this" required because we are not accessing
    // local data, only list information from the VideoEngine.
    int result = 0;
    if (mode == 0) {
      PspGeList lastList;
      if (ExternalGE.isActive()) {
        lastList = ExternalGE.getLastDrawList();
      } else {
        lastList = VideoEngine.getInstance().getLastDrawList();
      }

      if (lastList != null) {
        blockCurrentThreadOnList(lastList, new HLEAfterDrawSyncAction());
      } else {
        if (log.isDebugEnabled()) {
          log.debug("sceGeDrawSync all lists completed, not waiting");
        }
        hleGeAfterDrawSyncAction();
        Modules.ThreadManForUserModule.hleRescheduleCurrentThread();
      }
    } else if (mode == 1) {
      PspGeList currentList;
      if (ExternalGE.isActive()) {
        currentList = ExternalGE.getFirstDrawList();
      } else {
        currentList = VideoEngine.getInstance().getFirstDrawList();
      }
      if (currentList != null) {
        result = currentList.status;
      }
      if (log.isDebugEnabled()) {
        log.debug(String.format("sceGeDrawSync mode=%d, returning %d", mode, result));
      }
    }

    return result;
  }
예제 #4
0
  @HLEFunction(nid = 0x0C116E1B, version = 620)
  public int sceAtracLowLevelDecode(
      @CheckArgument("checkAtracID") int atID,
      TPointer sourceAddr,
      TPointer32 sourceBytesConsumedAddr,
      TPointer samplesAddr,
      TPointer32 sampleBytesAddr) {
    AtracID id = atracIDs[atID];
    ICodec codec = id.getCodec();

    if (log.isTraceEnabled()) {
      log.trace(
          String.format(
              "sceAtracLowLevelDecode input:%s",
              Utilities.getMemoryDump(sourceAddr.getAddress(), id.getSourceBufferLength())));
    }

    int sourceBytesConsumed = 0;
    int bytesPerSample = id.getOutputChannels() << 1;
    int result =
        codec.decode(sourceAddr.getAddress(), id.getSourceBufferLength(), samplesAddr.getAddress());
    if (log.isDebugEnabled()) {
      log.debug(String.format("sceAtracLowLevelDecode codec returned 0x%08X", result));
    }
    if (result < 0) {
      log.info(String.format("sceAtracLowLevelDecode codec returning 0x%08X", result));
      return result;
    }
    sourceBytesConsumed = result > 0 ? id.getSourceBufferLength() : 0;
    sampleBytesAddr.setValue(codec.getNumberOfSamples() * bytesPerSample);

    // Consume a part of the Atrac3 source buffer
    sourceBytesConsumedAddr.setValue(sourceBytesConsumed);

    Modules.ThreadManForUserModule.hleKernelDelayThread(atracDecodeDelay, false);

    return 0;
  }