@HLEFunction(nid = 0xA4FC06A4, version = 150, checkInsideInterrupt = true) public int sceGeSetCallback(TPointer cbdata_addr) { pspGeCallbackData cbdata = new pspGeCallbackData(); cbdata.read(cbdata_addr); // The cbid returned has a value in the range [0..15]. int cbid = SceUidManager.getNewId(geCallbackPurpose, 0, 15); if (cbid == SceUidManager.INVALID_ID) { log.warn(String.format("sceGeSetCallback no more callback ID available")); return SceKernelErrors.ERROR_OUT_OF_MEMORY; } if (log.isDebugEnabled()) { log.debug( String.format( "sceGeSetCallback signalFunc=0x%08X, signalArg=0x%08X, finishFunc=0x%08X, finishArg=0x%08X, result cbid=0x%X", cbdata.signalFunction, cbdata.signalArgument, cbdata.finishFunction, cbdata.finishArgument, cbid)); } ThreadManForUser threadMan = Modules.ThreadManForUserModule; SceKernelCallbackInfo callbackSignal = threadMan.hleKernelCreateCallback( "GeCallbackSignal", cbdata.signalFunction, cbdata.signalArgument); SceKernelCallbackInfo callbackFinish = threadMan.hleKernelCreateCallback( "GeCallbackFinish", cbdata.finishFunction, cbdata.finishArgument); signalCallbacks.put(cbid, callbackSignal); finishCallbacks.put(cbid, callbackFinish); return cbid; }
private void blockCurrentThreadOnList(PspGeList list, IAction action) { ThreadManForUser threadMan = Modules.ThreadManForUserModule; boolean blockCurrentThread = false; boolean executeAction = false; synchronized (this) { int currentThreadId = threadMan.getCurrentThreadID(); if (list.isDone()) { // There has been some race condition: the list has just completed // do not block the thread if (log.isDebugEnabled()) { log.debug( "blockCurrentThreadOnList not blocking thread " + Integer.toHexString(currentThreadId) + ", list completed " + list); } executeAction = true; } else { if (log.isDebugEnabled()) { log.debug( "blockCurrentThreadOnList blocking thread " + Integer.toHexString(currentThreadId) + " on list " + list); } list.blockedThreadIds.add(currentThreadId); blockCurrentThread = true; } } // Execute the action outside of the synchronized block if (executeAction && action != null) { action.execute(); } // Block the thread outside of the synchronized block if (blockCurrentThread) { // Block the thread, but do not execute callbacks. threadMan.hleBlockCurrentThread( SceKernelThreadInfo.JPCSP_WAIT_GE_LIST, list.id, false, action, new ListSyncWaitStateChecker(list)); ExternalGE.onGeStartWaitList(); } }
@HLEFunction(nid = 0x05DB22CE, version = 150, checkInsideInterrupt = true) public int sceGeUnsetCallback(int cbid) { ThreadManForUser threadMan = Modules.ThreadManForUserModule; SceKernelCallbackInfo callbackSignal = signalCallbacks.remove(cbid); SceKernelCallbackInfo callbackFinish = finishCallbacks.remove(cbid); if (callbackSignal != null) { threadMan.hleKernelDeleteCallback(callbackSignal.uid); } if (callbackFinish != null) { threadMan.hleKernelDeleteCallback(callbackFinish.uid); } SceUidManager.releaseId(cbid, geCallbackPurpose); return 0; }
public void step() { ThreadManForUser threadMan = Modules.ThreadManForUserModule; for (Integer thid = deferredThreadWakeupQueue.poll(); thid != null; thid = deferredThreadWakeupQueue.poll()) { if (log.isDebugEnabled()) { log.debug( "really waking thread " + Integer.toHexString(thid) + "(" + threadMan.getThreadName(thid) + ")"); } threadMan.hleUnblockThread(thid); ExternalGE.onGeStopWaitList(); } }