void timer_set_global_time(attotime newbase) { emu_timer *timer; /* set the new global offset */ global_basetime = newbase; LOG(("timer_set_global_time: new=%s head->expire=%s\n", attotime_string(newbase), attotime_string(timer_head->expire))); /* now process any timers that are overdue */ while (attotime_compare(timer_head->expire, global_basetime) <= 0) { int was_enabled = timer_head->enabled; /* if this is a one-shot timer, disable it now */ timer = timer_head; if (attotime_compare(timer->period, attotime_zero) == 0 || attotime_compare(timer->period, attotime_never) == 0) timer->enabled = FALSE; /* set the global state of which callback we're in */ callback_timer_modified = FALSE; callback_timer = timer; callback_timer_expire_time = timer->expire; /* call the callback */ if (was_enabled && timer->callback != NULL) { LOG(("Timer %s:%d[%s] fired (expire=%s)\n", timer->file, timer->line, timer->func, attotime_string(timer->expire, 9))); profiler_mark(PROFILER_TIMER_CALLBACK); (*timer->callback)(Machine, timer->ptr, timer->param); profiler_mark(PROFILER_END); } /* clear the callback timer global */ callback_timer = NULL; /* reset or remove the timer, but only if it wasn't modified during the callback */ if (!callback_timer_modified) { /* if the timer is temporary, remove it now */ if (timer->temporary) timer_remove(timer); /* otherwise, reschedule it */ else { timer->start = timer->expire; timer->expire = attotime_add(timer->expire, timer->period); timer_list_remove(timer); timer_list_insert(timer); } } } }
void timer_adjust_periodic(emu_timer *which, attotime start_delay, INT32 param, attotime period) { attotime time = get_current_time(); /* if this is the callback timer, mark it modified */ if (which == callback_timer) callback_timer_modified = TRUE; /* compute the time of the next firing and insert into the list */ which->param = param; which->enabled = TRUE; /* clamp negative times to 0 */ if (start_delay.seconds < 0) start_delay = attotime_zero; /* set the start and expire times */ which->start = time; which->expire = attotime_add(time, start_delay); which->period = period; /* remove and re-insert the timer in its new order */ timer_list_remove(which); timer_list_insert(which); /* if this was inserted as the head, abort the current timeslice and resync */ LOG(("timer_adjust_oneshot %s.%s:%d to expire @ %s\n", which->file, which->func, which->line, attotime_string(which->expire, 9))); if (which == timer_head && cpu_getexecutingcpu() >= 0) activecpu_abort_timeslice(); }
void timer_execute_timers(running_machine *machine) { timer_private *global = machine->timer_data; emu_timer *timer; /* if the current quantum has expired, find a new one */ if (attotime_compare(global->exec.basetime, global->quantum_current->expire) >= 0) { int curr; global->quantum_current->requested = 0; global->quantum_current = &global->quantum_list[0]; for (curr = 1; curr < ARRAY_LENGTH(global->quantum_list); curr++) if (global->quantum_list[curr].requested != 0 && global->quantum_list[curr].requested < global->quantum_current->requested) global->quantum_current = &global->quantum_list[curr]; global->exec.curquantum = global->quantum_current->actual; } LOG(("timer_set_global_time: new=%s head->expire=%s\n", attotime_string(global->exec.basetime, 9), attotime_string(global->activelist->expire, 9))); /* now process any timers that are overdue */ while (attotime_compare(global->activelist->expire, global->exec.basetime) <= 0) { int was_enabled = global->activelist->enabled; /* if this is a one-shot timer, disable it now */ timer = global->activelist; if (attotime_compare(timer->period, attotime_zero) == 0 || attotime_compare(timer->period, attotime_never) == 0) timer->enabled = FALSE; /* set the global state of which callback we're in */ global->callback_timer_modified = FALSE; global->callback_timer = timer; global->callback_timer_expire_time = timer->expire; /* call the callback */ if (was_enabled && timer->callback != NULL) { LOG(("Timer %s:%d[%s] fired (expire=%s)\n", timer->file, timer->line, timer->func, attotime_string(timer->expire, 9))); profiler_mark_start(PROFILER_TIMER_CALLBACK); (*timer->callback)(machine, timer->ptr, timer->param); profiler_mark_end(); } /* clear the callback timer global */ global->callback_timer = NULL; /* reset or remove the timer, but only if it wasn't modified during the callback */ if (!global->callback_timer_modified) { /* if the timer is temporary, remove it now */ if (timer->temporary) timer_remove(timer); /* otherwise, reschedule it */ else { timer->start = timer->expire; timer->expire = attotime_add(timer->expire, timer->period); timer_list_remove(timer); timer_list_insert(timer); } } } }