/** * Processes all of the scheduled delegates until there are no more to execute. * Sleeps when waiting for a scheduled delegate to be ready to invoke to reduce processor usage. */ static void Run() { StackTrace trace(__METHOD__, __FILE__, __LINE__); while (FutureEvents.empty() == false) { FutureEventHandler event = FutureEvents.top(); FutureEvents.pop(); Sleep(event.Time() - DateTime::Utc()); event(); } }
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; }
bool ___updateEventQueue(TimeType t, TimeType & currTime, EventQueue & eventQueue) { currTime += t; if(eventQueue.empty()) return false; if(currTime >= eventQueue.front().first) { eventQueue.front().second(); eventQueue.pop(); currTime = 0.0f; } return true; }
void AbstractDevice::eventThread() { ADR_GUARD("AbstractDevice::eventThread"); m_thread_exists = true; while (!m_thread_should_die) { m_event_mutex.lock(); while (m_events.empty()) { m_events_available.wait(m_event_mutex, 1); if (m_thread_should_die) { break; } } if (m_thread_should_die) { m_event_mutex.unlock(); break; } // Make a local copy of the events so they can be processed without // leaving the mutex locked. EventQueue events = m_events; // Queues don't support clear(). o_o while (!m_events.empty()) { m_events.pop(); } m_event_mutex.unlock(); // Process the events. while (!events.empty()) { EventPtr event = events.front(); events.pop(); processEvent(event.get()); } } m_thread_exists = false; }
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);*/ }