public ThreadWaitingForSampling(SceKernelThreadInfo thread, int readAddr, int readCount, bool readPositive) { this.thread = thread; this.readAddr = readAddr; this.readCount = readCount; this.readPositive = readPositive; }
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); }
public AfterAddDrvController(SceKernelThreadInfo thread, int sceIoAddDrv, int storageDrvAddr, int partitionDrvAddr) { this.thread = thread; this.sceIoAddDrv = sceIoAddDrv; this.storageDrvAddr = storageDrvAddr; this.partitionDrvAddr = partitionDrvAddr; }
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); }
// For Pdp sockets, data is read one packet at a time. // The caller has to provide enough space to fully read the available packet. public virtual int recv(TPointer srcMacAddr, TPointer16 portAddr, TPointer data, TPointer32 dataLengthAddr, int timeout, int nonblock) { int result = 0; try { SceKernelThreadInfo thread = Modules.ThreadManForUserModule.CurrentThread; if (pollRecv(srcMacAddr, portAddr, data, dataLengthAddr, thread)) { // Recv completed immediately result = thread.cpuContext._v0; } else if (nonblock != 0) { // Recv cannot be completed in non-blocking mode result = SceKernelErrors.ERROR_NET_ADHOC_NO_DATA_AVAILABLE; } else { // Block current thread BlockedPdpAction blockedPdpAction = new BlockedPdpRecv(this, srcMacAddr, portAddr, data, dataLengthAddr, timeout); blockedPdpAction.blockCurrentThread(); } } catch (IOException e) { result = SceKernelErrors.ERROR_NET_ADHOC_DISCONNECTED; Console.WriteLine("recv", e); } return(result); }
protected internal virtual void checkWaitingThreads() { //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.status == SceKernelThreadInfo.PSP_THREAD_WAITING) { int wantedUmdStat = waitingThread.wait.wantedUmdStat; if (waitingThread.waitType == JPCSP_WAIT_UMD && checkDriveStat(wantedUmdStat)) { //if (log.DebugEnabled) { Console.WriteLine("sceUmdUser - checkWaitingThreads waking " + waitingThread.uid.ToString("x") + " thread:'" + waitingThread.name + "'"); } //JAVA TO C# CONVERTER TODO TASK: .NET enumerators are read-only: lit.remove(); // Return success waitingThread.cpuContext._v0 = 0; // Wakeup thread Modules.ThreadManForUserModule.hleChangeThreadState(waitingThread, SceKernelThreadInfo.PSP_THREAD_READY); } } } }
public virtual int sceUmdActivate(int mode, PspString drive) { umdActivated = true; Modules.IoFileMgrForUserModule.registerUmdIso(); // Notify the callback. // The callback will be executed at the next sceXXXXCB() syscall. int notifyArg = NotificationArg; Modules.ThreadManForUserModule.hleKernelNotifyCallback(SceKernelThreadInfo.THREAD_CALLBACK_UMD, notifyArg); checkWaitingThreads(); // int arg[] = { 1 }; // sceIoAssign(drive, "umd0:", "isofs0:", 1, &arg, 4); int sceIoAssign = NIDMapper.Instance.getAddressByName("sceIoAssign"); if (sceIoAssign != 0) { SysMemInfo memInfo = Modules.SysMemUserForUserModule.malloc(SysMemUserForUser.KERNEL_PARTITION_ID, "sceUmdActivate", SysMemUserForUser.PSP_SMEM_Low, 32, 0); int argAddr = memInfo.addr; int umdAddr = memInfo.addr + 4; int isofsAddr = memInfo.addr + 10; Memory mem = Memory.Instance; Utilities.writeStringZ(mem, umdAddr, "umd0:"); Utilities.writeStringZ(mem, isofsAddr, "isofs0:"); mem.write32(argAddr, 1); SceKernelThreadInfo thread = Modules.ThreadManForUserModule.CurrentThread; Modules.ThreadManForUserModule.executeCallback(thread, sceIoAssign, null, false, drive.Address, umdAddr, isofsAddr, 1, argAddr, 4); } return(0); }
public virtual void onThreadDeleted(SceKernelThreadInfo thread) { if (thread.waitType == JPCSP_WAIT_UMD) { removeWaitingThread(thread); } }
public virtual void onThreadWaitReleased(SceKernelThreadInfo thread) { Console.WriteLine("UMD stat released"); removeWaitingThread(thread); // Return ERROR_WAIT_STATUS_RELEASED thread.cpuContext._v0 = ERROR_KERNEL_WAIT_STATUS_RELEASED; }
public virtual void onThreadWaitTimeout(SceKernelThreadInfo thread) { Console.WriteLine("UMD stat timedout"); removeWaitingThread(thread); // Return WAIT_TIMEOUT thread.cpuContext._v0 = ERROR_KERNEL_WAIT_TIMEOUT; }
public int sceKernelReferThreadStatus(int ThreadId, out SceKernelThreadInfo SceKernelThreadInfo) { var Thread = GetThreadById(ThreadId); SceKernelThreadInfo = Thread.Info; return(0); }
public virtual SceKernelThreadInfo getNextWaitingThread(SceKernelThreadInfo baseThread) { if (baseThread == null) { return(FirstWaitingThread); } int index = waitingThreads.IndexOf(baseThread.uid); if (index < 0 || (index + 1) >= NumWaitingThreads) { return(null); } int uid = waitingThreads[index + 1]; SceKernelThreadInfo thread = Modules.ThreadManForUserModule.getThreadById(uid); // Is the thread still existing if (thread == null) { // Thread is no longer existing, delete it from the waiting list and retry waitingThreads.RemoveAt(index + 1); return(getNextWaitingThread(baseThread)); } // Is the thread still waiting on this ID? if (!thread.isWaitingForType(waitType) || thread.waitId != waitId) { // The thread is no longer waiting on this object, remove it from the waiting list and retry waitingThreads.RemoveAt(index + 1); return(getNextWaitingThread(baseThread)); } return(thread); }
public virtual bool continueWaitState(SceKernelThreadInfo thread, ThreadWaitInfo wait) { // Check if the thread has to continue its wait state or if the fpl // has been allocated during the callback execution. SceKernelFplInfo fpl = outerInstance.fplMap[wait.Fpl_id]; if (fpl == null) { thread.cpuContext._v0 = ERROR_KERNEL_NOT_FOUND_FPOOL; return(false); } // Check fpl. int addr = outerInstance.tryAllocateFpl(fpl); if (addr != 0) { fpl.threadWaitingList.removeWaitingThread(thread); thread.wait.Fpl_dataAddr.setValue(addr); thread.cpuContext._v0 = 0; return(false); } return(true); }
public virtual void onThreadDeleted(SceKernelThreadInfo thread) { if (thread.isWaitingForType(PSP_WAIT_MBX)) { removeWaitingThread(thread); } }
public override void addWaitingThread(SceKernelThreadInfo thread) { bool added = false; if (waitingThreads.Count > 0) { //JAVA TO C# CONVERTER WARNING: Unlike Java's ListIterator, enumerators in .NET do not allow altering the collection: for (IEnumerator <int> lit = waitingThreads.GetEnumerator(); lit.MoveNext();) { int uid = lit.Current.intValue(); SceKernelThreadInfo waitingThread = Modules.ThreadManForUserModule.getThreadById(uid); if (waitingThread != null) { if (thread.currentPriority < waitingThread.currentPriority) { lit.previous(); lit.add(thread.uid); added = true; break; } } } } if (!added) { waitingThreads.Add(thread.uid); } }
public virtual bool continueWaitState(SceKernelThreadInfo thread, ThreadWaitInfo wait) { // Check if the thread has to continue its wait state or if the mbx // has received a new message during the callback execution. SceKernelMbxInfo info = outerInstance.mbxMap[wait.Mbx_id]; if (info == null) { thread.cpuContext._v0 = ERROR_KERNEL_NOT_FOUND_MESSAGE_BOX; return(false); } // Check the mbx for a new message. if (info.hasMessage()) { Memory mem = Memory.Instance; int msgAddr = info.removeMsg(mem); wait.Mbx_resultAddr.setValue(msgAddr); info.threadWaitingList.removeWaitingThread(thread); thread.cpuContext._v0 = 0; return(false); } return(true); }
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); }
public virtual void onThreadDeleted(SceKernelThreadInfo thread) { if (thread.isWaitingForType(PSP_WAIT_LWMUTEX)) { // decrement numWaitThreads removeWaitingThread(thread); } }
public override void stop() { sceNetApctlThread = null; sceNetApctlThreadTerminate = false; doScan = false; apctlHandlers.Clear(); base.stop(); }
protected internal virtual void triggerHandler(int oldState, int newState, int @event, int error) { SceKernelThreadInfo thread = Modules.ThreadManForUserModule.CurrentThread; if (thread != null) { Modules.ThreadManForUserModule.executeCallback(thread, addr, null, true, oldState, newState, @event, error, pArg); } }
protected internal virtual void hleAfterReadContextCallback() { if (readMessage == null) { int size = 256; int mem = Modules.sceNetIfhandleModule.hleNetMallocInternal(size); if (mem > 0) { readMessage = new TPointer(Memory.Instance, mem); readMessage.clear(size); RuntimeContext.debugMemory(mem, size); } } if (readMessage != null) { // Store dummy message SceNetIfMessage message = new SceNetIfMessage(); TPointer data = new TPointer(Memory.Instance, readMessage.Address + message.@sizeof()); TPointer header = new TPointer(data.Memory, data.Address); TPointer content = new TPointer(data.Memory, data.Address + 60); const int contentLength = 8; // Header information: header.setArray(0, Wlan.MacAddress, 6); // destination MAC address header.setArray(6, new sbyte[] { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 }, 6); // source MAC address header.setValue8(48, (sbyte)1); // 1 or 2 header.setValue8(49, (sbyte)0); header.setValue16(50, (short)endianSwap16(12 + contentLength)); // value must be >= 12 header.setValue16(52, (short)endianSwap16(0x22C)); // source port header.setValue16(54, (short)endianSwap16(0x22C)); // destination port header.setValue8(58, (sbyte)0); header.setValue8(59, (sbyte)0); // Real message content: content.setValue8(0, (sbyte)1); content.setValue8(1, (sbyte)1); content.setValue16(2, (short)endianSwap16(contentLength - 4)); // endian-swapped value, Length of following data content.setValue8(4, (sbyte)0); // Dummy data content.setValue8(5, (sbyte)0); content.setValue8(6, (sbyte)0); content.setValue8(7, (sbyte)0); message.dataAddr = data.Address; message.dataLength = 60 + contentLength; message.unknown24 = 60 + contentLength; message.write(readMessage); TPointer readContext = new TPointer(Memory.Instance, readContextAddr.getValue()); readContext.setValue32(0, readMessage.Address); readContext.setValue32(8, readContext.getValue32(8) + 1); } SceKernelThreadInfo thread = Modules.ThreadManForUserModule.CurrentThread; Modules.ThreadManForUserModule.executeCallback(thread, readCallback, null, true); }
public BlockedPdpAction(PdpObject pdpObject, long timeout) { this.pdpObject = pdpObject; timeoutMicros = Emulator.Clock.microTime() + timeout; threadUid = Modules.ThreadManForUserModule.CurrentThreadID; thread = Modules.ThreadManForUserModule.getThreadById(threadUid); //if (log.DebugEnabled) { Console.WriteLine(string.Format("BlockedPdpAction for thread {0}", thread)); } }
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); }
/// <summary> /// Call this to switch in the callback, in a given thread context. /// </summary> public override void call(SceKernelThreadInfo thread, IAction afterAction) { setArgument(0, notifyCount); setArgument(1, notifyArg); setArgument(2, callbackArgument); // clear the counter and the arg notifyCount = 0; notifyArg = 0; base.call(thread, afterAction); }
public virtual bool continueWaitState(SceKernelThreadInfo thread, ThreadWaitInfo wait) { // Continue the wait state until the list is done bool contineWait = !list.Done; if (!contineWait) { ExternalGE.onGeStopWaitList(); } return(contineWait); }
public virtual void onThreadWaitTimeout(SceKernelThreadInfo thread) { if (removeWaitingThread(thread)) { thread.cpuContext._v0 = ERROR_KERNEL_WAIT_TIMEOUT; } else { Console.WriteLine("Mbx deleted while we were waiting for it! (timeout expired)"); thread.cpuContext._v0 = ERROR_KERNEL_WAIT_DELETE; } }
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); }
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); }
private bool removeWaitingThread(SceKernelThreadInfo thread) { SceKernelMbxInfo info = mbxMap[thread.wait.Mbx_id]; if (info == null) { return(false); } info.threadWaitingList.removeWaitingThread(thread); return(true); }
public int sceKernelReferThreadStatus(int ThreadId, out SceKernelThreadInfo SceKernelThreadInfo) { var Thread = GetThreadById(ThreadId); SceKernelThreadInfo = Thread.Info; return 0; }