Esempio n. 1
0
            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);
            }
Esempio n. 2
0
        public virtual int sceKernelReferMbxStatus(int uid, TPointer infoAddr)
        {
            SceKernelMbxInfo info = mbxMap[uid];

            info.write(infoAddr);

            return(0);
        }
Esempio n. 3
0
        public virtual int sceKernelCancelReceiveMbx(int uid, TPointer32 pnumAddr)
        {
            SceKernelMbxInfo info = mbxMap[uid];

            pnumAddr.setValue(info.NumWaitThreads);
            info.threadWaitingList.removeAllWaitingThreads();
            onMbxCancelled(uid);

            return(0);
        }
Esempio n. 4
0
        private bool removeWaitingThread(SceKernelThreadInfo thread)
        {
            SceKernelMbxInfo info = mbxMap[thread.wait.Mbx_id];

            if (info == null)
            {
                return(false);
            }

            info.threadWaitingList.removeWaitingThread(thread);

            return(true);
        }
Esempio n. 5
0
        public virtual int sceKernelCreateMbx(string name, int attr, TPointer option)
        {
            if (option.NotNull)
            {
                int optionSize = option.getValue32();
                Console.WriteLine(string.Format("sceKernelCreateMbx option at {0}: size={1:D}", option, optionSize));
            }

            SceKernelMbxInfo info = new SceKernelMbxInfo(name, attr);

            //if (log.DebugEnabled)
            {
                Console.WriteLine(string.Format("sceKernelCreateMbx returning {0}", info));
            }
            mbxMap[info.uid] = info;

            return(info.uid);
        }
Esempio n. 6
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);
        }
Esempio n. 7
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);
        }