#include "qemu-timer.h"
-#ifdef __FreeBSD__
-#include <sys/param.h>
-#endif
-
#ifdef _WIN32
#include <mmsystem.h>
#endif
#define QEMU_CLOCK_HOST 2
struct QEMUClock {
- int type;
- bool enabled;
-
QEMUTimer *active_timers;
NotifierList reset_notifiers;
int64_t last;
+
+ int type;
+ bool enabled;
};
struct QEMUTimer {
- QEMUClock *clock;
int64_t expire_time; /* in nanoseconds */
- int scale;
+ QEMUClock *clock;
QEMUTimerCB *cb;
void *opaque;
- struct QEMUTimer *next;
+ QEMUTimer *next;
+ int scale;
};
struct qemu_alarm_timer {
void (*stop)(struct qemu_alarm_timer *t);
void (*rearm)(struct qemu_alarm_timer *t, int64_t nearest_delta_ns);
#if defined(__linux__)
- int fd;
timer_t timer;
+ int fd;
#elif defined(_WIN32)
HANDLE timer;
#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);
}
#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);
}
}