All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

Commit 68c23e55 authored by Paolo Bonzini's avatar Paolo Bonzini Committed by Blue Swirl

use win32 timer queues

Multimedia timers are only useful for compatibility with Windows NT 4.0
and earlier.  Plus, the implementation in Wine is extremely heavyweight.
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Signed-off-by: default avatarBlue Swirl <blauwirbel@gmail.com>
parent cfced5b2
...@@ -200,11 +200,6 @@ static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t) ...@@ -200,11 +200,6 @@ static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
#ifdef _WIN32 #ifdef _WIN32
struct qemu_alarm_win32 {
MMRESULT timerId;
unsigned int period;
} alarm_win32_data = {0, 0};
static int win32_start_timer(struct qemu_alarm_timer *t); static int win32_start_timer(struct qemu_alarm_timer *t);
static void win32_stop_timer(struct qemu_alarm_timer *t); static void win32_stop_timer(struct qemu_alarm_timer *t);
static void win32_rearm_timer(struct qemu_alarm_timer *t); static void win32_rearm_timer(struct qemu_alarm_timer *t);
...@@ -298,9 +293,9 @@ static struct qemu_alarm_timer alarm_timers[] = { ...@@ -298,9 +293,9 @@ static struct qemu_alarm_timer alarm_timers[] = {
{"unix", unix_start_timer, unix_stop_timer, NULL, NULL}, {"unix", unix_start_timer, unix_stop_timer, NULL, NULL},
#else #else
{"dynticks", win32_start_timer, {"dynticks", win32_start_timer,
win32_stop_timer, win32_rearm_timer, &alarm_win32_data}, win32_stop_timer, win32_rearm_timer, NULL},
{"win32", win32_start_timer, {"win32", win32_start_timer,
win32_stop_timer, NULL, &alarm_win32_data}, win32_stop_timer, NULL, NULL},
#endif #endif
{NULL, } {NULL, }
}; };
...@@ -636,9 +631,7 @@ void qemu_run_all_timers(void) ...@@ -636,9 +631,7 @@ void qemu_run_all_timers(void)
static int64_t qemu_next_alarm_deadline(void); static int64_t qemu_next_alarm_deadline(void);
#ifdef _WIN32 #ifdef _WIN32
static void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg, static void CALLBACK host_alarm_handler(PVOID lpParam, BOOLEAN unused)
DWORD_PTR dwUser, DWORD_PTR dw1,
DWORD_PTR dw2)
#else #else
static void host_alarm_handler(int host_signum) static void host_alarm_handler(int host_signum)
#endif #endif
...@@ -961,50 +954,45 @@ static void unix_stop_timer(struct qemu_alarm_timer *t) ...@@ -961,50 +954,45 @@ static void unix_stop_timer(struct qemu_alarm_timer *t)
static int win32_start_timer(struct qemu_alarm_timer *t) static int win32_start_timer(struct qemu_alarm_timer *t)
{ {
TIMECAPS tc; HANDLE hTimer;
struct qemu_alarm_win32 *data = t->priv; BOOLEAN success;
UINT flags;
/* If you call ChangeTimerQueueTimer on a one-shot timer (its period
memset(&tc, 0, sizeof(tc)); is zero) that has already expired, the timer is not updated. Since
timeGetDevCaps(&tc, sizeof(tc)); creating a new timer is relatively expensive, set a bogus one-hour
interval in the dynticks case. */
data->period = tc.wPeriodMin; success = CreateTimerQueueTimer(&hTimer,
timeBeginPeriod(data->period); NULL,
host_alarm_handler,
flags = TIME_CALLBACK_FUNCTION; t,
if (alarm_has_dynticks(t)) 1,
flags |= TIME_ONESHOT; alarm_has_dynticks(t) ? 3600000 : 1,
else WT_EXECUTEINTIMERTHREAD);
flags |= TIME_PERIODIC;
if (!success) {
data->timerId = timeSetEvent(1, // interval (ms)
data->period, // resolution
host_alarm_handler, // function
(DWORD)t, // parameter
flags);
if (!data->timerId) {
fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n", fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n",
GetLastError()); GetLastError());
timeEndPeriod(data->period);
return -1; return -1;
} }
t->priv = (PVOID) hTimer;
return 0; return 0;
} }
static void win32_stop_timer(struct qemu_alarm_timer *t) static void win32_stop_timer(struct qemu_alarm_timer *t)
{ {
struct qemu_alarm_win32 *data = t->priv; HANDLE hTimer = t->priv;
timeKillEvent(data->timerId); if (hTimer) {
timeEndPeriod(data->period); DeleteTimerQueueTimer(NULL, hTimer, NULL);
}
} }
static void win32_rearm_timer(struct qemu_alarm_timer *t) static void win32_rearm_timer(struct qemu_alarm_timer *t)
{ {
struct qemu_alarm_win32 *data = t->priv; HANDLE hTimer = t->priv;
int nearest_delta_ms; int nearest_delta_ms;
BOOLEAN success;
assert(alarm_has_dynticks(t)); assert(alarm_has_dynticks(t));
if (!active_timers[QEMU_CLOCK_REALTIME] && if (!active_timers[QEMU_CLOCK_REALTIME] &&
...@@ -1012,25 +1000,21 @@ static void win32_rearm_timer(struct qemu_alarm_timer *t) ...@@ -1012,25 +1000,21 @@ static void win32_rearm_timer(struct qemu_alarm_timer *t)
!active_timers[QEMU_CLOCK_HOST]) !active_timers[QEMU_CLOCK_HOST])
return; return;
timeKillEvent(data->timerId);
nearest_delta_ms = (qemu_next_alarm_deadline() + 999999) / 1000000; nearest_delta_ms = (qemu_next_alarm_deadline() + 999999) / 1000000;
if (nearest_delta_ms < 1) { if (nearest_delta_ms < 1) {
nearest_delta_ms = 1; nearest_delta_ms = 1;
} }
data->timerId = timeSetEvent(nearest_delta_ms, success = ChangeTimerQueueTimer(NULL,
data->period, hTimer,
host_alarm_handler, nearest_delta_ms,
(DWORD)t, 3600000);
TIME_ONESHOT | TIME_CALLBACK_FUNCTION);
if (!data->timerId) {
fprintf(stderr, "Failed to re-arm win32 alarm timer %ld\n",
GetLastError());
timeEndPeriod(data->period); if (!success) {
exit(1); fprintf(stderr, "Failed to rearm win32 alarm timer: %ld\n",
GetLastError());
exit(-1);
} }
} }
#endif /* _WIN32 */ #endif /* _WIN32 */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment