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); }