Statistics
| Branch: | Revision:

root / qemu-timer.h @ 14015304

History | View | Annotate | Download (8.9 kB)

1
#ifndef QEMU_TIMER_H
2
#define QEMU_TIMER_H
3

    
4
#include "qemu-common.h"
5
#include "notify.h"
6
#include <time.h>
7
#include <sys/time.h>
8

    
9
#ifdef _WIN32
10
#include <windows.h>
11
#endif
12

    
13
/* timers */
14

    
15
#define SCALE_MS 1000000
16
#define SCALE_US 1000
17
#define SCALE_NS 1
18

    
19
typedef struct QEMUClock QEMUClock;
20
typedef void QEMUTimerCB(void *opaque);
21

    
22
/* The real time clock should be used only for stuff which does not
23
   change the virtual machine state, as it is run even if the virtual
24
   machine is stopped. The real time clock has a frequency of 1000
25
   Hz. */
26
extern QEMUClock *rt_clock;
27

    
28
/* The virtual clock is only run during the emulation. It is stopped
29
   when the virtual machine is stopped. Virtual timers use a high
30
   precision clock, usually cpu cycles (use ticks_per_sec). */
31
extern QEMUClock *vm_clock;
32

    
33
/* The host clock should be use for device models that emulate accurate
34
   real time sources. It will continue to run when the virtual machine
35
   is suspended, and it will reflect system time changes the host may
36
   undergo (e.g. due to NTP). The host clock has the same precision as
37
   the virtual clock. */
38
extern QEMUClock *host_clock;
39

    
40
int64_t qemu_get_clock_ns(QEMUClock *clock);
41
void qemu_clock_enable(QEMUClock *clock, int enabled);
42
void qemu_clock_warp(QEMUClock *clock);
43

    
44
void qemu_register_clock_reset_notifier(QEMUClock *clock, Notifier *notifier);
45
void qemu_unregister_clock_reset_notifier(QEMUClock *clock,
46
                                          Notifier *notifier);
47

    
48
QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
49
                          QEMUTimerCB *cb, void *opaque);
50
void qemu_free_timer(QEMUTimer *ts);
51
void qemu_del_timer(QEMUTimer *ts);
52
void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time);
53
int qemu_timer_pending(QEMUTimer *ts);
54
int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time);
55

    
56
void qemu_run_all_timers(void);
57
int qemu_alarm_pending(void);
58
int64_t qemu_next_icount_deadline(void);
59
void configure_alarms(char const *opt);
60
void configure_icount(const char *option);
61
int qemu_calculate_timeout(void);
62
void init_clocks(void);
63
int init_timer_alarm(void);
64
void quit_timers(void);
65

    
66
int64_t cpu_get_ticks(void);
67
void cpu_enable_ticks(void);
68
void cpu_disable_ticks(void);
69

    
70
static inline QEMUTimer *qemu_new_timer_ns(QEMUClock *clock, QEMUTimerCB *cb,
71
                                           void *opaque)
72
{
73
    return qemu_new_timer(clock, SCALE_NS, cb, opaque);
74
}
75

    
76
static inline QEMUTimer *qemu_new_timer_ms(QEMUClock *clock, QEMUTimerCB *cb,
77
                                           void *opaque)
78
{
79
    return qemu_new_timer(clock, SCALE_MS, cb, opaque);
80
}
81

    
82
static inline int64_t qemu_get_clock_ms(QEMUClock *clock)
83
{
84
    return qemu_get_clock_ns(clock) / SCALE_MS;
85
}
86

    
87
static inline int64_t get_ticks_per_sec(void)
88
{
89
    return 1000000000LL;
90
}
91

    
92
/* real time host monotonic timer */
93
static inline int64_t get_clock_realtime(void)
94
{
95
    struct timeval tv;
96

    
97
    gettimeofday(&tv, NULL);
98
    return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
99
}
100

    
101
/* Warning: don't insert tracepoints into these functions, they are
102
   also used by simpletrace backend and tracepoints would cause
103
   an infinite recursion! */
104
#ifdef _WIN32
105
extern int64_t clock_freq;
106

    
107
static inline int64_t get_clock(void)
108
{
109
    LARGE_INTEGER ti;
110
    QueryPerformanceCounter(&ti);
111
    return muldiv64(ti.QuadPart, get_ticks_per_sec(), clock_freq);
112
}
113

    
114
#else
115

    
116
extern int use_rt_clock;
117

    
118
static inline int64_t get_clock(void)
119
{
120
#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \
121
    || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
122
    if (use_rt_clock) {
123
        struct timespec ts;
124
        clock_gettime(CLOCK_MONOTONIC, &ts);
125
        return ts.tv_sec * 1000000000LL + ts.tv_nsec;
126
    } else
127
#endif
128
    {
129
        /* XXX: using gettimeofday leads to problems if the date
130
           changes, so it should be avoided. */
131
        return get_clock_realtime();
132
    }
133
}
134
#endif
135

    
136
void qemu_get_timer(QEMUFile *f, QEMUTimer *ts);
137
void qemu_put_timer(QEMUFile *f, QEMUTimer *ts);
138

    
139
/* ptimer.c */
140
typedef struct ptimer_state ptimer_state;
141
typedef void (*ptimer_cb)(void *opaque);
142

    
143
ptimer_state *ptimer_init(QEMUBH *bh);
144
void ptimer_set_period(ptimer_state *s, int64_t period);
145
void ptimer_set_freq(ptimer_state *s, uint32_t freq);
146
void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload);
147
uint64_t ptimer_get_count(ptimer_state *s);
148
void ptimer_set_count(ptimer_state *s, uint64_t count);
149
void ptimer_run(ptimer_state *s, int oneshot);
150
void ptimer_stop(ptimer_state *s);
151

    
152
/* icount */
153
int64_t qemu_icount_round(int64_t count);
154
extern int64_t qemu_icount;
155
extern int use_icount;
156
extern int icount_time_shift;
157
extern int64_t qemu_icount_bias;
158
int64_t cpu_get_icount(void);
159

    
160
/*******************************************/
161
/* host CPU ticks (if available) */
162

    
163
#if defined(_ARCH_PPC)
164

    
165
static inline int64_t cpu_get_real_ticks(void)
166
{
167
    int64_t retval;
168
#ifdef _ARCH_PPC64
169
    /* This reads timebase in one 64bit go and includes Cell workaround from:
170
       http://ozlabs.org/pipermail/linuxppc-dev/2006-October/027052.html
171
    */
172
    __asm__ __volatile__ ("mftb    %0\n\t"
173
                          "cmpwi   %0,0\n\t"
174
                          "beq-    $-8"
175
                          : "=r" (retval));
176
#else
177
    /* http://ozlabs.org/pipermail/linuxppc-dev/1999-October/003889.html */
178
    unsigned long junk;
179
    __asm__ __volatile__ ("mfspr   %1,269\n\t"  /* mftbu */
180
                          "mfspr   %L0,268\n\t" /* mftb */
181
                          "mfspr   %0,269\n\t"  /* mftbu */
182
                          "cmpw    %0,%1\n\t"
183
                          "bne     $-16"
184
                          : "=r" (retval), "=r" (junk));
185
#endif
186
    return retval;
187
}
188

    
189
#elif defined(__i386__)
190

    
191
static inline int64_t cpu_get_real_ticks(void)
192
{
193
    int64_t val;
194
    asm volatile ("rdtsc" : "=A" (val));
195
    return val;
196
}
197

    
198
#elif defined(__x86_64__)
199

    
200
static inline int64_t cpu_get_real_ticks(void)
201
{
202
    uint32_t low,high;
203
    int64_t val;
204
    asm volatile("rdtsc" : "=a" (low), "=d" (high));
205
    val = high;
206
    val <<= 32;
207
    val |= low;
208
    return val;
209
}
210

    
211
#elif defined(__hppa__)
212

    
213
static inline int64_t cpu_get_real_ticks(void)
214
{
215
    int val;
216
    asm volatile ("mfctl %%cr16, %0" : "=r"(val));
217
    return val;
218
}
219

    
220
#elif defined(__ia64)
221

    
222
static inline int64_t cpu_get_real_ticks(void)
223
{
224
    int64_t val;
225
    asm volatile ("mov %0 = ar.itc" : "=r"(val) :: "memory");
226
    return val;
227
}
228

    
229
#elif defined(__s390__)
230

    
231
static inline int64_t cpu_get_real_ticks(void)
232
{
233
    int64_t val;
234
    asm volatile("stck 0(%1)" : "=m" (val) : "a" (&val) : "cc");
235
    return val;
236
}
237

    
238
#elif defined(__sparc_v8plus__) || defined(__sparc_v8plusa__) || defined(__sparc_v9__)
239

    
240
static inline int64_t cpu_get_real_ticks (void)
241
{
242
#if defined(_LP64)
243
    uint64_t        rval;
244
    asm volatile("rd %%tick,%0" : "=r"(rval));
245
    return rval;
246
#else
247
    union {
248
        uint64_t i64;
249
        struct {
250
            uint32_t high;
251
            uint32_t low;
252
        }       i32;
253
    } rval;
254
    asm volatile("rd %%tick,%1; srlx %1,32,%0"
255
                 : "=r"(rval.i32.high), "=r"(rval.i32.low));
256
    return rval.i64;
257
#endif
258
}
259

    
260
#elif defined(__mips__) && \
261
    ((defined(__mips_isa_rev) && __mips_isa_rev >= 2) || defined(__linux__))
262
/*
263
 * binutils wants to use rdhwr only on mips32r2
264
 * but as linux kernel emulate it, it's fine
265
 * to use it.
266
 *
267
 */
268
#define MIPS_RDHWR(rd, value) {                         \
269
        __asm__ __volatile__ (".set   push\n\t"         \
270
                              ".set mips32r2\n\t"       \
271
                              "rdhwr  %0, "rd"\n\t"     \
272
                              ".set   pop"              \
273
                              : "=r" (value));          \
274
    }
275

    
276
static inline int64_t cpu_get_real_ticks(void)
277
{
278
    /* On kernels >= 2.6.25 rdhwr <reg>, $2 and $3 are emulated */
279
    uint32_t count;
280
    static uint32_t cyc_per_count = 0;
281

    
282
    if (!cyc_per_count) {
283
        MIPS_RDHWR("$3", cyc_per_count);
284
    }
285

    
286
    MIPS_RDHWR("$2", count);
287
    return (int64_t)(count * cyc_per_count);
288
}
289

    
290
#elif defined(__alpha__)
291

    
292
static inline int64_t cpu_get_real_ticks(void)
293
{
294
    uint64_t cc;
295
    uint32_t cur, ofs;
296

    
297
    asm volatile("rpcc %0" : "=r"(cc));
298
    cur = cc;
299
    ofs = cc >> 32;
300
    return cur - ofs;
301
}
302

    
303
#else
304
/* The host CPU doesn't have an easily accessible cycle counter.
305
   Just return a monotonically increasing value.  This will be
306
   totally wrong, but hopefully better than nothing.  */
307
static inline int64_t cpu_get_real_ticks (void)
308
{
309
    static int64_t ticks = 0;
310
    return ticks++;
311
}
312
#endif
313

    
314
#ifdef NEED_CPU_H
315
/* Deterministic execution requires that IO only be performed on the last
316
   instruction of a TB so that interrupts take effect immediately.  */
317
static inline int can_do_io(CPUState *env)
318
{
319
    if (!use_icount)
320
        return 1;
321

    
322
    /* If not executing code then assume we are ok.  */
323
    if (!env->current_tb)
324
        return 1;
325

    
326
    return env->can_do_io != 0;
327
}
328
#endif
329

    
330
#ifdef CONFIG_PROFILER
331
static inline int64_t profile_getclock(void)
332
{
333
    return cpu_get_real_ticks();
334
}
335

    
336
extern int64_t qemu_time, qemu_time_start;
337
extern int64_t tlb_flush_time;
338
extern int64_t dev_time;
339
#endif
340

    
341
#endif