public int sceKernelReceiveMbx(MessageBox MessageBox, PspPointer *PointerToMessage, uint *Timeout)
        {
            var  CurrentThread = ThreadManager.Current;
            bool TimedOut      = false;

            CurrentThread.SetWaitAndPrepareWakeUp(HleThread.WaitType.None, "sceKernelReceiveMbx", MessageBox,
                                                  WakeUpCallback =>
            {
                if (Timeout != null)
                {
                    PspRtc.RegisterTimerInOnce(TimeSpanUtils.FromMicroseconds(*Timeout), () =>
                    {
                        TimedOut = true;
                        WakeUpCallback();
                    });
                }
                MessageBox.Receive(PointerToMessage, WakeUpCallback);
            }, HandleCallbacks: false);

            if (TimedOut)
            {
                return((int)SceKernelErrors.ERROR_KERNEL_WAIT_TIMEOUT);
            }
            else
            {
                //if (Timeout)
                //return MessageBox.Receive(Message);
                return(0);
            }
        }
        /// <summary>
        /// Wait for an event flag for a given bit pattern with callback.
        /// </summary>
        /// <param name="EventId">The event ID returned by <see cref="sceKernelCreateEventFlag"/>.</param>
        /// <param name="Bits">The bit pattern to poll for.</param>
        /// <param name="Wait">Wait type, one or more of PspEventFlagWaitTypes or'ed together</param>
        /// <param name="OutBits">The bit pattern that was matched.</param>
        /// <param name="Timeout">Timeout in microseconds</param>
        /// <param name="HandleCallbacks"></param>
        /// <returns>
        ///		ERROR_KERNEL_NOT_FOUND_EVENT_FLAG - If can't find the eventFlag
        ///		ERROR_KERNEL_WAIT_TIMEOUT         - If there was a timeout
        ///		0                                 - On success
        /// </returns>
        public int _sceKernelWaitEventFlagCB(HleEventFlag EventFlag, uint Bits, EventFlagWaitTypeSet Wait,
                                             uint *OutBits, uint *Timeout, bool HandleCallbacks)
        {
            if ((Wait & ~EventFlagWaitTypeSet.MaskValidBits) != 0)
            {
                throw new SceKernelException(SceKernelErrors.ERROR_KERNEL_ILLEGAL_MODE);
            }
            if (Bits == 0)
            {
                throw new SceKernelException(SceKernelErrors.ERROR_KERNEL_EVENT_FLAG_ILLEGAL_WAIT_PATTERN);
            }
            bool TimedOut = false;

            var PreviousPattern = EventFlag.Info.CurrentPattern;

            ThreadManager.Current.SetWaitAndPrepareWakeUp(
                HleThread.WaitType.Semaphore,
                $"_sceKernelWaitEventFlagCB(EventId={EventFlag.GetUidIndex(InjectContext)}, Bits={Bits:X}, Wait={Wait})",
                EventFlag,
                WakeUpCallback =>
            {
                if (Timeout != null)
                {
                    PspRtc.RegisterTimerInOnce(TimeSpanUtils.FromMicroseconds(*Timeout), () =>
                    {
                        TimedOut = true;
                        *Timeout = 0;
                        WakeUpCallback();
                    });
                }

                EventFlag.AddWaitingThread(new HleEventFlag.WaitThread()
                {
                    HleThread      = ThreadManager.Current,
                    BitsToMatch    = Bits,
                    WaitType       = Wait,
                    WakeUpCallback = () => { WakeUpCallback(); },
                    OutBits        = OutBits,
                });
            }, HandleCallbacks: HandleCallbacks);

            if (OutBits != null)
            {
                *OutBits = PreviousPattern;
            }

            if (TimedOut)
            {
                throw new SceKernelException(SceKernelErrors.ERROR_KERNEL_WAIT_TIMEOUT);
            }

            //throw(new NotImplementedException());
            return(0);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="ThreadId"></param>
        /// <param name="Timeout"></param>
        /// <param name="HandleCallbacks"></param>
        /// <returns></returns>
        private int _sceKernelWaitThreadEndCB(int ThreadId, uint *Timeout, bool HandleCallbacks)
        {
            var ThreadToWaitEnd = GetThreadById(ThreadId);

            if (ThreadToWaitEnd.HasAnyStatus(HleThread.Status.Stopped))
            {
                return(0);
            }

            if (ThreadToWaitEnd.HasAnyStatus(HleThread.Status.Killed))
            {
                return(0);
            }

            bool TimedOut = false;

            ThreadManager.Current.SetWaitAndPrepareWakeUp(HleThread.WaitType.None,
                                                          $"sceKernelWaitThreadEnd('{ThreadToWaitEnd.Name}')", ThreadToWaitEnd, WakeUpCallback =>
            {
                if (Timeout != null)
                {
                    PspRtc.RegisterTimerInOnce(TimeSpanUtils.FromMicroseconds(*Timeout), () =>
                    {
                        TimedOut = true;
                        WakeUpCallback();
                    });
                }

                Console.WriteLine("Wait End!");
                Action OnTerminate = null;

                OnTerminate = () =>
                {
                    ThreadToWaitEnd.OnTerminate -= OnTerminate;
                    Console.WriteLine("Ended!");
                    //throw(new Exception("aaaaaaaaaaaa"));
                    WakeUpCallback();
                };

                ThreadToWaitEnd.OnTerminate += OnTerminate;
            }, HandleCallbacks: HandleCallbacks);

            if (TimedOut)
            {
                return((int)SceKernelErrors.ERROR_KERNEL_WAIT_TIMEOUT);
            }
            else
            {
                return(0);
            }
        }
        private int _sceKernelDelayThreadCB(uint DelayInMicroseconds, bool HandleCallbacks)
        {
            var CurrentThread = ThreadManager.Current;

            CurrentThread.SetWaitAndPrepareWakeUp(HleThread.WaitType.Timer,
                                                  $"sceKernelDelayThread({DelayInMicroseconds}, {HandleCallbacks})", null,
                                                  WakeUpCallback =>
            {
                PspRtc.RegisterTimerInOnce(TimeSpanUtils.FromMicroseconds(DelayInMicroseconds),
                                           () => { WakeUpCallback(); });
            }, HandleCallbacks: HandleCallbacks);

            return(0);
        }
Example #5
0
        private void _DelayIo(IoDelayType IoDelayType, long DataSize = 1)
        {
            //return;

            var TimeSpan = IoDelayType.GetTimePerSize(DataSize);

            //Console.WriteLine("_DelayIo: {0}, {1} : {2}", IoDelayType, DataSize, TimeSpan);

            if (TimeSpan != TimeSpan.Zero)
            {
                var CurrentThread = ThreadManager.Current;
                //ThreadManager
                CurrentThread?.SetWaitAndPrepareWakeUp(HleThread.WaitType.Timer, "_DelayIo", null,
                                                       WakeUpCallback => { PspRtc.RegisterTimerInOnce(TimeSpan, WakeUpCallback); },
                                                       HandleCallbacks: false);
            }
            else
            {
                ThreadManager.Yield();
            }
        }
Example #6
0
        private void _DelayIo(IoDelayType ioDelayType, long dataSize = 1)
        {
            if (!PspHleRunningConfig.EnableDelayIo)
            {
                return;
            }

            var timeSpan = ioDelayType.GetTimePerSize(dataSize);

            //Console.WriteLine("_DelayIo: {0}, {1} : {2}", IoDelayType, DataSize, TimeSpan);

            if (timeSpan != TimeSpan.Zero)
            {
                var currentThread = ThreadManager.Current;
                //ThreadManager
                currentThread?.SetWaitAndPrepareWakeUp(HleThread.WaitType.Timer, "_DelayIo", null,
                                                       WakeUpCallback => { PspRtc.RegisterTimerInOnce(timeSpan, WakeUpCallback); },
                                                       HandleCallbacks: false);
            }
            else
            {
                ThreadManager.Yield();
            }
        }