xref: /qemu/util/qemu-timer.c (revision 6d327171551a12b937c5718073b9848d0274c74d)
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 
25 #include "sysemu/sysemu.h"
26 #include "monitor/monitor.h"
27 #include "ui/console.h"
28 
29 #include "hw/hw.h"
30 
31 #include "qemu/timer.h"
32 #ifdef CONFIG_POSIX
33 #include <pthread.h>
34 #endif
35 
36 #ifdef CONFIG_PPOLL
37 #include <poll.h>
38 #endif
39 
40 #ifdef CONFIG_PRCTL_PR_SET_TIMERSLACK
41 #include <sys/prctl.h>
42 #endif
43 
44 /***********************************************************/
45 /* timers */
46 
47 struct QEMUClock {
48     QEMUTimerList *main_loop_timerlist;
49     QLIST_HEAD(, QEMUTimerList) timerlists;
50 
51     NotifierList reset_notifiers;
52     int64_t last;
53 
54     QEMUClockType type;
55     bool enabled;
56 };
57 
58 QEMUTimerListGroup main_loop_tlg;
59 QEMUClock *qemu_clocks[QEMU_CLOCK_MAX];
60 
61 /* A QEMUTimerList is a list of timers attached to a clock. More
62  * than one QEMUTimerList can be attached to each clock, for instance
63  * used by different AioContexts / threads. Each clock also has
64  * a list of the QEMUTimerLists associated with it, in order that
65  * reenabling the clock can call all the notifiers.
66  */
67 
68 struct QEMUTimerList {
69     QEMUClock *clock;
70     QEMUTimer *active_timers;
71     QLIST_ENTRY(QEMUTimerList) list;
72     QEMUTimerListNotifyCB *notify_cb;
73     void *notify_opaque;
74 };
75 
76 static bool timer_expired_ns(QEMUTimer *timer_head, int64_t current_time)
77 {
78     return timer_head && (timer_head->expire_time <= current_time);
79 }
80 
81 static QEMUTimerList *timerlist_new_from_clock(QEMUClock *clock,
82                                                QEMUTimerListNotifyCB *cb,
83                                                void *opaque)
84 {
85     QEMUTimerList *timer_list;
86 
87     /* Assert if we do not have a clock. If you see this
88      * assertion in means that the clocks have not been
89      * initialised before a timerlist is needed. This
90      * normally happens if an AioContext is used before
91      * init_clocks() is called within main().
92      */
93     assert(clock);
94 
95     timer_list = g_malloc0(sizeof(QEMUTimerList));
96     timer_list->clock = clock;
97     timer_list->notify_cb = cb;
98     timer_list->notify_opaque = opaque;
99     QLIST_INSERT_HEAD(&clock->timerlists, timer_list, list);
100     return timer_list;
101 }
102 
103 QEMUTimerList *timerlist_new(QEMUClockType type,
104                              QEMUTimerListNotifyCB *cb, void *opaque)
105 {
106     return timerlist_new_from_clock(qemu_clock_ptr(type), cb, opaque);
107 }
108 
109 void timerlist_free(QEMUTimerList *timer_list)
110 {
111     assert(!timerlist_has_timers(timer_list));
112     if (timer_list->clock) {
113         QLIST_REMOVE(timer_list, list);
114         if (timer_list->clock->main_loop_timerlist == timer_list) {
115             timer_list->clock->main_loop_timerlist = NULL;
116         }
117     }
118     g_free(timer_list);
119 }
120 
121 static QEMUClock *qemu_clock_new(QEMUClockType type)
122 {
123     QEMUClock *clock;
124 
125     clock = g_malloc0(sizeof(QEMUClock));
126     clock->type = type;
127     clock->enabled = true;
128     clock->last = INT64_MIN;
129     QLIST_INIT(&clock->timerlists);
130     notifier_list_init(&clock->reset_notifiers);
131     clock->main_loop_timerlist = timerlist_new_from_clock(clock, NULL, NULL);
132     return clock;
133 }
134 
135 bool qemu_clock_use_for_deadline(QEMUClock *clock)
136 {
137     return !(use_icount && (clock->type == QEMU_CLOCK_VIRTUAL));
138 }
139 
140 void qemu_clock_notify(QEMUClock *clock)
141 {
142     QEMUTimerList *timer_list;
143     QLIST_FOREACH(timer_list, &clock->timerlists, list) {
144         timerlist_notify(timer_list);
145     }
146 }
147 
148 void qemu_clock_enable(QEMUClock *clock, bool enabled)
149 {
150     bool old = clock->enabled;
151     clock->enabled = enabled;
152     if (enabled && !old) {
153         qemu_clock_notify(clock);
154     }
155 }
156 
157 bool timerlist_has_timers(QEMUTimerList *timer_list)
158 {
159     return !!timer_list->active_timers;
160 }
161 
162 bool qemu_clock_has_timers(QEMUClock *clock)
163 {
164     return timerlist_has_timers(clock->main_loop_timerlist);
165 }
166 
167 bool timerlist_expired(QEMUTimerList *timer_list)
168 {
169     return (timer_list->active_timers &&
170             timer_list->active_timers->expire_time <
171             qemu_get_clock_ns(timer_list->clock));
172 }
173 
174 bool qemu_clock_expired(QEMUClock *clock)
175 {
176     return timerlist_expired(clock->main_loop_timerlist);
177 }
178 
179 int64_t timerlist_deadline(QEMUTimerList *timer_list)
180 {
181     /* To avoid problems with overflow limit this to 2^32.  */
182     int64_t delta = INT32_MAX;
183 
184     if (timer_list->clock->enabled && timer_list->active_timers) {
185         delta = timer_list->active_timers->expire_time -
186             qemu_get_clock_ns(timer_list->clock);
187     }
188     if (delta < 0) {
189         delta = 0;
190     }
191     return delta;
192 }
193 
194 int64_t qemu_clock_deadline(QEMUClock *clock)
195 {
196     return timerlist_deadline(clock->main_loop_timerlist);
197 }
198 
199 /*
200  * As above, but return -1 for no deadline, and do not cap to 2^32
201  * as we know the result is always positive.
202  */
203 
204 int64_t timerlist_deadline_ns(QEMUTimerList *timer_list)
205 {
206     int64_t delta;
207 
208     if (!timer_list->clock->enabled || !timer_list->active_timers) {
209         return -1;
210     }
211 
212     delta = timer_list->active_timers->expire_time -
213         qemu_get_clock_ns(timer_list->clock);
214 
215     if (delta <= 0) {
216         return 0;
217     }
218 
219     return delta;
220 }
221 
222 int64_t qemu_clock_deadline_ns(QEMUClock *clock)
223 {
224     return timerlist_deadline_ns(clock->main_loop_timerlist);
225 }
226 
227 /* Calculate the soonest deadline across all timerlists attached
228  * to the clock. This is used for the icount timeout so we
229  * ignore whether or not the clock should be used in deadline
230  * calculations.
231  */
232 int64_t qemu_clock_deadline_ns_all(QEMUClock *clock)
233 {
234     int64_t deadline = -1;
235     QEMUTimerList *timer_list;
236     QLIST_FOREACH(timer_list, &clock->timerlists, list) {
237         deadline = qemu_soonest_timeout(deadline,
238                                         timerlist_deadline_ns(timer_list));
239     }
240     return deadline;
241 }
242 
243 QEMUClock *timerlist_get_clock(QEMUTimerList *timer_list)
244 {
245     return timer_list->clock;
246 }
247 
248 QEMUTimerList *qemu_clock_get_main_loop_timerlist(QEMUClock *clock)
249 {
250     return clock->main_loop_timerlist;
251 }
252 
253 void timerlist_notify(QEMUTimerList *timer_list)
254 {
255     if (timer_list->notify_cb) {
256         timer_list->notify_cb(timer_list->notify_opaque);
257     } else {
258         qemu_notify_event();
259     }
260 }
261 
262 /* Transition function to convert a nanosecond timeout to ms
263  * This is used where a system does not support ppoll
264  */
265 int qemu_timeout_ns_to_ms(int64_t ns)
266 {
267     int64_t ms;
268     if (ns < 0) {
269         return -1;
270     }
271 
272     if (!ns) {
273         return 0;
274     }
275 
276     /* Always round up, because it's better to wait too long than to wait too
277      * little and effectively busy-wait
278      */
279     ms = (ns + SCALE_MS - 1) / SCALE_MS;
280 
281     /* To avoid overflow problems, limit this to 2^31, i.e. approx 25 days */
282     if (ms > (int64_t) INT32_MAX) {
283         ms = INT32_MAX;
284     }
285 
286     return (int) ms;
287 }
288 
289 
290 /* qemu implementation of g_poll which uses a nanosecond timeout but is
291  * otherwise identical to g_poll
292  */
293 int qemu_poll_ns(GPollFD *fds, guint nfds, int64_t timeout)
294 {
295 #ifdef CONFIG_PPOLL
296     if (timeout < 0) {
297         return ppoll((struct pollfd *)fds, nfds, NULL, NULL);
298     } else {
299         struct timespec ts;
300         ts.tv_sec = timeout / 1000000000LL;
301         ts.tv_nsec = timeout % 1000000000LL;
302         return ppoll((struct pollfd *)fds, nfds, &ts, NULL);
303     }
304 #else
305     return g_poll(fds, nfds, qemu_timeout_ns_to_ms(timeout));
306 #endif
307 }
308 
309 
310 void timer_init(QEMUTimer *ts,
311                 QEMUTimerList *timer_list, int scale,
312                 QEMUTimerCB *cb, void *opaque)
313 {
314     ts->timer_list = timer_list;
315     ts->cb = cb;
316     ts->opaque = opaque;
317     ts->scale = scale;
318 }
319 
320 QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
321                           QEMUTimerCB *cb, void *opaque)
322 {
323     return timer_new_tl(clock->main_loop_timerlist,
324                      scale, cb, opaque);
325 }
326 
327 void qemu_free_timer(QEMUTimer *ts)
328 {
329     g_free(ts);
330 }
331 
332 /* stop a timer, but do not dealloc it */
333 void qemu_del_timer(QEMUTimer *ts)
334 {
335     QEMUTimer **pt, *t;
336 
337     /* NOTE: this code must be signal safe because
338        timer_expired() can be called from a signal. */
339     pt = &ts->timer_list->active_timers;
340     for(;;) {
341         t = *pt;
342         if (!t)
343             break;
344         if (t == ts) {
345             *pt = t->next;
346             break;
347         }
348         pt = &t->next;
349     }
350 }
351 
352 /* modify the current timer so that it will be fired when current_time
353    >= expire_time. The corresponding callback will be called. */
354 void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time)
355 {
356     QEMUTimer **pt, *t;
357 
358     qemu_del_timer(ts);
359 
360     /* add the timer in the sorted list */
361     /* NOTE: this code must be signal safe because
362        timer_expired() can be called from a signal. */
363     pt = &ts->timer_list->active_timers;
364     for(;;) {
365         t = *pt;
366         if (!timer_expired_ns(t, expire_time)) {
367             break;
368         }
369         pt = &t->next;
370     }
371     ts->expire_time = expire_time;
372     ts->next = *pt;
373     *pt = ts;
374 
375     /* Rearm if necessary  */
376     if (pt == &ts->timer_list->active_timers) {
377         /* Interrupt execution to force deadline recalculation.  */
378         qemu_clock_warp(ts->timer_list->clock);
379         timerlist_notify(ts->timer_list);
380     }
381 }
382 
383 void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
384 {
385     qemu_mod_timer_ns(ts, expire_time * ts->scale);
386 }
387 
388 bool timer_pending(QEMUTimer *ts)
389 {
390     QEMUTimer *t;
391     for (t = ts->timer_list->active_timers; t != NULL; t = t->next) {
392         if (t == ts) {
393             return true;
394         }
395     }
396     return false;
397 }
398 
399 bool timer_expired(QEMUTimer *timer_head, int64_t current_time)
400 {
401     return timer_expired_ns(timer_head, current_time * timer_head->scale);
402 }
403 
404 bool timerlist_run_timers(QEMUTimerList *timer_list)
405 {
406     QEMUTimer *ts;
407     int64_t current_time;
408     bool progress = false;
409 
410     if (!timer_list->clock->enabled) {
411         return progress;
412     }
413 
414     current_time = qemu_get_clock_ns(timer_list->clock);
415     for(;;) {
416         ts = timer_list->active_timers;
417         if (!timer_expired_ns(ts, current_time)) {
418             break;
419         }
420         /* remove timer from the list before calling the callback */
421         timer_list->active_timers = ts->next;
422         ts->next = NULL;
423 
424         /* run the callback (the timer list can be modified) */
425         ts->cb(ts->opaque);
426         progress = true;
427     }
428     return progress;
429 }
430 
431 bool qemu_run_timers(QEMUClock *clock)
432 {
433     return timerlist_run_timers(clock->main_loop_timerlist);
434 }
435 
436 void timerlistgroup_init(QEMUTimerListGroup *tlg,
437                          QEMUTimerListNotifyCB *cb, void *opaque)
438 {
439     QEMUClockType type;
440     for (type = 0; type < QEMU_CLOCK_MAX; type++) {
441         tlg->tl[type] = timerlist_new(type, cb, opaque);
442     }
443 }
444 
445 void timerlistgroup_deinit(QEMUTimerListGroup *tlg)
446 {
447     QEMUClockType type;
448     for (type = 0; type < QEMU_CLOCK_MAX; type++) {
449         timerlist_free(tlg->tl[type]);
450     }
451 }
452 
453 bool timerlistgroup_run_timers(QEMUTimerListGroup *tlg)
454 {
455     QEMUClockType type;
456     bool progress = false;
457     for (type = 0; type < QEMU_CLOCK_MAX; type++) {
458         progress |= timerlist_run_timers(tlg->tl[type]);
459     }
460     return progress;
461 }
462 
463 int64_t timerlistgroup_deadline_ns(QEMUTimerListGroup *tlg)
464 {
465     int64_t deadline = -1;
466     QEMUClockType type;
467     for (type = 0; type < QEMU_CLOCK_MAX; type++) {
468         if (qemu_clock_use_for_deadline(tlg->tl[type]->clock)) {
469             deadline = qemu_soonest_timeout(deadline,
470                                             timerlist_deadline_ns(
471                                                 tlg->tl[type]));
472         }
473     }
474     return deadline;
475 }
476 
477 int64_t qemu_get_clock_ns(QEMUClock *clock)
478 {
479     int64_t now, last;
480 
481     switch(clock->type) {
482     case QEMU_CLOCK_REALTIME:
483         return get_clock();
484     default:
485     case QEMU_CLOCK_VIRTUAL:
486         if (use_icount) {
487             return cpu_get_icount();
488         } else {
489             return cpu_get_clock();
490         }
491     case QEMU_CLOCK_HOST:
492         now = get_clock_realtime();
493         last = clock->last;
494         clock->last = now;
495         if (now < last) {
496             notifier_list_notify(&clock->reset_notifiers, &now);
497         }
498         return now;
499     }
500 }
501 
502 void qemu_register_clock_reset_notifier(QEMUClock *clock, Notifier *notifier)
503 {
504     notifier_list_add(&clock->reset_notifiers, notifier);
505 }
506 
507 void qemu_unregister_clock_reset_notifier(QEMUClock *clock, Notifier *notifier)
508 {
509     notifier_remove(notifier);
510 }
511 
512 void init_clocks(void)
513 {
514     QEMUClockType type;
515     for (type = 0; type < QEMU_CLOCK_MAX; type++) {
516         if (!qemu_clocks[type]) {
517             qemu_clocks[type] = qemu_clock_new(type);
518             main_loop_tlg.tl[type] = qemu_clocks[type]->main_loop_timerlist;
519         }
520     }
521 
522 #ifdef CONFIG_PRCTL_PR_SET_TIMERSLACK
523     prctl(PR_SET_TIMERSLACK, 1, 0, 0, 0);
524 #endif
525 }
526 
527 uint64_t timer_expire_time_ns(QEMUTimer *ts)
528 {
529     return timer_pending(ts) ? ts->expire_time : -1;
530 }
531 
532 bool qemu_run_all_timers(void)
533 {
534     bool progress = false;
535     QEMUClockType type;
536 
537     for (type = 0; type < QEMU_CLOCK_MAX; type++) {
538         progress |= qemu_run_timers(qemu_clock_ptr(type));
539     }
540 
541     return progress;
542 }
543