public virtual 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) { Console.WriteLine(string.Format("sceGeSetCallback no more callback ID available")); return(SceKernelErrors.ERROR_OUT_OF_MEMORY); } //if (log.DebugEnabled) { Console.WriteLine(string.Format("sceGeSetCallback signalFunc=0x{0:X8}, signalArg=0x{1:X8}, finishFunc=0x{2:X8}, finishArg=0x{3:X8}, result cbid=0x{4: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[cbid] = callbackSignal; finishCallbacks[cbid] = callbackFinish; return(cbid); }
protected internal virtual int hleCtrlReadBuffer(int addr, int count, bool positive) { if (count < 0 || count > SAMPLE_BUFFER_SIZE) { return(SceKernelErrors.ERROR_INVALID_SIZE); } // Some data available in sample buffer? if (NumberOfAvailableSamples > 0) { // Yes, read immediately return(hleCtrlReadBufferImmediately(addr, count, positive, false)); } // No, wait for next sampling ThreadManForUser threadMan = Modules.ThreadManForUserModule; SceKernelThreadInfo currentThread = threadMan.CurrentThread; ThreadWaitingForSampling threadWaitingForSampling = new ThreadWaitingForSampling(currentThread, addr, count, positive); threadsWaitingForSampling.Add(threadWaitingForSampling); threadMan.hleBlockCurrentThread(SceKernelThreadInfo.JPCSP_WAIT_CTRL); //if (log.DebugEnabled) { Console.WriteLine("hleCtrlReadBuffer waiting for sample"); } return(0); }
private int hleKernelAllocateFpl(int uid, TPointer32 dataAddr, TPointer32 timeoutAddr, bool wait, bool doCallbacks) { SceKernelFplInfo fpl = fplMap[uid]; int addr = tryAllocateFpl(fpl); ThreadManForUser threadMan = Modules.ThreadManForUserModule; if (addr == 0) { //if (log.DebugEnabled) { Console.WriteLine(string.Format("hleKernelAllocateFpl {0} fast check failed", fpl)); } if (!wait) { return(ERROR_KERNEL_WAIT_CAN_NOT_WAIT); } // Go to wait state SceKernelThreadInfo currentThread = threadMan.CurrentThread; fpl.threadWaitingList.addWaitingThread(currentThread); currentThread.wait.Fpl_id = uid; currentThread.wait.Fpl_dataAddr = dataAddr; threadMan.hleKernelThreadEnterWaitState(PSP_WAIT_FPL, uid, fplWaitStateChecker, timeoutAddr.Address, doCallbacks); } else { // Success, do not reschedule the current thread. //if (log.DebugEnabled) { Console.WriteLine(string.Format("hleKernelAllocateFpl {0} fast check succeeded", fpl)); } dataAddr.setValue(addr); } return(0); }
public virtual int sceUmdCancelWaitDriveStat() { ThreadManForUser threadMan = Modules.ThreadManForUserModule; //JAVA TO C# CONVERTER WARNING: Unlike Java's ListIterator, enumerators in .NET do not allow altering the collection: for (IEnumerator <SceKernelThreadInfo> lit = waitingThreads.GetEnumerator(); lit.MoveNext();) { SceKernelThreadInfo waitingThread = lit.Current; if (!waitingThread.Waiting || waitingThread.waitType != JPCSP_WAIT_UMD) { Console.WriteLine(string.Format("sceUmdCancelWaitDriveStat thread {0} not waiting on umd", waitingThread)); } else { //if (log.DebugEnabled) { Console.WriteLine(string.Format("sceUmdCancelWaitDriveStat waking thread {0}", waitingThread)); } lit.remove(); // Return WAIT_CANCELLED. waitingThread.cpuContext._v0 = ERROR_KERNEL_WAIT_CANCELLED; // Wakeup thread threadMan.hleChangeThreadState(waitingThread, SceKernelThreadInfo.PSP_THREAD_READY); } } return(0); }
public int sceKernelCreateLwMutex(SceLwMutexWorkarea* WorkAreaPointer, string Name, ThreadManForUser.MutexAttributesEnum Attributes, int InitialCount, int OptionAddress) { WorkAreaPointer->attr = Attributes; WorkAreaPointer->lockLevel = 0; //throw(new NotImplementedException()); return 0; }
public virtual int hleKernelWaitSema(SceKernelSemaInfo sema, int signal, TPointer32 timeoutAddr, bool doCallbacks) { if (!tryWaitSemaphore(sema, signal)) { // Failed, but it's ok, just wait a little //if (log.DebugEnabled) { Console.WriteLine(string.Format("hleKernelWaitSema {0} fast check failed", sema)); } ThreadManForUser threadMan = Modules.ThreadManForUserModule; SceKernelThreadInfo currentThread = threadMan.CurrentThread; sema.threadWaitingList.addWaitingThread(currentThread); // Wait on a specific semaphore currentThread.wait.Semaphore_id = sema.uid; currentThread.wait.Semaphore_signal = signal; threadMan.hleKernelThreadEnterWaitState(PSP_WAIT_SEMA, sema.uid, semaWaitStateChecker, timeoutAddr.Address, doCallbacks); } else { // Success, do not reschedule the current thread. //if (log.DebugEnabled) { Console.WriteLine(string.Format("hleKernelWaitSema {0} fast check succeeded", sema)); } } return(0); }
protected internal virtual void blockThreadInput(int addr, int samples, int frequency) { ThreadManForUser threadMan = Modules.ThreadManForUserModule; int threadId = threadMan.CurrentThreadID; threadMan.hleBlockCurrentThread(SceKernelThreadInfo.JPCSP_WAIT_AUDIO); blockThreadInput(threadId, addr, samples, frequency, hleAudioGetInputLength()); }
protected internal static void blockThreadOutput(SoundChannel channel, int addr, int leftVolume, int rightVolume) { ThreadManForUser threadMan = Modules.ThreadManForUserModule; blockThreadOutput(threadMan.CurrentThreadID, channel, addr, leftVolume, rightVolume); threadMan.hleBlockCurrentThread(SceKernelThreadInfo.JPCSP_WAIT_AUDIO); channel.Busy = true; }
public virtual int sceUmdRegisterUMDCallBack(int uid) { ThreadManForUser threadMan = Modules.ThreadManForUserModule; if (!threadMan.hleKernelRegisterCallback(SceKernelThreadInfo.THREAD_CALLBACK_UMD, uid)) { return(-1); } return(0); }
public virtual int sceNetApctlInit(int stackSize, int initPriority) { if (sceNetApctlThread == null) { ThreadManForUser threadMan = Modules.ThreadManForUserModule; sceNetApctlThread = threadMan.hleKernelCreateThread("SceNetApctl", ThreadManForUser.NET_APCTL_LOOP_ADDRESS, initPriority, stackSize, threadMan.CurrentThread.attr, 0, SysMemUserForUser.USER_PARTITION_ID); sceNetApctlThreadTerminate = false; threadMan.hleKernelStartThread(sceNetApctlThread, 0, 0, sceNetApctlThread.gpReg_addr); } return(0); }
public virtual int scePowerRegisterCallback(int slot, int uid) { bool notifyCallback = false; int result; // Multiple power callbacks (up to 16) can be assigned for multiple threads. if (slot == PSP_POWER_CB_SLOT_AUTO) { // Return ERROR_OUT_OF_MEMORY when no free slot found result = SceKernelErrors.ERROR_OUT_OF_MEMORY; for (int i = 0; i < powerCBSlots.Length; i++) { if (powerCBSlots[i] == 0) { powerCBSlots[i] = uid; result = i; notifyCallback = true; break; } } } else if (slot >= 0 && slot < powerCBSlots.Length) { if (powerCBSlots[slot] == 0) { powerCBSlots[slot] = uid; result = 0; notifyCallback = true; } else { result = SceKernelErrors.ERROR_ALREADY; } } else { result = -1; } if (notifyCallback) { ThreadManForUser threadMan = Modules.ThreadManForUserModule; if (threadMan.hleKernelRegisterCallback(SceKernelThreadInfo.THREAD_CALLBACK_POWER, uid)) { // Start by notifying the POWER callback that we're using AC power. threadMan.hleKernelNotifyCallback(SceKernelThreadInfo.THREAD_CALLBACK_POWER, uid, PSP_POWER_CB_AC_POWER); } } return(result); }
private int hleKernelReceiveMsgPipe(int uid, TPointer msgAddr, int size, int waitMode, TPointer32 resultSizeAddr, TPointer32 timeoutAddr, bool doCallbacks, bool poll) { SceKernelMppInfo info = msgMap[uid]; if (info.bufSize != 0 && size > info.bufSize) { Console.WriteLine(string.Format("hleKernelReceiveMsgPipe illegal size 0x{0:X}, max 0x{1:X}", size, info.bufSize)); return(ERROR_KERNEL_ILLEGAL_SIZE); } ThreadManForUser threadMan = Modules.ThreadManForUserModule; if (!tryReceiveMsgPipe(info, msgAddr, size, waitMode, resultSizeAddr)) { if (!poll) { // Failed, but it's ok, just wait a little //if (log.DebugEnabled) { Console.WriteLine(string.Format("hleKernelReceiveMsgPipe {0} waiting for 0x{1:X} bytes to become available", info, size)); } SceKernelThreadInfo currentThread = threadMan.CurrentThread; info.receiveThreadWaitingList.addWaitingThread(currentThread); // Wait on a specific MsgPipe. currentThread.wait.MsgPipe_isSend = false; currentThread.wait.MsgPipe_id = uid; currentThread.wait.MsgPipe_address = msgAddr; currentThread.wait.MsgPipe_size = size; currentThread.wait.MsgPipe_resultSize_addr = resultSizeAddr; threadMan.hleKernelThreadEnterWaitState(PSP_WAIT_MSGPIPE, uid, msgPipeReceiveWaitStateChecker, timeoutAddr.Address, doCallbacks); } else { //if (log.DebugEnabled) { Console.WriteLine(string.Format("hleKernelReceiveMsgPipe trying to read more than is available size 0x{0:X}, available 0x{1:X}", size, info.bufSize - info.freeSize)); } return(ERROR_KERNEL_MESSAGE_PIPE_EMPTY); } } else { // Success, do not reschedule the current thread. //if (log.DebugEnabled) { Console.WriteLine(string.Format("hleKernelReceiveMsgPipe {0} fast check succeeded", info)); } onMsgPipeSendModified(info); } return(0); }
public virtual int hleKernelWaitEventFlag(int uid, int bits, int wait, TPointer32 outBitsAddr, TPointer32 timeoutAddr, bool doCallbacks) { if ((wait & ~(PSP_EVENT_WAITOR | PSP_EVENT_WAITCLEAR | PSP_EVENT_WAITCLEARALL)) != 0 || (wait & (PSP_EVENT_WAITCLEAR | PSP_EVENT_WAITCLEARALL)) == (PSP_EVENT_WAITCLEAR | PSP_EVENT_WAITCLEARALL)) { return(ERROR_KERNEL_ILLEGAL_MODE); } if (bits == 0) { return(ERROR_KERNEL_EVENT_FLAG_ILLEGAL_WAIT_PATTERN); } if (!Modules.ThreadManForUserModule.DispatchThreadEnabled) { return(ERROR_KERNEL_WAIT_CAN_NOT_WAIT); } SceKernelEventFlagInfo @event = eventMap[uid]; if (@event.NumWaitThreads >= 1 && (@event.attr & PSP_EVENT_WAITMULTIPLE) != PSP_EVENT_WAITMULTIPLE) { Console.WriteLine("hleKernelWaitEventFlag already another thread waiting on it"); return(ERROR_KERNEL_EVENT_FLAG_NO_MULTI_PERM); } if (!checkEventFlag(@event, bits, wait, outBitsAddr)) { // Failed, but it's ok, just wait a little //if (log.DebugEnabled) { Console.WriteLine(string.Format("hleKernelWaitEventFlag - {0} fast check failed", @event)); } ThreadManForUser threadMan = Modules.ThreadManForUserModule; SceKernelThreadInfo currentThread = threadMan.CurrentThread; @event.threadWaitingList.addWaitingThread(currentThread); // Wait on a specific event flag currentThread.wait.EventFlag_id = uid; currentThread.wait.EventFlag_bits = bits; currentThread.wait.EventFlag_wait = wait; currentThread.wait.EventFlag_outBits_addr = outBitsAddr; threadMan.hleKernelThreadEnterWaitState(PSP_WAIT_EVENTFLAG, uid, eventFlagWaitStateChecker, timeoutAddr.Address, doCallbacks); } else { // Success, do not reschedule the current thread. //if (log.DebugEnabled) { Console.WriteLine(string.Format("hleKernelWaitEventFlag - {0} fast check succeeded", @event)); } } return(0); }
public virtual void step() { ThreadManForUser threadMan = Modules.ThreadManForUserModule; for (int?thid = deferredThreadWakeupQueue.poll(); thid != null; thid = deferredThreadWakeupQueue.poll()) { //if (log.DebugEnabled) { Console.WriteLine("really waking thread " + thid.ToString("x") + "(" + threadMan.getThreadName(thid.Value) + ")"); } threadMan.hleUnblockThread(thid); ExternalGE.onGeStopWaitList(); } }
public virtual int scePowerUnregisterCallback(int slot) { if (slot < 0 || slot >= powerCBSlots.Length) { return(-1); } if (powerCBSlots[slot] != 0) { ThreadManForUser threadMan = Modules.ThreadManForUserModule; threadMan.hleKernelUnRegisterCallback(SceKernelThreadInfo.THREAD_CALLBACK_POWER, powerCBSlots[slot]); powerCBSlots[slot] = 0; } return(0); }
protected internal virtual int hleUmdWaitDriveStat(int wantedStat, bool doCallbacks, bool doTimeout, int timeout) { ThreadManForUser threadMan = Modules.ThreadManForUserModule; if (!checkDriveStat(wantedStat)) { SceKernelThreadInfo currentThread = threadMan.CurrentThread; // Wait on a specific umdStat. currentThread.wait.wantedUmdStat = wantedStat; waitingThreads.Add(currentThread); threadMan.hleKernelThreadEnterWaitState(currentThread, JPCSP_WAIT_UMD, -1, umdWaitStateChecker, timeout, !doTimeout, doCallbacks); } threadMan.hleRescheduleCurrentThread(doCallbacks); return(0); }
public static void dumpThreads() { ThreadManForUser threadMan = Modules.ThreadManForUserModule; for (IEnumerator <SceKernelThreadInfo> it = threadMan.GetEnumerator(); it.MoveNext();) { SceKernelThreadInfo thread = it.Current; log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); log(string.Format("Thread Name: '{0}' ID: 0x{1:X4} Module ID: 0x{2:X4}", thread.name, thread.uid, thread.moduleid)); log(string.Format("Thread Status: 0x{0:X8} {1}", thread.status, thread.StatusName)); log(string.Format("Thread Attr: 0x{0:X8} Current Priority: 0x{1:X2} Initial Priority: 0x{2:X2}", thread.attr, thread.currentPriority, thread.initPriority)); log(string.Format("Thread Entry: 0x{0:X8} Stack: 0x{1:X8} - 0x{2:X8} Stack Size: 0x{3:X8}", thread.entry_addr, thread.StackAddr, thread.StackAddr + thread.stackSize, thread.stackSize)); log(string.Format("Thread Run Clocks: {0:D} Exit Code: 0x{1:X8}", thread.runClocks, thread.exitStatus)); log(string.Format("Thread Wait Type: {0} Us: {1:D} Forever: {2}", thread.WaitName, thread.wait.micros, thread.wait.forever)); } }
private void blockCurrentThreadOnList(PspGeList list, IAction action) { ThreadManForUser threadMan = Modules.ThreadManForUserModule; bool blockCurrentThread = false; bool executeAction = false; lock (this) { int currentThreadId = threadMan.CurrentThreadID; if (list.Done) { // There has been some race condition: the list has just completed // do not block the thread //if (log.DebugEnabled) { Console.WriteLine("blockCurrentThreadOnList not blocking thread " + currentThreadId.ToString("x") + ", list completed " + list); } executeAction = true; } else { //if (log.DebugEnabled) { Console.WriteLine("blockCurrentThreadOnList blocking thread " + currentThreadId.ToString("x") + " 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(); } }
public virtual 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 virtual int sceKernelSendMbx(int uid, TPointer msgAddr) { SceKernelMbxInfo info = mbxMap[uid]; bool msgConsumed = false; // If the Mbx is empty, check if some thread is already waiting. // If a thread is already waiting, do not update the msg "nextMsgPacketAddr" FieldInfo. if (!info.hasMessage()) { SceKernelThreadInfo thread = info.threadWaitingList.FirstWaitingThread; if (thread != null) { //if (log.DebugEnabled) { Console.WriteLine(string.Format("sceKernelSendMbx waking thread {0}", thread)); } thread.wait.Mbx_resultAddr.setValue(msgAddr.Address); info.threadWaitingList.removeWaitingThread(thread); thread.cpuContext._v0 = 0; ThreadManForUser threadMan = Modules.ThreadManForUserModule; threadMan.hleChangeThreadState(thread, PSP_THREAD_READY); threadMan.hleRescheduleCurrentThread(); msgConsumed = true; } } // Add the message if it has not yet been consumed by a waiting thread if (!msgConsumed) { if ((info.attr & PSP_MBX_ATTR_MSG_PRIORITY) == PSP_MBX_ATTR_MSG_FIFO) { info.addMsg(msgAddr.Memory, msgAddr.Address); } else if ((info.attr & PSP_MBX_ATTR_MSG_PRIORITY) == PSP_MBX_ATTR_MSG_PRIORITY) { info.addMsgByPriority(msgAddr.Memory, msgAddr.Address); } } return(0); }
private int hleKernelAllocateVpl(int uid, int size, TPointer32 dataAddr, TPointer32 timeoutAddr, bool wait, bool doCallbacks) { SceKernelVplInfo vpl = vplMap[uid]; if (size <= 0 || size > vpl.poolSize) { return(ERROR_KERNEL_ILLEGAL_MEMSIZE); } int addr = tryAllocateVpl(vpl, size); ThreadManForUser threadMan = Modules.ThreadManForUserModule; if (addr == 0) { //if (log.DebugEnabled) { Console.WriteLine(string.Format("hleKernelAllocateVpl {0} fast check failed", vpl)); } if (!wait) { return(ERROR_KERNEL_WAIT_CAN_NOT_WAIT); } // Go to wait state SceKernelThreadInfo currentThread = threadMan.CurrentThread; vpl.threadWaitingList.addWaitingThread(currentThread); // Wait on a specific fpl currentThread.wait.Vpl_id = uid; currentThread.wait.Vpl_size = size; currentThread.wait.Vpl_dataAddr = dataAddr; threadMan.hleKernelThreadEnterWaitState(PSP_WAIT_VPL, uid, vplWaitStateChecker, timeoutAddr.Address, doCallbacks); } else { // Success, do not reschedule the current thread. //if (log.DebugEnabled) { Console.WriteLine(string.Format("hleKernelAllocateVpl {0} fast check succeeded, allocated addr=0x{1:X8}", vpl, addr)); } dataAddr.setValue(addr); } return(0); }
private bool tryReceiveMsgPipe(SceKernelMppInfo info, TPointer addr, int size, int waitMode, TPointer32 resultSizeAddr) { if (size > 0) { int availableSize = info.availableReadSize(); if (availableSize == 0) { return(false); } // Trying to receive more than available? if (size > availableSize) { // Do we need to receive the complete size? if (waitMode == PSP_MPP_WAIT_MODE_COMPLETE) { return(false); } // We can just receive the available size. size = availableSize; } info.consume(addr.Memory, addr.Address, size); if (info.bufSize == 0 && info.availableReadSize() == 0 && info.NumSendWaitThreads > 0) { SceKernelThreadInfo thread = info.sendThreadWaitingList.FirstWaitingThread; if (thread.wait.MsgPipe_isSend) { //if (log.DebugEnabled) { Console.WriteLine(string.Format("tryReceiveMsgPipe waking thread {0}", thread)); } ThreadManForUser threadMan = Modules.ThreadManForUserModule; info.sendThreadWaitingList.removeWaitingThread(thread); thread.cpuContext._v0 = 0; threadMan.hleChangeThreadState(thread, PSP_THREAD_READY); threadMan.hleRescheduleCurrentThread(); } } } resultSizeAddr.setValue(size); return(true); }
public virtual int start(int evthPri, int evthStack, int inthPri, int inthStack, int optLen, int optData) { try { setHelloOpt(optLen, optData); openSocket(); ThreadManForUser threadMan = Modules.ThreadManForUserModule; if (eventThread == null) { eventThread = threadMan.hleKernelCreateThread("SceNetAdhocMatchingEvent", ThreadManForUser.NET_ADHOC_MATCHING_EVENT_LOOP_ADDRESS, evthPri, evthStack, threadMan.CurrentThread.attr, 0, SysMemUserForUser.USER_PARTITION_ID); threadMan.hleKernelStartThread(eventThread, 0, 0, eventThread.gpReg_addr); eventThread.cpuContext.setRegister(sceNetAdhocMatching.loopThreadRegisterArgument, Id); } if (inputThread == null) { inputThread = threadMan.hleKernelCreateThread("SceNetAdhocMatchingInput", ThreadManForUser.NET_ADHOC_MATCHING_INPUT_LOOP_ADDRESS, inthPri, inthStack, threadMan.CurrentThread.attr, 0, SysMemUserForUser.USER_PARTITION_ID); threadMan.hleKernelStartThread(inputThread, 0, 0, inputThread.gpReg_addr); inputThread.cpuContext.setRegister(sceNetAdhocMatching.loopThreadRegisterArgument, Id); } // Add myself as the first member addMember(Wlan.MacAddress); started = true; } catch (SocketException e) { Console.WriteLine("start", e); } catch (UnknownHostException e) { Console.WriteLine("start", e); } catch (IOException e) { Console.WriteLine("start", e); } return(0); }
private int hleKernelReceiveMbx(int uid, TPointer32 addrMsgAddr, TPointer32 timeoutAddr, bool doCallbacks, bool poll) { SceKernelMbxInfo info = mbxMap[uid]; ThreadManForUser threadMan = Modules.ThreadManForUserModule; if (!info.hasMessage()) { if (!poll) { //if (log.DebugEnabled) { Console.WriteLine(string.Format("hleKernelReceiveMbx - {0} (waiting)", info)); } SceKernelThreadInfo currentThread = threadMan.CurrentThread; info.threadWaitingList.addWaitingThread(currentThread); currentThread.wait.Mbx_id = uid; currentThread.wait.Mbx_resultAddr = addrMsgAddr; threadMan.hleKernelThreadEnterWaitState(PSP_WAIT_MBX, uid, mbxWaitStateChecker, timeoutAddr.Address, doCallbacks); } else { //if (log.DebugEnabled) { Console.WriteLine("hleKernelReceiveMbx has no messages."); } return(ERROR_KERNEL_MESSAGEBOX_NO_MESSAGE); } } else { // Success, do not reschedule the current thread. //if (log.DebugEnabled) { Console.WriteLine(string.Format("hleKernelReceiveMbx - {0} fast check succeeded", info)); } int msgAddr = info.removeMsg(Memory.Instance); addrMsgAddr.setValue(msgAddr); } return(0); }
private void onFplFree(SceKernelFplInfo info) { ThreadManForUser threadMan = Modules.ThreadManForUserModule; bool reschedule = false; SceKernelThreadInfo checkedThread = null; while (info.freeBlocks > 0) { SceKernelThreadInfo thread = info.threadWaitingList.getNextWaitingThread(checkedThread); if (thread == null) { break; } int addr = tryAllocateFpl(info); if (addr != 0) { //if (log.DebugEnabled) { Console.WriteLine(string.Format("onFplFree waking thread {0}", thread)); } // Return the allocated address thread.wait.Fpl_dataAddr.setValue(addr); info.threadWaitingList.removeWaitingThread(thread); thread.cpuContext._v0 = 0; threadMan.hleChangeThreadState(thread, PSP_THREAD_READY); reschedule = true; } else { checkedThread = thread; } } // Reschedule only if threads waked up. if (reschedule) { threadMan.hleRescheduleCurrentThread(); } }
private void onMbxDeletedCancelled(int mbxid, int result) { ThreadManForUser threadMan = Modules.ThreadManForUserModule; bool reschedule = false; for (IEnumerator <SceKernelThreadInfo> it = threadMan.GetEnumerator(); it.MoveNext();) { SceKernelThreadInfo thread = it.Current; if (thread.isWaitingFor(PSP_WAIT_MBX, mbxid)) { thread.cpuContext._v0 = result; threadMan.hleChangeThreadState(thread, PSP_THREAD_READY); reschedule = true; } } // Reschedule only if threads waked up. if (reschedule) { threadMan.hleRescheduleCurrentThread(); } }
private void onLwMutexDeleted(int lwmid) { ThreadManForUser threadMan = Modules.ThreadManForUserModule; bool reschedule = false; for (IEnumerator <SceKernelThreadInfo> it = threadMan.GetEnumerator(); it.MoveNext();) { SceKernelThreadInfo thread = it.Current; if (thread.isWaitingFor(PSP_WAIT_LWMUTEX, lwmid)) { thread.cpuContext._v0 = 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; bool reschedule = false; SceKernelThreadInfo checkedThread = null; while (true) { SceKernelThreadInfo thread = info.threadWaitingList.getNextWaitingThread(checkedThread); if (thread == null) { break; } if (tryLockLwMutex(info, thread.wait.LwMutex_count, thread)) { //if (log.DebugEnabled) { Console.WriteLine(string.Format("onLwMutexModified waking thread {0}", thread)); } // New thread is taking control of LwMutex. info.threadid = thread.uid; info.threadWaitingList.removeWaitingThread(thread); thread.cpuContext._v0 = 0; threadMan.hleChangeThreadState(thread, PSP_THREAD_READY); reschedule = true; } else { checkedThread = thread; } } // Reschedule only if threads waked up. if (reschedule) { Modules.ThreadManForUserModule.hleRescheduleCurrentThread(); } }
public virtual void hleAudioBlockingOutput(int threadId, SoundChannel channel, int addr, int leftVolume, int rightVolume) { //if (log.DebugEnabled) { Console.WriteLine(string.Format("hleAudioBlockingOutput {0}", channel.ToString())); } if (addr == 0) { // If another thread is also sending audio data on this channel, // do not wait for the channel to be drained, unblock the thread now. ThreadManForUser threadMan = Modules.ThreadManForUserModule; SceKernelThreadInfo thread = threadMan.getThreadById(threadId); if (thread != null) { thread.cpuContext._v0 = channel.SampleLength; threadMan.hleUnblockThread(threadId); } channel.Busy = false; } else if (!channel.OutputBlocking) { ThreadManForUser threadMan = Modules.ThreadManForUserModule; SceKernelThreadInfo thread = threadMan.getThreadById(threadId); if (thread != null) { changeChannelVolume(channel, leftVolume, rightVolume); int ret = doAudioOutput(channel, addr); thread.cpuContext._v0 = ret; threadMan.hleUnblockThread(threadId); } channel.Busy = false; } else { blockThreadOutput(threadId, channel, addr, leftVolume, rightVolume); } }
private void onMsgPipeReceiveModified(SceKernelMppInfo info) { ThreadManForUser threadMan = Modules.ThreadManForUserModule; bool reschedule = false; SceKernelThreadInfo checkedThread = null; while (true) { SceKernelThreadInfo thread = info.receiveThreadWaitingList.getNextWaitingThread(checkedThread); if (thread == null) { break; } if (!thread.wait.MsgPipe_isSend && tryReceiveMsgPipe(info, thread.wait.MsgPipe_address, thread.wait.MsgPipe_size, thread.wait.MsgPipe_waitMode, thread.wait.MsgPipe_resultSize_addr)) { //if (log.DebugEnabled) { Console.WriteLine(string.Format("onMsgPipeReceiveModified waking thread {0}", thread)); } info.receiveThreadWaitingList.removeWaitingThread(thread); thread.cpuContext._v0 = 0; threadMan.hleChangeThreadState(thread, PSP_THREAD_READY); reschedule = true; } else { checkedThread = thread; } } // Reschedule only if threads waked up. if (reschedule) { threadMan.hleRescheduleCurrentThread(); } }
private void onSemaphoreModified(SceKernelSemaInfo sema) { ThreadManForUser threadMan = Modules.ThreadManForUserModule; bool reschedule = false; SceKernelThreadInfo checkedThread = null; while (sema.currentCount > 0) { SceKernelThreadInfo thread = sema.threadWaitingList.getNextWaitingThread(checkedThread); if (thread == null) { break; } if (tryWaitSemaphore(sema, thread.wait.Semaphore_signal)) { //if (log.DebugEnabled) { Console.WriteLine(string.Format("onSemaphoreModified waking thread {0}", thread)); } sema.threadWaitingList.removeWaitingThread(thread); thread.cpuContext._v0 = 0; threadMan.hleChangeThreadState(thread, PSP_THREAD_READY); reschedule = true; } else { checkedThread = thread; } } // Reschedule only if threads waked up. if (reschedule) { threadMan.hleRescheduleCurrentThread(); } }