Esempio n. 1
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);
        }