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