replay: recording and replaying clock ticks
[sdk/emulator/qemu.git] / qemu-timer.c
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 "qemu/main-loop.h"
26 #include "qemu/timer.h"
27 #include "sysemu/replay.h"
28
29 #ifdef CONFIG_POSIX
30 #include <pthread.h>
31 #endif
32
33 #ifdef CONFIG_PPOLL
34 #include <poll.h>
35 #endif
36
37 #ifdef CONFIG_PRCTL_PR_SET_TIMERSLACK
38 #include <sys/prctl.h>
39 #endif
40
41 /***********************************************************/
42 /* timers */
43
44 typedef struct QEMUClock {
45     /* We rely on BQL to protect the timerlists */
46     QLIST_HEAD(, QEMUTimerList) timerlists;
47
48     NotifierList reset_notifiers;
49     int64_t last;
50
51     QEMUClockType type;
52     bool enabled;
53 } QEMUClock;
54
55 QEMUTimerListGroup main_loop_tlg;
56 static QEMUClock qemu_clocks[QEMU_CLOCK_MAX];
57
58 /* A QEMUTimerList is a list of timers attached to a clock. More
59  * than one QEMUTimerList can be attached to each clock, for instance
60  * used by different AioContexts / threads. Each clock also has
61  * a list of the QEMUTimerLists associated with it, in order that
62  * reenabling the clock can call all the notifiers.
63  */
64
65 struct QEMUTimerList {
66     QEMUClock *clock;
67     QemuMutex active_timers_lock;
68     QEMUTimer *active_timers;
69     QLIST_ENTRY(QEMUTimerList) list;
70     QEMUTimerListNotifyCB *notify_cb;
71     void *notify_opaque;
72
73     /* lightweight method to mark the end of timerlist's running */
74     QemuEvent timers_done_ev;
75 };
76
77 /**
78  * qemu_clock_ptr:
79  * @type: type of clock
80  *
81  * Translate a clock type into a pointer to QEMUClock object.
82  *
83  * Returns: a pointer to the QEMUClock object
84  */
85 static inline QEMUClock *qemu_clock_ptr(QEMUClockType type)
86 {
87     return &qemu_clocks[type];
88 }
89
90 static bool timer_expired_ns(QEMUTimer *timer_head, int64_t current_time)
91 {
92     return timer_head && (timer_head->expire_time <= current_time);
93 }
94
95 QEMUTimerList *timerlist_new(QEMUClockType type,
96                              QEMUTimerListNotifyCB *cb,
97                              void *opaque)
98 {
99     QEMUTimerList *timer_list;
100     QEMUClock *clock = qemu_clock_ptr(type);
101
102     timer_list = g_malloc0(sizeof(QEMUTimerList));
103     qemu_event_init(&timer_list->timers_done_ev, true);
104     timer_list->clock = clock;
105     timer_list->notify_cb = cb;
106     timer_list->notify_opaque = opaque;
107     qemu_mutex_init(&timer_list->active_timers_lock);
108     QLIST_INSERT_HEAD(&clock->timerlists, timer_list, list);
109     return timer_list;
110 }
111
112 void timerlist_free(QEMUTimerList *timer_list)
113 {
114     assert(!timerlist_has_timers(timer_list));
115     if (timer_list->clock) {
116         QLIST_REMOVE(timer_list, list);
117     }
118     qemu_mutex_destroy(&timer_list->active_timers_lock);
119     g_free(timer_list);
120 }
121
122 static void qemu_clock_init(QEMUClockType type)
123 {
124     QEMUClock *clock = qemu_clock_ptr(type);
125
126     /* Assert that the clock of type TYPE has not been initialized yet. */
127     assert(main_loop_tlg.tl[type] == NULL);
128
129     clock->type = type;
130     clock->enabled = true;
131     clock->last = INT64_MIN;
132     QLIST_INIT(&clock->timerlists);
133     notifier_list_init(&clock->reset_notifiers);
134     main_loop_tlg.tl[type] = timerlist_new(type, NULL, NULL);
135 }
136
137 bool qemu_clock_use_for_deadline(QEMUClockType type)
138 {
139     return !(use_icount && (type == QEMU_CLOCK_VIRTUAL));
140 }
141
142 void qemu_clock_notify(QEMUClockType type)
143 {
144     QEMUTimerList *timer_list;
145     QEMUClock *clock = qemu_clock_ptr(type);
146     QLIST_FOREACH(timer_list, &clock->timerlists, list) {
147         timerlist_notify(timer_list);
148     }
149 }
150
151 /* Disabling the clock will wait for related timerlists to stop
152  * executing qemu_run_timers.  Thus, this functions should not
153  * be used from the callback of a timer that is based on @clock.
154  * Doing so would cause a deadlock.
155  *
156  * Caller should hold BQL.
157  */
158 void qemu_clock_enable(QEMUClockType type, bool enabled)
159 {
160     QEMUClock *clock = qemu_clock_ptr(type);
161     QEMUTimerList *tl;
162     bool old = clock->enabled;
163     clock->enabled = enabled;
164     if (enabled && !old) {
165         qemu_clock_notify(type);
166     } else if (!enabled && old) {
167         QLIST_FOREACH(tl, &clock->timerlists, list) {
168             qemu_event_wait(&tl->timers_done_ev);
169         }
170     }
171 }
172
173 bool timerlist_has_timers(QEMUTimerList *timer_list)
174 {
175     return !!timer_list->active_timers;
176 }
177
178 bool qemu_clock_has_timers(QEMUClockType type)
179 {
180     return timerlist_has_timers(
181         main_loop_tlg.tl[type]);
182 }
183
184 bool timerlist_expired(QEMUTimerList *timer_list)
185 {
186     int64_t expire_time;
187
188     qemu_mutex_lock(&timer_list->active_timers_lock);
189     if (!timer_list->active_timers) {
190         qemu_mutex_unlock(&timer_list->active_timers_lock);
191         return false;
192     }
193     expire_time = timer_list->active_timers->expire_time;
194     qemu_mutex_unlock(&timer_list->active_timers_lock);
195
196     return expire_time < qemu_clock_get_ns(timer_list->clock->type);
197 }
198
199 bool qemu_clock_expired(QEMUClockType type)
200 {
201     return timerlist_expired(
202         main_loop_tlg.tl[type]);
203 }
204
205 /*
206  * As above, but return -1 for no deadline, and do not cap to 2^32
207  * as we know the result is always positive.
208  */
209
210 int64_t timerlist_deadline_ns(QEMUTimerList *timer_list)
211 {
212     int64_t delta;
213     int64_t expire_time;
214
215     if (!timer_list->clock->enabled) {
216         return -1;
217     }
218
219     /* The active timers list may be modified before the caller uses our return
220      * value but ->notify_cb() is called when the deadline changes.  Therefore
221      * the caller should notice the change and there is no race condition.
222      */
223     qemu_mutex_lock(&timer_list->active_timers_lock);
224     if (!timer_list->active_timers) {
225         qemu_mutex_unlock(&timer_list->active_timers_lock);
226         return -1;
227     }
228     expire_time = timer_list->active_timers->expire_time;
229     qemu_mutex_unlock(&timer_list->active_timers_lock);
230
231     delta = expire_time - qemu_clock_get_ns(timer_list->clock->type);
232
233     if (delta <= 0) {
234         return 0;
235     }
236
237     return delta;
238 }
239
240 /* Calculate the soonest deadline across all timerlists attached
241  * to the clock. This is used for the icount timeout so we
242  * ignore whether or not the clock should be used in deadline
243  * calculations.
244  */
245 int64_t qemu_clock_deadline_ns_all(QEMUClockType type)
246 {
247     int64_t deadline = -1;
248     QEMUTimerList *timer_list;
249     QEMUClock *clock = qemu_clock_ptr(type);
250     QLIST_FOREACH(timer_list, &clock->timerlists, list) {
251         deadline = qemu_soonest_timeout(deadline,
252                                         timerlist_deadline_ns(timer_list));
253     }
254     return deadline;
255 }
256
257 QEMUClockType timerlist_get_clock(QEMUTimerList *timer_list)
258 {
259     return timer_list->clock->type;
260 }
261
262 QEMUTimerList *qemu_clock_get_main_loop_timerlist(QEMUClockType type)
263 {
264     return main_loop_tlg.tl[type];
265 }
266
267 void timerlist_notify(QEMUTimerList *timer_list)
268 {
269     if (timer_list->notify_cb) {
270         timer_list->notify_cb(timer_list->notify_opaque);
271     } else {
272         qemu_notify_event();
273     }
274 }
275
276 /* Transition function to convert a nanosecond timeout to ms
277  * This is used where a system does not support ppoll
278  */
279 int qemu_timeout_ns_to_ms(int64_t ns)
280 {
281     int64_t ms;
282     if (ns < 0) {
283         return -1;
284     }
285
286     if (!ns) {
287         return 0;
288     }
289
290     /* Always round up, because it's better to wait too long than to wait too
291      * little and effectively busy-wait
292      */
293     ms = (ns + SCALE_MS - 1) / SCALE_MS;
294
295     /* To avoid overflow problems, limit this to 2^31, i.e. approx 25 days */
296     if (ms > (int64_t) INT32_MAX) {
297         ms = INT32_MAX;
298     }
299
300     return (int) ms;
301 }
302
303
304 /* qemu implementation of g_poll which uses a nanosecond timeout but is
305  * otherwise identical to g_poll
306  */
307 int qemu_poll_ns(GPollFD *fds, guint nfds, int64_t timeout)
308 {
309 #ifdef CONFIG_PPOLL
310     if (timeout < 0) {
311         return ppoll((struct pollfd *)fds, nfds, NULL, NULL);
312     } else {
313         struct timespec ts;
314         int64_t tvsec = timeout / 1000000000LL;
315         /* Avoid possibly overflowing and specifying a negative number of
316          * seconds, which would turn a very long timeout into a busy-wait.
317          */
318         if (tvsec > (int64_t)INT32_MAX) {
319             tvsec = INT32_MAX;
320         }
321         ts.tv_sec = tvsec;
322         ts.tv_nsec = timeout % 1000000000LL;
323         return ppoll((struct pollfd *)fds, nfds, &ts, NULL);
324     }
325 #else
326     return g_poll(fds, nfds, qemu_timeout_ns_to_ms(timeout));
327 #endif
328 }
329
330
331 void timer_init_tl(QEMUTimer *ts,
332                    QEMUTimerList *timer_list, int scale,
333                    QEMUTimerCB *cb, void *opaque)
334 {
335     ts->timer_list = timer_list;
336     ts->cb = cb;
337     ts->opaque = opaque;
338     ts->scale = scale;
339     ts->expire_time = -1;
340 }
341
342 void timer_deinit(QEMUTimer *ts)
343 {
344     assert(ts->expire_time == -1);
345     ts->timer_list = NULL;
346 }
347
348 void timer_free(QEMUTimer *ts)
349 {
350     g_free(ts);
351 }
352
353 static void timer_del_locked(QEMUTimerList *timer_list, QEMUTimer *ts)
354 {
355     QEMUTimer **pt, *t;
356
357     ts->expire_time = -1;
358     pt = &timer_list->active_timers;
359     for(;;) {
360         t = *pt;
361         if (!t)
362             break;
363         if (t == ts) {
364             *pt = t->next;
365             break;
366         }
367         pt = &t->next;
368     }
369 }
370
371 static bool timer_mod_ns_locked(QEMUTimerList *timer_list,
372                                 QEMUTimer *ts, int64_t expire_time)
373 {
374     QEMUTimer **pt, *t;
375
376     /* add the timer in the sorted list */
377     pt = &timer_list->active_timers;
378     for (;;) {
379         t = *pt;
380         if (!timer_expired_ns(t, expire_time)) {
381             break;
382         }
383         pt = &t->next;
384     }
385     ts->expire_time = MAX(expire_time, 0);
386     ts->next = *pt;
387     *pt = ts;
388
389     return pt == &timer_list->active_timers;
390 }
391
392 static void timerlist_rearm(QEMUTimerList *timer_list)
393 {
394     /* Interrupt execution to force deadline recalculation.  */
395     qemu_clock_warp(timer_list->clock->type);
396     timerlist_notify(timer_list);
397 }
398
399 /* stop a timer, but do not dealloc it */
400 void timer_del(QEMUTimer *ts)
401 {
402     QEMUTimerList *timer_list = ts->timer_list;
403
404     if (timer_list) {
405         qemu_mutex_lock(&timer_list->active_timers_lock);
406         timer_del_locked(timer_list, ts);
407         qemu_mutex_unlock(&timer_list->active_timers_lock);
408     }
409 }
410
411 /* modify the current timer so that it will be fired when current_time
412    >= expire_time. The corresponding callback will be called. */
413 void timer_mod_ns(QEMUTimer *ts, int64_t expire_time)
414 {
415     QEMUTimerList *timer_list = ts->timer_list;
416     bool rearm;
417
418     qemu_mutex_lock(&timer_list->active_timers_lock);
419     timer_del_locked(timer_list, ts);
420     rearm = timer_mod_ns_locked(timer_list, ts, expire_time);
421     qemu_mutex_unlock(&timer_list->active_timers_lock);
422
423     if (rearm) {
424         timerlist_rearm(timer_list);
425     }
426 }
427
428 /* modify the current timer so that it will be fired when current_time
429    >= expire_time or the current deadline, whichever comes earlier.
430    The corresponding callback will be called. */
431 void timer_mod_anticipate_ns(QEMUTimer *ts, int64_t expire_time)
432 {
433     QEMUTimerList *timer_list = ts->timer_list;
434     bool rearm;
435
436     qemu_mutex_lock(&timer_list->active_timers_lock);
437     if (ts->expire_time == -1 || ts->expire_time > expire_time) {
438         if (ts->expire_time != -1) {
439             timer_del_locked(timer_list, ts);
440         }
441         rearm = timer_mod_ns_locked(timer_list, ts, expire_time);
442     } else {
443         rearm = false;
444     }
445     qemu_mutex_unlock(&timer_list->active_timers_lock);
446
447     if (rearm) {
448         timerlist_rearm(timer_list);
449     }
450 }
451
452 void timer_mod(QEMUTimer *ts, int64_t expire_time)
453 {
454     timer_mod_ns(ts, expire_time * ts->scale);
455 }
456
457 void timer_mod_anticipate(QEMUTimer *ts, int64_t expire_time)
458 {
459     timer_mod_anticipate_ns(ts, expire_time * ts->scale);
460 }
461
462 bool timer_pending(QEMUTimer *ts)
463 {
464     return ts->expire_time >= 0;
465 }
466
467 bool timer_expired(QEMUTimer *timer_head, int64_t current_time)
468 {
469     return timer_expired_ns(timer_head, current_time * timer_head->scale);
470 }
471
472 bool timerlist_run_timers(QEMUTimerList *timer_list)
473 {
474     QEMUTimer *ts;
475     int64_t current_time;
476     bool progress = false;
477     QEMUTimerCB *cb;
478     void *opaque;
479
480     qemu_event_reset(&timer_list->timers_done_ev);
481     if (!timer_list->clock->enabled) {
482         goto out;
483     }
484
485     current_time = qemu_clock_get_ns(timer_list->clock->type);
486     for(;;) {
487         qemu_mutex_lock(&timer_list->active_timers_lock);
488         ts = timer_list->active_timers;
489         if (!timer_expired_ns(ts, current_time)) {
490             qemu_mutex_unlock(&timer_list->active_timers_lock);
491             break;
492         }
493
494         /* remove timer from the list before calling the callback */
495         timer_list->active_timers = ts->next;
496         ts->next = NULL;
497         ts->expire_time = -1;
498         cb = ts->cb;
499         opaque = ts->opaque;
500         qemu_mutex_unlock(&timer_list->active_timers_lock);
501
502         /* run the callback (the timer list can be modified) */
503         cb(opaque);
504         progress = true;
505     }
506
507 out:
508     qemu_event_set(&timer_list->timers_done_ev);
509     return progress;
510 }
511
512 bool qemu_clock_run_timers(QEMUClockType type)
513 {
514     return timerlist_run_timers(main_loop_tlg.tl[type]);
515 }
516
517 void timerlistgroup_init(QEMUTimerListGroup *tlg,
518                          QEMUTimerListNotifyCB *cb, void *opaque)
519 {
520     QEMUClockType type;
521     for (type = 0; type < QEMU_CLOCK_MAX; type++) {
522         tlg->tl[type] = timerlist_new(type, cb, opaque);
523     }
524 }
525
526 void timerlistgroup_deinit(QEMUTimerListGroup *tlg)
527 {
528     QEMUClockType type;
529     for (type = 0; type < QEMU_CLOCK_MAX; type++) {
530         timerlist_free(tlg->tl[type]);
531     }
532 }
533
534 bool timerlistgroup_run_timers(QEMUTimerListGroup *tlg)
535 {
536     QEMUClockType type;
537     bool progress = false;
538     for (type = 0; type < QEMU_CLOCK_MAX; type++) {
539         progress |= timerlist_run_timers(tlg->tl[type]);
540     }
541     return progress;
542 }
543
544 int64_t timerlistgroup_deadline_ns(QEMUTimerListGroup *tlg)
545 {
546     int64_t deadline = -1;
547     QEMUClockType type;
548     for (type = 0; type < QEMU_CLOCK_MAX; type++) {
549         if (qemu_clock_use_for_deadline(tlg->tl[type]->clock->type)) {
550             deadline = qemu_soonest_timeout(deadline,
551                                             timerlist_deadline_ns(
552                                                 tlg->tl[type]));
553         }
554     }
555     return deadline;
556 }
557
558 int64_t qemu_clock_get_ns(QEMUClockType type)
559 {
560     int64_t now, last;
561     QEMUClock *clock = qemu_clock_ptr(type);
562
563     switch (type) {
564     case QEMU_CLOCK_REALTIME:
565         return get_clock();
566     default:
567     case QEMU_CLOCK_VIRTUAL:
568         if (use_icount) {
569             return cpu_get_icount();
570         } else {
571             return cpu_get_clock();
572         }
573     case QEMU_CLOCK_HOST:
574         now = REPLAY_CLOCK(REPLAY_CLOCK_HOST, get_clock_realtime());
575         last = clock->last;
576         clock->last = now;
577         if ((now < last || now > (last + get_max_clock_jump()))
578             && replay_mode == REPLAY_MODE_NONE) {
579             notifier_list_notify(&clock->reset_notifiers, &now);
580         }
581         return now;
582     case QEMU_CLOCK_VIRTUAL_RT:
583         return REPLAY_CLOCK(REPLAY_CLOCK_VIRTUAL_RT, cpu_get_clock());
584     }
585 }
586
587 void qemu_clock_register_reset_notifier(QEMUClockType type,
588                                         Notifier *notifier)
589 {
590     QEMUClock *clock = qemu_clock_ptr(type);
591     notifier_list_add(&clock->reset_notifiers, notifier);
592 }
593
594 void qemu_clock_unregister_reset_notifier(QEMUClockType type,
595                                           Notifier *notifier)
596 {
597     notifier_remove(notifier);
598 }
599
600 void init_clocks(void)
601 {
602     QEMUClockType type;
603     for (type = 0; type < QEMU_CLOCK_MAX; type++) {
604         qemu_clock_init(type);
605     }
606
607 #ifdef CONFIG_PRCTL_PR_SET_TIMERSLACK
608     prctl(PR_SET_TIMERSLACK, 1, 0, 0, 0);
609 #endif
610 }
611
612 uint64_t timer_expire_time_ns(QEMUTimer *ts)
613 {
614     return timer_pending(ts) ? ts->expire_time : -1;
615 }
616
617 bool qemu_clock_run_all_timers(void)
618 {
619     bool progress = false;
620     QEMUClockType type;
621
622     for (type = 0; type < QEMU_CLOCK_MAX; type++) {
623         progress |= qemu_clock_run_timers(type);
624     }
625
626     return progress;
627 }