Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
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);
        }
Exemplo n.º 4
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);
        }
Exemplo n.º 5
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;
 }
Exemplo n.º 6
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);
        }
Exemplo n.º 7
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());
        }
Exemplo n.º 8
0
        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;
        }
Exemplo n.º 9
0
        public virtual int sceUmdRegisterUMDCallBack(int uid)
        {
            ThreadManForUser threadMan = Modules.ThreadManForUserModule;

            if (!threadMan.hleKernelRegisterCallback(SceKernelThreadInfo.THREAD_CALLBACK_UMD, uid))
            {
                return(-1);
            }

            return(0);
        }
Exemplo n.º 10
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);
        }
Exemplo n.º 11
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);
        }
Exemplo n.º 12
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);
        }
Exemplo n.º 13
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);
        }
Exemplo n.º 14
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();
            }
        }
Exemplo n.º 15
0
        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);
        }
Exemplo n.º 16
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);
        }
Exemplo n.º 17
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));
            }
        }
Exemplo n.º 18
0
        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();
            }
        }
Exemplo n.º 19
0
        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);
        }
Exemplo n.º 20
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);
        }
Exemplo n.º 21
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);
        }
Exemplo n.º 22
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);
        }
Exemplo n.º 23
0
        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);
        }
Exemplo n.º 24
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);
        }
Exemplo n.º 25
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();
            }
        }
Exemplo n.º 26
0
        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();
            }
        }
Exemplo n.º 27
0
        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();
            }
        }
Exemplo n.º 28
0
        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();
            }
        }
Exemplo n.º 29
0
        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);
            }
        }
Exemplo n.º 30
0
        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();
            }
        }
Exemplo n.º 31
0
        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();
            }
        }