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