Revision 68c23e55 qemu-timer.c
b/qemu-timer.c | ||
---|---|---|
200 | 200 |
|
201 | 201 |
#ifdef _WIN32 |
202 | 202 |
|
203 |
struct qemu_alarm_win32 { |
|
204 |
MMRESULT timerId; |
|
205 |
unsigned int period; |
|
206 |
} alarm_win32_data = {0, 0}; |
|
207 |
|
|
208 | 203 |
static int win32_start_timer(struct qemu_alarm_timer *t); |
209 | 204 |
static void win32_stop_timer(struct qemu_alarm_timer *t); |
210 | 205 |
static void win32_rearm_timer(struct qemu_alarm_timer *t); |
... | ... | |
298 | 293 |
{"unix", unix_start_timer, unix_stop_timer, NULL, NULL}, |
299 | 294 |
#else |
300 | 295 |
{"dynticks", win32_start_timer, |
301 |
win32_stop_timer, win32_rearm_timer, &alarm_win32_data},
|
|
296 |
win32_stop_timer, win32_rearm_timer, NULL},
|
|
302 | 297 |
{"win32", win32_start_timer, |
303 |
win32_stop_timer, NULL, &alarm_win32_data},
|
|
298 |
win32_stop_timer, NULL, NULL},
|
|
304 | 299 |
#endif |
305 | 300 |
{NULL, } |
306 | 301 |
}; |
... | ... | |
636 | 631 |
static int64_t qemu_next_alarm_deadline(void); |
637 | 632 |
|
638 | 633 |
#ifdef _WIN32 |
639 |
static void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg, |
|
640 |
DWORD_PTR dwUser, DWORD_PTR dw1, |
|
641 |
DWORD_PTR dw2) |
|
634 |
static void CALLBACK host_alarm_handler(PVOID lpParam, BOOLEAN unused) |
|
642 | 635 |
#else |
643 | 636 |
static void host_alarm_handler(int host_signum) |
644 | 637 |
#endif |
... | ... | |
961 | 954 |
|
962 | 955 |
static int win32_start_timer(struct qemu_alarm_timer *t) |
963 | 956 |
{ |
964 |
TIMECAPS tc; |
|
965 |
struct qemu_alarm_win32 *data = t->priv; |
|
966 |
UINT flags; |
|
967 |
|
|
968 |
memset(&tc, 0, sizeof(tc)); |
|
969 |
timeGetDevCaps(&tc, sizeof(tc)); |
|
970 |
|
|
971 |
data->period = tc.wPeriodMin; |
|
972 |
timeBeginPeriod(data->period); |
|
973 |
|
|
974 |
flags = TIME_CALLBACK_FUNCTION; |
|
975 |
if (alarm_has_dynticks(t)) |
|
976 |
flags |= TIME_ONESHOT; |
|
977 |
else |
|
978 |
flags |= TIME_PERIODIC; |
|
979 |
|
|
980 |
data->timerId = timeSetEvent(1, // interval (ms) |
|
981 |
data->period, // resolution |
|
982 |
host_alarm_handler, // function |
|
983 |
(DWORD)t, // parameter |
|
984 |
flags); |
|
985 |
|
|
986 |
if (!data->timerId) { |
|
957 |
HANDLE hTimer; |
|
958 |
BOOLEAN success; |
|
959 |
|
|
960 |
/* If you call ChangeTimerQueueTimer on a one-shot timer (its period |
|
961 |
is zero) that has already expired, the timer is not updated. Since |
|
962 |
creating a new timer is relatively expensive, set a bogus one-hour |
|
963 |
interval in the dynticks case. */ |
|
964 |
success = CreateTimerQueueTimer(&hTimer, |
|
965 |
NULL, |
|
966 |
host_alarm_handler, |
|
967 |
t, |
|
968 |
1, |
|
969 |
alarm_has_dynticks(t) ? 3600000 : 1, |
|
970 |
WT_EXECUTEINTIMERTHREAD); |
|
971 |
|
|
972 |
if (!success) { |
|
987 | 973 |
fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n", |
988 | 974 |
GetLastError()); |
989 |
timeEndPeriod(data->period); |
|
990 | 975 |
return -1; |
991 | 976 |
} |
992 | 977 |
|
978 |
t->priv = (PVOID) hTimer; |
|
993 | 979 |
return 0; |
994 | 980 |
} |
995 | 981 |
|
996 | 982 |
static void win32_stop_timer(struct qemu_alarm_timer *t) |
997 | 983 |
{ |
998 |
struct qemu_alarm_win32 *data = t->priv;
|
|
984 |
HANDLE hTimer = t->priv;
|
|
999 | 985 |
|
1000 |
timeKillEvent(data->timerId); |
|
1001 |
timeEndPeriod(data->period); |
|
986 |
if (hTimer) { |
|
987 |
DeleteTimerQueueTimer(NULL, hTimer, NULL); |
|
988 |
} |
|
1002 | 989 |
} |
1003 | 990 |
|
1004 | 991 |
static void win32_rearm_timer(struct qemu_alarm_timer *t) |
1005 | 992 |
{ |
1006 |
struct qemu_alarm_win32 *data = t->priv;
|
|
993 |
HANDLE hTimer = t->priv;
|
|
1007 | 994 |
int nearest_delta_ms; |
995 |
BOOLEAN success; |
|
1008 | 996 |
|
1009 | 997 |
assert(alarm_has_dynticks(t)); |
1010 | 998 |
if (!active_timers[QEMU_CLOCK_REALTIME] && |
... | ... | |
1012 | 1000 |
!active_timers[QEMU_CLOCK_HOST]) |
1013 | 1001 |
return; |
1014 | 1002 |
|
1015 |
timeKillEvent(data->timerId); |
|
1016 |
|
|
1017 | 1003 |
nearest_delta_ms = (qemu_next_alarm_deadline() + 999999) / 1000000; |
1018 | 1004 |
if (nearest_delta_ms < 1) { |
1019 | 1005 |
nearest_delta_ms = 1; |
1020 | 1006 |
} |
1021 |
data->timerId = timeSetEvent(nearest_delta_ms, |
|
1022 |
data->period, |
|
1023 |
host_alarm_handler, |
|
1024 |
(DWORD)t, |
|
1025 |
TIME_ONESHOT | TIME_CALLBACK_FUNCTION); |
|
1026 |
|
|
1027 |
if (!data->timerId) { |
|
1028 |
fprintf(stderr, "Failed to re-arm win32 alarm timer %ld\n", |
|
1029 |
GetLastError()); |
|
1007 |
success = ChangeTimerQueueTimer(NULL, |
|
1008 |
hTimer, |
|
1009 |
nearest_delta_ms, |
|
1010 |
3600000); |
|
1030 | 1011 |
|
1031 |
timeEndPeriod(data->period); |
|
1032 |
exit(1); |
|
1012 |
if (!success) { |
|
1013 |
fprintf(stderr, "Failed to rearm win32 alarm timer: %ld\n", |
|
1014 |
GetLastError()); |
|
1015 |
exit(-1); |
|
1033 | 1016 |
} |
1017 |
|
|
1034 | 1018 |
} |
1035 | 1019 |
|
1036 | 1020 |
#endif /* _WIN32 */ |
Also available in: Unified diff