#include "qemu-timer.h"
-#ifdef __FreeBSD__
-#include <sys/param.h>
-#endif
-
#ifdef _WIN32
#include <mmsystem.h>
#endif
static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
{
- int64_t nearest_delta_ns;
- if (!rt_clock->active_timers &&
- !vm_clock->active_timers &&
- !host_clock->active_timers) {
- return;
+ int64_t nearest_delta_ns = qemu_next_alarm_deadline();
+ if (nearest_delta_ns < INT64_MAX) {
+ t->rearm(t, nearest_delta_ns);
}
- nearest_delta_ns = qemu_next_alarm_deadline();
- t->rearm(t, nearest_delta_ns);
}
/* TODO: MIN_TIMER_REARM_NS should be optimized */
char *name;
struct qemu_alarm_timer tmp;
- if (!strcmp(opt, "?")) {
+ if (is_help_option(opt)) {
show_available_alarms();
exit(0);
}
void qemu_run_timers(QEMUClock *clock)
{
- QEMUTimer **ptimer_head, *ts;
+ QEMUTimer *ts;
int64_t current_time;
if (!clock->enabled)
return;
current_time = qemu_get_clock_ns(clock);
- ptimer_head = &clock->active_timers;
for(;;) {
- ts = *ptimer_head;
+ ts = clock->active_timers;
if (!qemu_timer_expired_ns(ts, current_time)) {
break;
}
/* remove timer from the list before calling the callback */
- *ptimer_head = ts->next;
+ clock->active_timers = ts->next;
ts->next = NULL;
/* run the callback (the timer list can be modified) */
#ifdef _WIN32
static MMRESULT mm_timer;
-static unsigned mm_period;
+static TIMECAPS mm_tc;
static void CALLBACK mm_alarm_handler(UINT uTimerID, UINT uMsg,
DWORD_PTR dwUser, DWORD_PTR dw1,
static int mm_start_timer(struct qemu_alarm_timer *t)
{
- TIMECAPS tc;
+ timeGetDevCaps(&mm_tc, sizeof(mm_tc));
- memset(&tc, 0, sizeof(tc));
- timeGetDevCaps(&tc, sizeof(tc));
+ timeBeginPeriod(mm_tc.wPeriodMin);
- mm_period = tc.wPeriodMin;
- timeBeginPeriod(mm_period);
-
- mm_timer = timeSetEvent(1, /* interval (ms) */
- mm_period, /* resolution */
+ mm_timer = timeSetEvent(mm_tc.wPeriodMin, /* interval (ms) */
+ mm_tc.wPeriodMin, /* resolution */
mm_alarm_handler, /* function */
(DWORD_PTR)t, /* parameter */
TIME_ONESHOT | TIME_CALLBACK_FUNCTION);
if (!mm_timer) {
- fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n",
- GetLastError());
- timeEndPeriod(mm_period);
+ fprintf(stderr, "Failed to initialize win32 alarm timer\n");
+ timeEndPeriod(mm_tc.wPeriodMin);
return -1;
}
static void mm_stop_timer(struct qemu_alarm_timer *t)
{
timeKillEvent(mm_timer);
- timeEndPeriod(mm_period);
+ timeEndPeriod(mm_tc.wPeriodMin);
}
static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta)
{
int64_t nearest_delta_ms = delta / 1000000;
- if (nearest_delta_ms < 1) {
- nearest_delta_ms = 1;
- }
- /* UINT_MAX can be 32 bit */
- if (nearest_delta_ms > UINT_MAX) {
- nearest_delta_ms = UINT_MAX;
+ if (nearest_delta_ms < mm_tc.wPeriodMin) {
+ nearest_delta_ms = mm_tc.wPeriodMin;
+ } else if (nearest_delta_ms > mm_tc.wPeriodMax) {
+ nearest_delta_ms = mm_tc.wPeriodMax;
}
timeKillEvent(mm_timer);
- mm_timer = timeSetEvent((unsigned int) nearest_delta_ms,
- mm_period,
+ mm_timer = timeSetEvent((UINT)nearest_delta_ms,
+ mm_tc.wPeriodMin,
mm_alarm_handler,
(DWORD_PTR)t,
TIME_ONESHOT | TIME_CALLBACK_FUNCTION);
if (!mm_timer) {
- fprintf(stderr, "Failed to re-arm win32 alarm timer %ld\n",
- GetLastError());
-
- timeEndPeriod(mm_period);
+ fprintf(stderr, "Failed to re-arm win32 alarm timer\n");
+ timeEndPeriod(mm_tc.wPeriodMin);
exit(1);
}
}
goto fail;
}
- /* first event is at time 0 */
atexit(quit_timers);
- t->pending = true;
alarm_timer = t;
-
return 0;
fail: