int main() { EventQueue event = *EventQueue::getInstance(); Event event1("H1"), event2("H2"), event3("H3"), event4("H4"), event5("H5"); event1.time = 0.5; event2.time = 0.6; event3.time = 0.3; event.push(&event1); event.push(&event2); event.push(&event3); //the order now should be 0.3/0.5/0.6 assert(event.pop()->time == 0.3); event4.time = 1; event5.time = 0.1; event.push(&event4); event.push(&event5); //the order should now be 0.1/0.5/0.6/1 assert(event.pop()->time == 0.1); assert(event.pop()->time == 0.5); assert(event.pop()->time == 0.6); assert(event.pop()->time == 1); //if nothing is in the event, return "-1" assert(event.pop()->time == -1); assert(event.pop()->time == -1); printf("Test Success - event queue\n"); return EXIT_SUCCESS; }
int sys_event_queue_receive(u32 equeue_id, mem_ptr_t<sys_event_data> event, u64 timeout) { sys_event.Warning("sys_event_queue_receive(equeue_id=%d, event_addr=0x%x, timeout=%lld)", equeue_id, event.GetAddr(), timeout); if (!event.IsGood()) { return CELL_EFAULT; } EventQueue* eq; if (!Emu.GetIdManager().GetIDData(equeue_id, eq)) { return CELL_ESRCH; } if (eq->type != SYS_PPU_QUEUE) { return CELL_EINVAL; } u32 tid = GetCurrentPPUThread().GetId(); eq->push(tid); // add thread to sleep queue timeout = timeout ? (timeout / 1000) : ~0; u64 counter = 0; while (true) { switch (eq->owner.trylock(tid)) { case SMR_OK: if (!eq->events.count()) { eq->owner.unlock(tid); break; } else { u32 next = (eq->protocol == SYS_SYNC_FIFO) ? eq->pop() : eq->pop_prio(); if (next != tid) { eq->owner.unlock(tid, next); break; } } case SMR_SIGNAL: { eq->events.pop(*(sys_event_data*)(Memory + event)); eq->owner.unlock(tid); return CELL_OK; } case SMR_FAILED: break; default: eq->invalidate(tid); return CELL_ECANCELED; } Sleep(1); if (counter++ > timeout || Emu.IsStopped()) { if (Emu.IsStopped()) ConLog.Warning("sys_event_queue_receive(equeue=%d) aborted", equeue_id); eq->invalidate(tid); return CELL_ETIMEDOUT; } } /* auto queue_receive = [&](int status) -> bool { if(status == CPUThread_Stopped) { result = CELL_ECANCELED; return false; } EventQueue* equeue; if (!Emu.GetIdManager().GetIDData(equeue_id, equeue)) { result = CELL_ESRCH; return false; } for(int i=0; i<equeue->pos; ++i) { if(!equeue->ports[i]->has_data && equeue->ports[i]->thread) { SPUThread* thr = (SPUThread*)equeue->ports[i]->thread; if(thr->SPU.OutIntr_Mbox.GetCount()) { u32 val; thr->SPU.OutIntr_Mbox.Pop(val); if(!thr->SPU.Out_MBox.Pop(val)) val = 0; equeue->ports[i]->data1 = val; equeue->ports[i]->data2 = 0; equeue->ports[i]->data3 = 0; equeue->ports[i]->has_data = true; } } } for(int i=0; i<equeue->pos; i++) { if(equeue->ports[i]->has_data) { event->source = equeue->ports[i]->name; event->data1 = equeue->ports[i]->data1; event->data2 = equeue->ports[i]->data2; event->data3 = equeue->ports[i]->data3; equeue->ports[i]->has_data = false; result = CELL_OK; return false; } } return true; }; GetCurrentPPUThread().WaitFor(queue_receive);*/ }
/** * Schedules a delegate to be executed after the specified amount of time passed. * * @param timeout The duration to wait before executing the delegate. * @param delegate The delegate to invoke. */ static void SetTimeout(const TimeSpan& timeout, const Delegate<void ()>& delegate) { StackTrace trace(__METHOD__, __FILE__, __LINE__); FutureEvents.push(FutureEventHandler(DateTime::Utc() + timeout, delegate)); }