diff options
author | Blue Swirl <blauwirbel@gmail.com> | 2010-10-23 15:24:07 +0000 |
---|---|---|
committer | Blue Swirl <blauwirbel@gmail.com> | 2010-10-23 15:24:07 +0000 |
commit | c57c846a80f9306aa2c6cf7efdef45ed42723fac (patch) | |
tree | 42fc65ee94c4c97e824b85c6d5b8b757fb2327aa /qemu-timer.h | |
parent | 2b2e59e6c95beff2248069b2b129ba8c92c5f4d3 (diff) |
qemu-timer: move commonly used timer code to qemu-timer-common
Move timer init functions to a new file, qemu-timer-common.c. Make other
critical timer functions inlined to preserve performance in
qemu-timer.c, also move muldiv64() (used by the inline functions)
to qemu-timer.h.
Adjust block/raw-posix.c and simpletrace.c to use get_clock() directly.
Remove a similar/duplicate definition in qemu-tool.c.
Adjust hw/omap_clk.c to include qemu-timer.h because muldiv64() is used
there.
After this change, tracing can be used also for user code and
simpletrace on Win32.
Cc: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Acked-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Diffstat (limited to 'qemu-timer.h')
-rw-r--r-- | qemu-timer.h | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/qemu-timer.h b/qemu-timer.h index 1494f79406..299e387768 100644 --- a/qemu-timer.h +++ b/qemu-timer.h @@ -2,6 +2,13 @@ #define QEMU_TIMER_H #include "qemu-common.h" +#include <time.h> +#include <sys/time.h> + +#ifdef _WIN32 +#include <windows.h> +#include <mmsystem.h> +#endif /* timers */ @@ -52,6 +59,73 @@ static inline int64_t get_ticks_per_sec(void) return 1000000000LL; } +/* compute with 96 bit intermediate result: (a*b)/c */ +static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c) +{ + union { + uint64_t ll; + struct { +#ifdef HOST_WORDS_BIGENDIAN + uint32_t high, low; +#else + uint32_t low, high; +#endif + } l; + } u, res; + uint64_t rl, rh; + + u.ll = a; + rl = (uint64_t)u.l.low * (uint64_t)b; + rh = (uint64_t)u.l.high * (uint64_t)b; + rh += (rl >> 32); + res.l.high = rh / c; + res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c; + return res.ll; +} + +/* real time host monotonic timer */ +static inline int64_t get_clock_realtime(void) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000); +} + +/* Warning: don't insert tracepoints into these functions, they are + also used by simpletrace backend and tracepoints would cause + an infinite recursion! */ +#ifdef _WIN32 +extern int64_t clock_freq; + +static inline int64_t get_clock(void) +{ + LARGE_INTEGER ti; + QueryPerformanceCounter(&ti); + return muldiv64(ti.QuadPart, get_ticks_per_sec(), clock_freq); +} + +#else + +extern int use_rt_clock; + +static inline int64_t get_clock(void) +{ +#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \ + || defined(__DragonFly__) || defined(__FreeBSD_kernel__) + if (use_rt_clock) { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return ts.tv_sec * 1000000000LL + ts.tv_nsec; + } else +#endif + { + /* XXX: using gettimeofday leads to problems if the date + changes, so it should be avoided. */ + return get_clock_realtime(); + } +} +#endif void qemu_get_timer(QEMUFile *f, QEMUTimer *ts); void qemu_put_timer(QEMUFile *f, QEMUTimer *ts); |