// timer helpers //------------------------------------------------- // timer_list_insert - insert a new timer into // the list at the appropriate location //------------------------------------------------- public emu_timer timer_list_insert(emu_timer timer) { // disabled timers sort to the end attotime expire = timer.enabled() ? timer.expire() : attotime.never; // loop over the timer list emu_timer prevtimer = null; for (emu_timer curtimer = m_timer_list; curtimer != null; prevtimer = curtimer, curtimer = curtimer.next()) { // if the current list entry expires after us, we should be inserted before it if (curtimer.expire() > expire) { // link the new guy in before the current list entry timer.m_prev = prevtimer; timer.m_next = curtimer; if (prevtimer != null) { prevtimer.m_next = timer; } else { m_timer_list = timer; } curtimer.m_prev = timer; return(timer); } } // need to insert after the last one if (prevtimer != null) { prevtimer.m_next = timer; } else { m_timer_list = timer; } timer.m_prev = prevtimer; timer.m_next = null; return(timer); }
//------------------------------------------------- // execute_timers - execute timers that are due //------------------------------------------------- void execute_timers() { if (machine().video().frame_update_count() % 400 == 0) { LOG("execute_timers: new={0} head->expire={1}\n", m_basetime.as_string(), m_timer_list.expire().as_string()); } // now process any timers that are overdue while (m_timer_list.expire() <= m_basetime) { // if this is a one-shot timer, disable it now emu_timer timer = m_timer_list; bool was_enabled = timer.enabled(); if (timer.m_period.is_zero() || timer.m_period.is_never()) { timer.m_enabled = false; } // set the global state of which callback we're in m_callback_timer_modified = false; m_callback_timer = timer; m_callback_timer_expire_time = timer.expire(); // call the callback if (was_enabled) { g_profiler.start(profile_type.PROFILER_TIMER_CALLBACK); if (timer.m_callback != null) { if (timer.m_device != null) { LOG("execute_timers: expired: {0} timer device {1} timer {2}\n", timer.expire().attoseconds(), timer.m_device.tag(), timer.m_id); } else { LOG("execute_timers: expired: {0} timer callback {1}\n", timer.expire().attoseconds(), timer.m_callback.ToString()); } timer.m_callback(timer.m_ptr, timer.m_param); } g_profiler.stop(); } // reset or remove the timer, but only if it wasn't modified during the callback if (!m_callback_timer_modified) { // if the timer is temporary, remove it now if (timer.m_temporary) { m_timer_allocator.reclaim(timer.release()); } // otherwise, reschedule it else { timer.schedule_next_period(); } } } // clear the callback timer global m_callback_timer = null; }