qemu-timer.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769
  1. /*
  2. * QEMU System Emulator
  3. *
  4. * Copyright (c) 2003-2008 Fabrice Bellard
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. */
  24. #include "sysemu.h"
  25. #include "net.h"
  26. #include "monitor.h"
  27. #include "console.h"
  28. #include "hw/hw.h"
  29. #include "qemu-timer.h"
  30. #ifdef _WIN32
  31. #include <mmsystem.h>
  32. #endif
  33. /***********************************************************/
  34. /* timers */
  35. #define QEMU_CLOCK_REALTIME 0
  36. #define QEMU_CLOCK_VIRTUAL 1
  37. #define QEMU_CLOCK_HOST 2
  38. struct QEMUClock {
  39. QEMUTimer *active_timers;
  40. NotifierList reset_notifiers;
  41. int64_t last;
  42. int type;
  43. bool enabled;
  44. };
  45. struct QEMUTimer {
  46. int64_t expire_time; /* in nanoseconds */
  47. QEMUClock *clock;
  48. QEMUTimerCB *cb;
  49. void *opaque;
  50. QEMUTimer *next;
  51. int scale;
  52. };
  53. struct qemu_alarm_timer {
  54. char const *name;
  55. int (*start)(struct qemu_alarm_timer *t);
  56. void (*stop)(struct qemu_alarm_timer *t);
  57. void (*rearm)(struct qemu_alarm_timer *t, int64_t nearest_delta_ns);
  58. #if defined(__linux__)
  59. timer_t timer;
  60. int fd;
  61. #elif defined(_WIN32)
  62. HANDLE timer;
  63. #endif
  64. bool expired;
  65. bool pending;
  66. };
  67. static struct qemu_alarm_timer *alarm_timer;
  68. static bool qemu_timer_expired_ns(QEMUTimer *timer_head, int64_t current_time)
  69. {
  70. return timer_head && (timer_head->expire_time <= current_time);
  71. }
  72. static int64_t qemu_next_alarm_deadline(void)
  73. {
  74. int64_t delta = INT64_MAX;
  75. int64_t rtdelta;
  76. if (!use_icount && vm_clock->enabled && vm_clock->active_timers) {
  77. delta = vm_clock->active_timers->expire_time -
  78. qemu_get_clock_ns(vm_clock);
  79. }
  80. if (host_clock->enabled && host_clock->active_timers) {
  81. int64_t hdelta = host_clock->active_timers->expire_time -
  82. qemu_get_clock_ns(host_clock);
  83. if (hdelta < delta) {
  84. delta = hdelta;
  85. }
  86. }
  87. if (rt_clock->enabled && rt_clock->active_timers) {
  88. rtdelta = (rt_clock->active_timers->expire_time -
  89. qemu_get_clock_ns(rt_clock));
  90. if (rtdelta < delta) {
  91. delta = rtdelta;
  92. }
  93. }
  94. return delta;
  95. }
  96. static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
  97. {
  98. int64_t nearest_delta_ns = qemu_next_alarm_deadline();
  99. if (nearest_delta_ns < INT64_MAX) {
  100. t->rearm(t, nearest_delta_ns);
  101. }
  102. }
  103. /* TODO: MIN_TIMER_REARM_NS should be optimized */
  104. #define MIN_TIMER_REARM_NS 250000
  105. #ifdef _WIN32
  106. static int mm_start_timer(struct qemu_alarm_timer *t);
  107. static void mm_stop_timer(struct qemu_alarm_timer *t);
  108. static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta);
  109. static int win32_start_timer(struct qemu_alarm_timer *t);
  110. static void win32_stop_timer(struct qemu_alarm_timer *t);
  111. static void win32_rearm_timer(struct qemu_alarm_timer *t, int64_t delta);
  112. #else
  113. static int unix_start_timer(struct qemu_alarm_timer *t);
  114. static void unix_stop_timer(struct qemu_alarm_timer *t);
  115. static void unix_rearm_timer(struct qemu_alarm_timer *t, int64_t delta);
  116. #ifdef __linux__
  117. static int dynticks_start_timer(struct qemu_alarm_timer *t);
  118. static void dynticks_stop_timer(struct qemu_alarm_timer *t);
  119. static void dynticks_rearm_timer(struct qemu_alarm_timer *t, int64_t delta);
  120. #endif /* __linux__ */
  121. #endif /* _WIN32 */
  122. static struct qemu_alarm_timer alarm_timers[] = {
  123. #ifndef _WIN32
  124. #ifdef __linux__
  125. {"dynticks", dynticks_start_timer,
  126. dynticks_stop_timer, dynticks_rearm_timer},
  127. #endif
  128. {"unix", unix_start_timer, unix_stop_timer, unix_rearm_timer},
  129. #else
  130. {"mmtimer", mm_start_timer, mm_stop_timer, mm_rearm_timer},
  131. {"dynticks", win32_start_timer, win32_stop_timer, win32_rearm_timer},
  132. #endif
  133. {NULL, }
  134. };
  135. static void show_available_alarms(void)
  136. {
  137. int i;
  138. printf("Available alarm timers, in order of precedence:\n");
  139. for (i = 0; alarm_timers[i].name; i++)
  140. printf("%s\n", alarm_timers[i].name);
  141. }
  142. void configure_alarms(char const *opt)
  143. {
  144. int i;
  145. int cur = 0;
  146. int count = ARRAY_SIZE(alarm_timers) - 1;
  147. char *arg;
  148. char *name;
  149. struct qemu_alarm_timer tmp;
  150. if (is_help_option(opt)) {
  151. show_available_alarms();
  152. exit(0);
  153. }
  154. arg = g_strdup(opt);
  155. /* Reorder the array */
  156. name = strtok(arg, ",");
  157. while (name) {
  158. for (i = 0; i < count && alarm_timers[i].name; i++) {
  159. if (!strcmp(alarm_timers[i].name, name))
  160. break;
  161. }
  162. if (i == count) {
  163. fprintf(stderr, "Unknown clock %s\n", name);
  164. goto next;
  165. }
  166. if (i < cur)
  167. /* Ignore */
  168. goto next;
  169. /* Swap */
  170. tmp = alarm_timers[i];
  171. alarm_timers[i] = alarm_timers[cur];
  172. alarm_timers[cur] = tmp;
  173. cur++;
  174. next:
  175. name = strtok(NULL, ",");
  176. }
  177. g_free(arg);
  178. if (cur) {
  179. /* Disable remaining timers */
  180. for (i = cur; i < count; i++)
  181. alarm_timers[i].name = NULL;
  182. } else {
  183. show_available_alarms();
  184. exit(1);
  185. }
  186. }
  187. QEMUClock *rt_clock;
  188. QEMUClock *vm_clock;
  189. QEMUClock *host_clock;
  190. static QEMUClock *qemu_new_clock(int type)
  191. {
  192. QEMUClock *clock;
  193. clock = g_malloc0(sizeof(QEMUClock));
  194. clock->type = type;
  195. clock->enabled = true;
  196. clock->last = INT64_MIN;
  197. notifier_list_init(&clock->reset_notifiers);
  198. return clock;
  199. }
  200. void qemu_clock_enable(QEMUClock *clock, bool enabled)
  201. {
  202. bool old = clock->enabled;
  203. clock->enabled = enabled;
  204. if (enabled && !old) {
  205. qemu_rearm_alarm_timer(alarm_timer);
  206. }
  207. }
  208. int64_t qemu_clock_has_timers(QEMUClock *clock)
  209. {
  210. return !!clock->active_timers;
  211. }
  212. int64_t qemu_clock_expired(QEMUClock *clock)
  213. {
  214. return (clock->active_timers &&
  215. clock->active_timers->expire_time < qemu_get_clock_ns(clock));
  216. }
  217. int64_t qemu_clock_deadline(QEMUClock *clock)
  218. {
  219. /* To avoid problems with overflow limit this to 2^32. */
  220. int64_t delta = INT32_MAX;
  221. if (clock->active_timers) {
  222. delta = clock->active_timers->expire_time - qemu_get_clock_ns(clock);
  223. }
  224. if (delta < 0) {
  225. delta = 0;
  226. }
  227. return delta;
  228. }
  229. QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
  230. QEMUTimerCB *cb, void *opaque)
  231. {
  232. QEMUTimer *ts;
  233. ts = g_malloc0(sizeof(QEMUTimer));
  234. ts->clock = clock;
  235. ts->cb = cb;
  236. ts->opaque = opaque;
  237. ts->scale = scale;
  238. return ts;
  239. }
  240. void qemu_free_timer(QEMUTimer *ts)
  241. {
  242. g_free(ts);
  243. }
  244. /* stop a timer, but do not dealloc it */
  245. void qemu_del_timer(QEMUTimer *ts)
  246. {
  247. QEMUTimer **pt, *t;
  248. /* NOTE: this code must be signal safe because
  249. qemu_timer_expired() can be called from a signal. */
  250. pt = &ts->clock->active_timers;
  251. for(;;) {
  252. t = *pt;
  253. if (!t)
  254. break;
  255. if (t == ts) {
  256. *pt = t->next;
  257. break;
  258. }
  259. pt = &t->next;
  260. }
  261. }
  262. /* modify the current timer so that it will be fired when current_time
  263. >= expire_time. The corresponding callback will be called. */
  264. void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time)
  265. {
  266. QEMUTimer **pt, *t;
  267. qemu_del_timer(ts);
  268. /* add the timer in the sorted list */
  269. /* NOTE: this code must be signal safe because
  270. qemu_timer_expired() can be called from a signal. */
  271. pt = &ts->clock->active_timers;
  272. for(;;) {
  273. t = *pt;
  274. if (!qemu_timer_expired_ns(t, expire_time)) {
  275. break;
  276. }
  277. pt = &t->next;
  278. }
  279. ts->expire_time = expire_time;
  280. ts->next = *pt;
  281. *pt = ts;
  282. /* Rearm if necessary */
  283. if (pt == &ts->clock->active_timers) {
  284. if (!alarm_timer->pending) {
  285. qemu_rearm_alarm_timer(alarm_timer);
  286. }
  287. /* Interrupt execution to force deadline recalculation. */
  288. qemu_clock_warp(ts->clock);
  289. if (use_icount) {
  290. qemu_notify_event();
  291. }
  292. }
  293. }
  294. void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
  295. {
  296. qemu_mod_timer_ns(ts, expire_time * ts->scale);
  297. }
  298. bool qemu_timer_pending(QEMUTimer *ts)
  299. {
  300. QEMUTimer *t;
  301. for (t = ts->clock->active_timers; t != NULL; t = t->next) {
  302. if (t == ts) {
  303. return true;
  304. }
  305. }
  306. return false;
  307. }
  308. bool qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
  309. {
  310. return qemu_timer_expired_ns(timer_head, current_time * timer_head->scale);
  311. }
  312. void qemu_run_timers(QEMUClock *clock)
  313. {
  314. QEMUTimer **ptimer_head, *ts;
  315. int64_t current_time;
  316. if (!clock->enabled)
  317. return;
  318. current_time = qemu_get_clock_ns(clock);
  319. ptimer_head = &clock->active_timers;
  320. for(;;) {
  321. ts = *ptimer_head;
  322. if (!qemu_timer_expired_ns(ts, current_time)) {
  323. break;
  324. }
  325. /* remove timer from the list before calling the callback */
  326. *ptimer_head = ts->next;
  327. ts->next = NULL;
  328. /* run the callback (the timer list can be modified) */
  329. ts->cb(ts->opaque);
  330. }
  331. }
  332. int64_t qemu_get_clock_ns(QEMUClock *clock)
  333. {
  334. int64_t now, last;
  335. switch(clock->type) {
  336. case QEMU_CLOCK_REALTIME:
  337. return get_clock();
  338. default:
  339. case QEMU_CLOCK_VIRTUAL:
  340. if (use_icount) {
  341. return cpu_get_icount();
  342. } else {
  343. return cpu_get_clock();
  344. }
  345. case QEMU_CLOCK_HOST:
  346. now = get_clock_realtime();
  347. last = clock->last;
  348. clock->last = now;
  349. if (now < last) {
  350. notifier_list_notify(&clock->reset_notifiers, &now);
  351. }
  352. return now;
  353. }
  354. }
  355. void qemu_register_clock_reset_notifier(QEMUClock *clock, Notifier *notifier)
  356. {
  357. notifier_list_add(&clock->reset_notifiers, notifier);
  358. }
  359. void qemu_unregister_clock_reset_notifier(QEMUClock *clock, Notifier *notifier)
  360. {
  361. notifier_remove(notifier);
  362. }
  363. void init_clocks(void)
  364. {
  365. rt_clock = qemu_new_clock(QEMU_CLOCK_REALTIME);
  366. vm_clock = qemu_new_clock(QEMU_CLOCK_VIRTUAL);
  367. host_clock = qemu_new_clock(QEMU_CLOCK_HOST);
  368. }
  369. uint64_t qemu_timer_expire_time_ns(QEMUTimer *ts)
  370. {
  371. return qemu_timer_pending(ts) ? ts->expire_time : -1;
  372. }
  373. void qemu_run_all_timers(void)
  374. {
  375. alarm_timer->pending = false;
  376. /* vm time timers */
  377. qemu_run_timers(vm_clock);
  378. qemu_run_timers(rt_clock);
  379. qemu_run_timers(host_clock);
  380. /* rearm timer, if not periodic */
  381. if (alarm_timer->expired) {
  382. alarm_timer->expired = false;
  383. qemu_rearm_alarm_timer(alarm_timer);
  384. }
  385. }
  386. #ifdef _WIN32
  387. static void CALLBACK host_alarm_handler(PVOID lpParam, BOOLEAN unused)
  388. #else
  389. static void host_alarm_handler(int host_signum)
  390. #endif
  391. {
  392. struct qemu_alarm_timer *t = alarm_timer;
  393. if (!t)
  394. return;
  395. t->expired = true;
  396. t->pending = true;
  397. qemu_notify_event();
  398. }
  399. #if defined(__linux__)
  400. #include "compatfd.h"
  401. static int dynticks_start_timer(struct qemu_alarm_timer *t)
  402. {
  403. struct sigevent ev;
  404. timer_t host_timer;
  405. struct sigaction act;
  406. sigfillset(&act.sa_mask);
  407. act.sa_flags = 0;
  408. act.sa_handler = host_alarm_handler;
  409. sigaction(SIGALRM, &act, NULL);
  410. /*
  411. * Initialize ev struct to 0 to avoid valgrind complaining
  412. * about uninitialized data in timer_create call
  413. */
  414. memset(&ev, 0, sizeof(ev));
  415. ev.sigev_value.sival_int = 0;
  416. ev.sigev_notify = SIGEV_SIGNAL;
  417. #ifdef SIGEV_THREAD_ID
  418. if (qemu_signalfd_available()) {
  419. ev.sigev_notify = SIGEV_THREAD_ID;
  420. ev._sigev_un._tid = qemu_get_thread_id();
  421. }
  422. #endif /* SIGEV_THREAD_ID */
  423. ev.sigev_signo = SIGALRM;
  424. if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) {
  425. perror("timer_create");
  426. return -1;
  427. }
  428. t->timer = host_timer;
  429. return 0;
  430. }
  431. static void dynticks_stop_timer(struct qemu_alarm_timer *t)
  432. {
  433. timer_t host_timer = t->timer;
  434. timer_delete(host_timer);
  435. }
  436. static void dynticks_rearm_timer(struct qemu_alarm_timer *t,
  437. int64_t nearest_delta_ns)
  438. {
  439. timer_t host_timer = t->timer;
  440. struct itimerspec timeout;
  441. int64_t current_ns;
  442. if (nearest_delta_ns < MIN_TIMER_REARM_NS)
  443. nearest_delta_ns = MIN_TIMER_REARM_NS;
  444. /* check whether a timer is already running */
  445. if (timer_gettime(host_timer, &timeout)) {
  446. perror("gettime");
  447. fprintf(stderr, "Internal timer error: aborting\n");
  448. exit(1);
  449. }
  450. current_ns = timeout.it_value.tv_sec * 1000000000LL + timeout.it_value.tv_nsec;
  451. if (current_ns && current_ns <= nearest_delta_ns)
  452. return;
  453. timeout.it_interval.tv_sec = 0;
  454. timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */
  455. timeout.it_value.tv_sec = nearest_delta_ns / 1000000000;
  456. timeout.it_value.tv_nsec = nearest_delta_ns % 1000000000;
  457. if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) {
  458. perror("settime");
  459. fprintf(stderr, "Internal timer error: aborting\n");
  460. exit(1);
  461. }
  462. }
  463. #endif /* defined(__linux__) */
  464. #if !defined(_WIN32)
  465. static int unix_start_timer(struct qemu_alarm_timer *t)
  466. {
  467. struct sigaction act;
  468. /* timer signal */
  469. sigfillset(&act.sa_mask);
  470. act.sa_flags = 0;
  471. act.sa_handler = host_alarm_handler;
  472. sigaction(SIGALRM, &act, NULL);
  473. return 0;
  474. }
  475. static void unix_rearm_timer(struct qemu_alarm_timer *t,
  476. int64_t nearest_delta_ns)
  477. {
  478. struct itimerval itv;
  479. int err;
  480. if (nearest_delta_ns < MIN_TIMER_REARM_NS)
  481. nearest_delta_ns = MIN_TIMER_REARM_NS;
  482. itv.it_interval.tv_sec = 0;
  483. itv.it_interval.tv_usec = 0; /* 0 for one-shot timer */
  484. itv.it_value.tv_sec = nearest_delta_ns / 1000000000;
  485. itv.it_value.tv_usec = (nearest_delta_ns % 1000000000) / 1000;
  486. err = setitimer(ITIMER_REAL, &itv, NULL);
  487. if (err) {
  488. perror("setitimer");
  489. fprintf(stderr, "Internal timer error: aborting\n");
  490. exit(1);
  491. }
  492. }
  493. static void unix_stop_timer(struct qemu_alarm_timer *t)
  494. {
  495. struct itimerval itv;
  496. memset(&itv, 0, sizeof(itv));
  497. setitimer(ITIMER_REAL, &itv, NULL);
  498. }
  499. #endif /* !defined(_WIN32) */
  500. #ifdef _WIN32
  501. static MMRESULT mm_timer;
  502. static TIMECAPS mm_tc;
  503. static void CALLBACK mm_alarm_handler(UINT uTimerID, UINT uMsg,
  504. DWORD_PTR dwUser, DWORD_PTR dw1,
  505. DWORD_PTR dw2)
  506. {
  507. struct qemu_alarm_timer *t = alarm_timer;
  508. if (!t) {
  509. return;
  510. }
  511. t->expired = true;
  512. t->pending = true;
  513. qemu_notify_event();
  514. }
  515. static int mm_start_timer(struct qemu_alarm_timer *t)
  516. {
  517. timeGetDevCaps(&mm_tc, sizeof(mm_tc));
  518. timeBeginPeriod(mm_tc.wPeriodMin);
  519. mm_timer = timeSetEvent(mm_tc.wPeriodMin, /* interval (ms) */
  520. mm_tc.wPeriodMin, /* resolution */
  521. mm_alarm_handler, /* function */
  522. (DWORD_PTR)t, /* parameter */
  523. TIME_ONESHOT | TIME_CALLBACK_FUNCTION);
  524. if (!mm_timer) {
  525. fprintf(stderr, "Failed to initialize win32 alarm timer\n");
  526. timeEndPeriod(mm_tc.wPeriodMin);
  527. return -1;
  528. }
  529. return 0;
  530. }
  531. static void mm_stop_timer(struct qemu_alarm_timer *t)
  532. {
  533. timeKillEvent(mm_timer);
  534. timeEndPeriod(mm_tc.wPeriodMin);
  535. }
  536. static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta)
  537. {
  538. int64_t nearest_delta_ms = delta / 1000000;
  539. if (nearest_delta_ms < mm_tc.wPeriodMin) {
  540. nearest_delta_ms = mm_tc.wPeriodMin;
  541. } else if (nearest_delta_ms > mm_tc.wPeriodMax) {
  542. nearest_delta_ms = mm_tc.wPeriodMax;
  543. }
  544. timeKillEvent(mm_timer);
  545. mm_timer = timeSetEvent((UINT)nearest_delta_ms,
  546. mm_tc.wPeriodMin,
  547. mm_alarm_handler,
  548. (DWORD_PTR)t,
  549. TIME_ONESHOT | TIME_CALLBACK_FUNCTION);
  550. if (!mm_timer) {
  551. fprintf(stderr, "Failed to re-arm win32 alarm timer\n");
  552. timeEndPeriod(mm_tc.wPeriodMin);
  553. exit(1);
  554. }
  555. }
  556. static int win32_start_timer(struct qemu_alarm_timer *t)
  557. {
  558. HANDLE hTimer;
  559. BOOLEAN success;
  560. /* If you call ChangeTimerQueueTimer on a one-shot timer (its period
  561. is zero) that has already expired, the timer is not updated. Since
  562. creating a new timer is relatively expensive, set a bogus one-hour
  563. interval in the dynticks case. */
  564. success = CreateTimerQueueTimer(&hTimer,
  565. NULL,
  566. host_alarm_handler,
  567. t,
  568. 1,
  569. 3600000,
  570. WT_EXECUTEINTIMERTHREAD);
  571. if (!success) {
  572. fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n",
  573. GetLastError());
  574. return -1;
  575. }
  576. t->timer = hTimer;
  577. return 0;
  578. }
  579. static void win32_stop_timer(struct qemu_alarm_timer *t)
  580. {
  581. HANDLE hTimer = t->timer;
  582. if (hTimer) {
  583. DeleteTimerQueueTimer(NULL, hTimer, NULL);
  584. }
  585. }
  586. static void win32_rearm_timer(struct qemu_alarm_timer *t,
  587. int64_t nearest_delta_ns)
  588. {
  589. HANDLE hTimer = t->timer;
  590. int64_t nearest_delta_ms;
  591. BOOLEAN success;
  592. nearest_delta_ms = nearest_delta_ns / 1000000;
  593. if (nearest_delta_ms < 1) {
  594. nearest_delta_ms = 1;
  595. }
  596. /* ULONG_MAX can be 32 bit */
  597. if (nearest_delta_ms > ULONG_MAX) {
  598. nearest_delta_ms = ULONG_MAX;
  599. }
  600. success = ChangeTimerQueueTimer(NULL,
  601. hTimer,
  602. (unsigned long) nearest_delta_ms,
  603. 3600000);
  604. if (!success) {
  605. fprintf(stderr, "Failed to rearm win32 alarm timer: %ld\n",
  606. GetLastError());
  607. exit(-1);
  608. }
  609. }
  610. #endif /* _WIN32 */
  611. static void quit_timers(void)
  612. {
  613. struct qemu_alarm_timer *t = alarm_timer;
  614. alarm_timer = NULL;
  615. t->stop(t);
  616. }
  617. int init_timer_alarm(void)
  618. {
  619. struct qemu_alarm_timer *t = NULL;
  620. int i, err = -1;
  621. for (i = 0; alarm_timers[i].name; i++) {
  622. t = &alarm_timers[i];
  623. err = t->start(t);
  624. if (!err)
  625. break;
  626. }
  627. if (err) {
  628. err = -ENOENT;
  629. goto fail;
  630. }
  631. atexit(quit_timers);
  632. alarm_timer = t;
  633. return 0;
  634. fail:
  635. return err;
  636. }