Statistics
| Branch: | Revision:

root / qemu-timer.h @ 338b922e

History | View | Annotate | Download (8.2 kB)

1
#ifndef QEMU_TIMER_H
2
#define QEMU_TIMER_H
3

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

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

    
13
/* timers */
14

    
15
typedef struct QEMUClock QEMUClock;
16
typedef void QEMUTimerCB(void *opaque);
17

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

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

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

    
36
int64_t qemu_get_clock(QEMUClock *clock);
37
int64_t qemu_get_clock_ns(QEMUClock *clock);
38
void qemu_clock_enable(QEMUClock *clock, int enabled);
39

    
40
QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque);
41
void qemu_free_timer(QEMUTimer *ts);
42
void qemu_del_timer(QEMUTimer *ts);
43
void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time);
44
int qemu_timer_pending(QEMUTimer *ts);
45
int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time);
46

    
47
void qemu_run_all_timers(void);
48
int qemu_alarm_pending(void);
49
int64_t qemu_next_deadline(void);
50
void configure_alarms(char const *opt);
51
void configure_icount(const char *option);
52
int qemu_calculate_timeout(void);
53
void init_clocks(void);
54
int init_timer_alarm(void);
55
void quit_timers(void);
56

    
57
static inline int64_t get_ticks_per_sec(void)
58
{
59
    return 1000000000LL;
60
}
61

    
62
/* real time host monotonic timer */
63
static inline int64_t get_clock_realtime(void)
64
{
65
    struct timeval tv;
66

    
67
    gettimeofday(&tv, NULL);
68
    return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
69
}
70

    
71
/* Warning: don't insert tracepoints into these functions, they are
72
   also used by simpletrace backend and tracepoints would cause
73
   an infinite recursion! */
74
#ifdef _WIN32
75
extern int64_t clock_freq;
76

    
77
static inline int64_t get_clock(void)
78
{
79
    LARGE_INTEGER ti;
80
    QueryPerformanceCounter(&ti);
81
    return muldiv64(ti.QuadPart, get_ticks_per_sec(), clock_freq);
82
}
83

    
84
#else
85

    
86
extern int use_rt_clock;
87

    
88
static inline int64_t get_clock(void)
89
{
90
#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \
91
    || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
92
    if (use_rt_clock) {
93
        struct timespec ts;
94
        clock_gettime(CLOCK_MONOTONIC, &ts);
95
        return ts.tv_sec * 1000000000LL + ts.tv_nsec;
96
    } else
97
#endif
98
    {
99
        /* XXX: using gettimeofday leads to problems if the date
100
           changes, so it should be avoided. */
101
        return get_clock_realtime();
102
    }
103
}
104
#endif
105

    
106
void qemu_get_timer(QEMUFile *f, QEMUTimer *ts);
107
void qemu_put_timer(QEMUFile *f, QEMUTimer *ts);
108

    
109
/* ptimer.c */
110
typedef struct ptimer_state ptimer_state;
111
typedef void (*ptimer_cb)(void *opaque);
112

    
113
ptimer_state *ptimer_init(QEMUBH *bh);
114
void ptimer_set_period(ptimer_state *s, int64_t period);
115
void ptimer_set_freq(ptimer_state *s, uint32_t freq);
116
void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload);
117
uint64_t ptimer_get_count(ptimer_state *s);
118
void ptimer_set_count(ptimer_state *s, uint64_t count);
119
void ptimer_run(ptimer_state *s, int oneshot);
120
void ptimer_stop(ptimer_state *s);
121
void qemu_put_ptimer(QEMUFile *f, ptimer_state *s);
122
void qemu_get_ptimer(QEMUFile *f, ptimer_state *s);
123

    
124
/* icount */
125
int64_t qemu_icount_round(int64_t count);
126
extern int64_t qemu_icount;
127
extern int use_icount;
128
extern int icount_time_shift;
129
extern int64_t qemu_icount_bias;
130
int64_t cpu_get_icount(void);
131

    
132
/*******************************************/
133
/* host CPU ticks (if available) */
134

    
135
#if defined(_ARCH_PPC)
136

    
137
static inline int64_t cpu_get_real_ticks(void)
138
{
139
    int64_t retval;
140
#ifdef _ARCH_PPC64
141
    /* This reads timebase in one 64bit go and includes Cell workaround from:
142
       http://ozlabs.org/pipermail/linuxppc-dev/2006-October/027052.html
143
    */
144
    __asm__ __volatile__ ("mftb    %0\n\t"
145
                          "cmpwi   %0,0\n\t"
146
                          "beq-    $-8"
147
                          : "=r" (retval));
148
#else
149
    /* http://ozlabs.org/pipermail/linuxppc-dev/1999-October/003889.html */
150
    unsigned long junk;
151
    __asm__ __volatile__ ("mfspr   %1,269\n\t"  /* mftbu */
152
                          "mfspr   %L0,268\n\t" /* mftb */
153
                          "mfspr   %0,269\n\t"  /* mftbu */
154
                          "cmpw    %0,%1\n\t"
155
                          "bne     $-16"
156
                          : "=r" (retval), "=r" (junk));
157
#endif
158
    return retval;
159
}
160

    
161
#elif defined(__i386__)
162

    
163
static inline int64_t cpu_get_real_ticks(void)
164
{
165
    int64_t val;
166
    asm volatile ("rdtsc" : "=A" (val));
167
    return val;
168
}
169

    
170
#elif defined(__x86_64__)
171

    
172
static inline int64_t cpu_get_real_ticks(void)
173
{
174
    uint32_t low,high;
175
    int64_t val;
176
    asm volatile("rdtsc" : "=a" (low), "=d" (high));
177
    val = high;
178
    val <<= 32;
179
    val |= low;
180
    return val;
181
}
182

    
183
#elif defined(__hppa__)
184

    
185
static inline int64_t cpu_get_real_ticks(void)
186
{
187
    int val;
188
    asm volatile ("mfctl %%cr16, %0" : "=r"(val));
189
    return val;
190
}
191

    
192
#elif defined(__ia64)
193

    
194
static inline int64_t cpu_get_real_ticks(void)
195
{
196
    int64_t val;
197
    asm volatile ("mov %0 = ar.itc" : "=r"(val) :: "memory");
198
    return val;
199
}
200

    
201
#elif defined(__s390__)
202

    
203
static inline int64_t cpu_get_real_ticks(void)
204
{
205
    int64_t val;
206
    asm volatile("stck 0(%1)" : "=m" (val) : "a" (&val) : "cc");
207
    return val;
208
}
209

    
210
#elif defined(__sparc_v8plus__) || defined(__sparc_v8plusa__) || defined(__sparc_v9__)
211

    
212
static inline int64_t cpu_get_real_ticks (void)
213
{
214
#if defined(_LP64)
215
    uint64_t        rval;
216
    asm volatile("rd %%tick,%0" : "=r"(rval));
217
    return rval;
218
#else
219
    union {
220
        uint64_t i64;
221
        struct {
222
            uint32_t high;
223
            uint32_t low;
224
        }       i32;
225
    } rval;
226
    asm volatile("rd %%tick,%1; srlx %1,32,%0"
227
                 : "=r"(rval.i32.high), "=r"(rval.i32.low));
228
    return rval.i64;
229
#endif
230
}
231

    
232
#elif defined(__mips__) && \
233
    ((defined(__mips_isa_rev) && __mips_isa_rev >= 2) || defined(__linux__))
234
/*
235
 * binutils wants to use rdhwr only on mips32r2
236
 * but as linux kernel emulate it, it's fine
237
 * to use it.
238
 *
239
 */
240
#define MIPS_RDHWR(rd, value) {                         \
241
        __asm__ __volatile__ (".set   push\n\t"         \
242
                              ".set mips32r2\n\t"       \
243
                              "rdhwr  %0, "rd"\n\t"     \
244
                              ".set   pop"              \
245
                              : "=r" (value));          \
246
    }
247

    
248
static inline int64_t cpu_get_real_ticks(void)
249
{
250
    /* On kernels >= 2.6.25 rdhwr <reg>, $2 and $3 are emulated */
251
    uint32_t count;
252
    static uint32_t cyc_per_count = 0;
253

    
254
    if (!cyc_per_count) {
255
        MIPS_RDHWR("$3", cyc_per_count);
256
    }
257

    
258
    MIPS_RDHWR("$2", count);
259
    return (int64_t)(count * cyc_per_count);
260
}
261

    
262
#elif defined(__alpha__)
263

    
264
static inline int64_t cpu_get_real_ticks(void)
265
{
266
    uint64_t cc;
267
    uint32_t cur, ofs;
268

    
269
    asm volatile("rpcc %0" : "=r"(cc));
270
    cur = cc;
271
    ofs = cc >> 32;
272
    return cur - ofs;
273
}
274

    
275
#else
276
/* The host CPU doesn't have an easily accessible cycle counter.
277
   Just return a monotonically increasing value.  This will be
278
   totally wrong, but hopefully better than nothing.  */
279
static inline int64_t cpu_get_real_ticks (void)
280
{
281
    static int64_t ticks = 0;
282
    return ticks++;
283
}
284
#endif
285

    
286
#ifdef NEED_CPU_H
287
/* Deterministic execution requires that IO only be performed on the last
288
   instruction of a TB so that interrupts take effect immediately.  */
289
static inline int can_do_io(CPUState *env)
290
{
291
    if (!use_icount)
292
        return 1;
293

    
294
    /* If not executing code then assume we are ok.  */
295
    if (!env->current_tb)
296
        return 1;
297

    
298
    return env->can_do_io != 0;
299
}
300
#endif
301

    
302
#ifdef CONFIG_PROFILER
303
static inline int64_t profile_getclock(void)
304
{
305
    return cpu_get_real_ticks();
306
}
307

    
308
extern int64_t qemu_time, qemu_time_start;
309
extern int64_t tlb_flush_time;
310
extern int64_t dev_time;
311
#endif
312

    
313
#endif