public virtual bool continueWaitState(SceKernelThreadInfo thread, ThreadWaitInfo wait) { // Check if the thread has to continue its wait state or if the vpl // has been allocated during the callback execution. SceKernelVplInfo vpl = outerInstance.vplMap[wait.Vpl_id]; if (vpl == null) { thread.cpuContext._v0 = ERROR_KERNEL_NOT_FOUND_VPOOL; return(false); } // Check vpl. int addr = outerInstance.tryAllocateVpl(vpl, wait.Vpl_size); if (addr != 0) { // Return the allocated address wait.Vpl_dataAddr.setValue(addr); vpl.threadWaitingList.removeWaitingThread(thread); thread.cpuContext._v0 = 0; return(false); } return(true); }
public virtual int sceKernelCancelVpl(int uid, TPointer32 numWaitThreadAddr) { SceKernelVplInfo info = vplMap[uid]; numWaitThreadAddr.setValue(info.NumWaitingThreads); info.threadWaitingList.removeAllWaitingThreads(); onVplCancelled(uid); return(0); }
public virtual int sceKernelReferVplStatus(int uid, TPointer infoAddr) { SceKernelVplInfo info = vplMap[uid]; //if (log.DebugEnabled) { Console.WriteLine(string.Format("sceKernelReferVplStatus returning {0}", info)); } info.write(infoAddr); return(0); }
private bool removeWaitingThread(SceKernelThreadInfo thread) { SceKernelVplInfo fpl = vplMap[thread.wait.Vpl_id]; if (fpl == null) { return(false); } fpl.threadWaitingList.removeWaitingThread(thread); return(true); }
public virtual int sceKernelDeleteVpl(int uid) { SceKernelVplInfo info = vplMap.Remove(uid); if (info.freeSize < info.poolSize) { Console.WriteLine(string.Format("sceKernelDeleteVpl approx 0x{0:X} unfreed bytes allocated", info.poolSize - info.freeSize)); } info.delete(); onVplDeleted(uid); return(0); }
public virtual int sceKernelFreeVpl(int uid, TPointer dataAddr) { SceKernelVplInfo info = vplMap[uid]; if (!info.free(dataAddr.Address)) { return(ERROR_KERNEL_ILLEGAL_MEMBLOCK); } onVplFree(info); return(0); }
public virtual int sceKernelCreateVpl(PspString name, int partitionid, int attr, int size, TPointer option) { if (name.Null) { // PSP is returning this error is case of a NULL name return(SceKernelErrors.ERROR_KERNEL_ERROR); } if (option.NotNull) { int optionSize = option.getValue32(); Console.WriteLine(string.Format("sceKernelCreateVpl option at {0}, size={1:D}", option, optionSize)); } int memType = PSP_SMEM_Low; if ((attr & PSP_VPL_ATTR_ADDR_HIGH) == PSP_VPL_ATTR_ADDR_HIGH) { memType = PSP_SMEM_High; } if ((attr & ~PSP_VPL_ATTR_MASK) != 0) { Console.WriteLine("sceKernelCreateVpl bad attr value 0x" + attr.ToString("x")); return(ERROR_KERNEL_ILLEGAL_ATTR); } if (size == 0) { return(ERROR_KERNEL_ILLEGAL_MEMSIZE); } if (size < 0) { return(ERROR_KERNEL_NO_MEMORY); } SceKernelVplInfo info = SceKernelVplInfo.tryCreateVpl(name.String, partitionid, attr, size, memType); if (info == null) { return(ERROR_KERNEL_NO_MEMORY); } //if (log.DebugEnabled) { Console.WriteLine(string.Format("sceKernelCreateVpl returning {0}", info)); } vplMap[info.uid] = info; return(info.uid); }
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); }
public virtual int hleNetMallocInternal(int size) { int allocatedAddr; // When flash0:/kd/ifhandle.prx is in use, allocate the memory through this // implementation instead of using the HLE implementation. // ifhandle.prx is creating a VPL name "SceNet" and allocating from it. SceKernelVplInfo vplInfo = Managers.vpl.getVplInfoByName("SceNet"); if (vplInfo != null) { allocatedAddr = Managers.vpl.tryAllocateVpl(vplInfo, size); } else { allocatedAddr = sceNetMallocInternal(size); } return(allocatedAddr); }
private void onVplFree(SceKernelVplInfo info) { ThreadManForUser threadMan = Modules.ThreadManForUserModule; bool reschedule = false; SceKernelThreadInfo checkedThread = null; while (info.freeSize > 0) { SceKernelThreadInfo thread = info.threadWaitingList.getNextWaitingThread(checkedThread); if (thread == null) { break; } int addr = tryAllocateVpl(info, thread.wait.Vpl_size); if (addr != 0) { //if (log.DebugEnabled) { Console.WriteLine(string.Format("onVplFree waking thread {0}", thread)); } // Return allocated address thread.wait.Vpl_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(); } }
/// <returns> the address of the allocated block or 0 if failed. </returns> public virtual int tryAllocateVpl(SceKernelVplInfo info, int size) { return(info.alloc(size)); }
public int sceKernelReferVplStatus(VariablePoolId VariablePoolId, SceKernelVplInfo* Info) { var VariablePool = VariablePoolList.Get(VariablePoolId); *Info = VariablePool.Info; return 0; }
public int sceKernelReferVplStatus(VariablePool VariablePool, SceKernelVplInfo* Info) { *Info = VariablePool.Info; return 0; }