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(); } }
@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; }
@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; }