aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBlue Swirl <blauwirbel@gmail.com>2010-10-23 15:24:07 +0000
committerBlue Swirl <blauwirbel@gmail.com>2010-10-23 15:24:07 +0000
commitc57c846a80f9306aa2c6cf7efdef45ed42723fac (patch)
tree42fc65ee94c4c97e824b85c6d5b8b757fb2327aa
parent2b2e59e6c95beff2248069b2b129ba8c92c5f4d3 (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>
-rw-r--r--Makefile6
-rw-r--r--Makefile.objs3
-rw-r--r--block/raw-posix.c12
-rw-r--r--hw/omap_clk.c1
-rw-r--r--qemu-common.h2
-rw-r--r--qemu-timer-common.c62
-rw-r--r--qemu-timer.c73
-rw-r--r--qemu-timer.h74
-rw-r--r--qemu-tool.c7
-rw-r--r--simpletrace.c10
-rw-r--r--vl.c24
11 files changed, 150 insertions, 124 deletions
diff --git a/Makefile b/Makefile
index 252c817d27..a1434b1bd9 100644
--- a/Makefile
+++ b/Makefile
@@ -129,11 +129,11 @@ version-obj-$(CONFIG_WIN32) += version.o
qemu-img.o: qemu-img-cmds.h
qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o: $(GENERATED_HEADERS)
-qemu-img$(EXESUF): qemu-img.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y)
+qemu-img$(EXESUF): qemu-img.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o
-qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y)
+qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o
-qemu-io$(EXESUF): qemu-io.o cmd.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y)
+qemu-io$(EXESUF): qemu-io.o cmd.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o
qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx
$(call quiet-command,sh $(SRC_PATH)/hxtool -h < $< > $@," GEN $@")
diff --git a/Makefile.objs b/Makefile.objs
index 6e6f60a3af..f07fb01bc3 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -127,7 +127,7 @@ common-obj-y += iov.o acl.o
common-obj-$(CONFIG_THREAD) += qemu-thread.o
common-obj-$(CONFIG_IOTHREAD) += compatfd.o
common-obj-y += notify.o event_notifier.o
-common-obj-y += qemu-timer.o
+common-obj-y += qemu-timer.o qemu-timer-common.o
slirp-obj-y = cksum.o if.o ip_icmp.o ip_input.o ip_output.o
slirp-obj-y += slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o
@@ -278,6 +278,7 @@ libdis-$(CONFIG_SPARC_DIS) += sparc-dis.o
trace-obj-y = trace.o
ifeq ($(TRACE_BACKEND),simple)
trace-obj-y += simpletrace.o
+user-obj-y += qemu-timer-common.o
endif
vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
diff --git a/block/raw-posix.c b/block/raw-posix.c
index a5cbb7e929..d0393e0c44 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -97,9 +97,9 @@
#define FTYPE_CD 1
#define FTYPE_FD 2
-/* if the FD is not accessed during that time (in ms), we try to
+/* if the FD is not accessed during that time (in ns), we try to
reopen it to see if the disk has been changed */
-#define FD_OPEN_TIMEOUT 1000
+#define FD_OPEN_TIMEOUT (1000000000)
#define MAX_BLOCKSIZE 4096
@@ -908,7 +908,7 @@ static int fd_open(BlockDriverState *bs)
return 0;
last_media_present = (s->fd >= 0);
if (s->fd >= 0 &&
- (qemu_get_clock(rt_clock) - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
+ (get_clock() - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
close(s->fd);
s->fd = -1;
#ifdef DEBUG_FLOPPY
@@ -917,7 +917,7 @@ static int fd_open(BlockDriverState *bs)
}
if (s->fd < 0) {
if (s->fd_got_error &&
- (qemu_get_clock(rt_clock) - s->fd_error_time) < FD_OPEN_TIMEOUT) {
+ (get_clock() - s->fd_error_time) < FD_OPEN_TIMEOUT) {
#ifdef DEBUG_FLOPPY
printf("No floppy (open delayed)\n");
#endif
@@ -925,7 +925,7 @@ static int fd_open(BlockDriverState *bs)
}
s->fd = open(bs->filename, s->open_flags & ~O_NONBLOCK);
if (s->fd < 0) {
- s->fd_error_time = qemu_get_clock(rt_clock);
+ s->fd_error_time = get_clock();
s->fd_got_error = 1;
if (last_media_present)
s->fd_media_changed = 1;
@@ -940,7 +940,7 @@ static int fd_open(BlockDriverState *bs)
}
if (!last_media_present)
s->fd_media_changed = 1;
- s->fd_open_time = qemu_get_clock(rt_clock);
+ s->fd_open_time = get_clock();
s->fd_got_error = 0;
return 0;
}
diff --git a/hw/omap_clk.c b/hw/omap_clk.c
index 6bcabef8ac..10c9c4308c 100644
--- a/hw/omap_clk.c
+++ b/hw/omap_clk.c
@@ -20,6 +20,7 @@
*/
#include "hw.h"
#include "omap.h"
+#include "qemu-timer.h" /* for muldiv64() */
struct clk {
const char *name;
diff --git a/qemu-common.h b/qemu-common.h
index d5ae42020e..2fbc27f9f0 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -133,8 +133,6 @@ void qemu_bh_delete(QEMUBH *bh);
int qemu_bh_poll(void);
void qemu_bh_update_timeout(int *timeout);
-uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c);
-
void qemu_get_timedate(struct tm *tm, int offset);
int qemu_timedate_diff(struct tm *tm);
diff --git a/qemu-timer-common.c b/qemu-timer-common.c
new file mode 100644
index 0000000000..fff43996d8
--- /dev/null
+++ b/qemu-timer-common.c
@@ -0,0 +1,62 @@
+/*
+ * QEMU System Emulator
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu-timer.h"
+
+/***********************************************************/
+/* real time host monotonic timer */
+
+#ifdef _WIN32
+
+int64_t clock_freq;
+
+static void __attribute__((constructor)) init_get_clock(void)
+{
+ LARGE_INTEGER freq;
+ int ret;
+ ret = QueryPerformanceFrequency(&freq);
+ if (ret == 0) {
+ fprintf(stderr, "Could not calibrate ticks\n");
+ exit(1);
+ }
+ clock_freq = freq.QuadPart;
+}
+
+#else
+
+int use_rt_clock;
+
+static void __attribute__((constructor)) init_get_clock(void)
+{
+ use_rt_clock = 0;
+#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \
+ || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
+ {
+ struct timespec ts;
+ if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
+ use_rt_clock = 1;
+ }
+ }
+#endif
+}
+#endif
diff --git a/qemu-timer.c b/qemu-timer.c
index bc5f207bb6..95814af798 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -64,78 +64,6 @@ int64_t qemu_icount_bias;
static QEMUTimer *icount_rt_timer;
static QEMUTimer *icount_vm_timer;
-
-/***********************************************************/
-/* real time host monotonic timer */
-
-
-static int64_t get_clock_realtime(void)
-{
- struct timeval tv;
-
- gettimeofday(&tv, NULL);
- return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
-}
-
-#ifdef WIN32
-
-static int64_t clock_freq;
-
-static void init_get_clock(void)
-{
- LARGE_INTEGER freq;
- int ret;
- ret = QueryPerformanceFrequency(&freq);
- if (ret == 0) {
- fprintf(stderr, "Could not calibrate ticks\n");
- exit(1);
- }
- clock_freq = freq.QuadPart;
-}
-
-static int64_t get_clock(void)
-{
- LARGE_INTEGER ti;
- QueryPerformanceCounter(&ti);
- return muldiv64(ti.QuadPart, get_ticks_per_sec(), clock_freq);
-}
-
-#else
-
-static int use_rt_clock;
-
-static void init_get_clock(void)
-{
- use_rt_clock = 0;
-#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \
- || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
- {
- struct timespec ts;
- if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
- use_rt_clock = 1;
- }
- }
-#endif
-}
-
-static 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
-
/***********************************************************/
/* guest cycle counter */
@@ -614,7 +542,6 @@ int64_t qemu_get_clock_ns(QEMUClock *clock)
void init_clocks(void)
{
- init_get_clock();
rt_clock = qemu_new_clock(QEMU_CLOCK_REALTIME);
vm_clock = qemu_new_clock(QEMU_CLOCK_VIRTUAL);
host_clock = qemu_new_clock(QEMU_CLOCK_HOST);
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);
diff --git a/qemu-tool.c b/qemu-tool.c
index b39af86e01..9ccca655ef 100644
--- a/qemu-tool.c
+++ b/qemu-tool.c
@@ -110,10 +110,3 @@ int qemu_set_fd_handler2(int fd,
{
return 0;
}
-
-int64_t qemu_get_clock(QEMUClock *clock)
-{
- qemu_timeval tv;
- qemu_gettimeofday(&tv);
- return (tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000)) / 1000000;
-}
diff --git a/simpletrace.c b/simpletrace.c
index b488d51766..9ea0d1f984 100644
--- a/simpletrace.c
+++ b/simpletrace.c
@@ -12,6 +12,7 @@
#include <stdint.h>
#include <stdio.h>
#include <time.h>
+#include "qemu-timer.h"
#include "trace.h"
/** Trace file header event ID */
@@ -140,20 +141,13 @@ static void trace(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3,
uint64_t x4, uint64_t x5, uint64_t x6)
{
TraceRecord *rec = &trace_buf[trace_idx];
- struct timespec ts;
-
- /* TODO Windows? It would be good to use qemu-timer here but that isn't
- * linked into qemu-tools. Also we should avoid recursion in the tracing
- * code, therefore it is useful to be self-contained.
- */
- clock_gettime(CLOCK_MONOTONIC, &ts);
if (!trace_list[event].state) {
return;
}
rec->event = event;
- rec->timestamp_ns = ts.tv_sec * 1000000000LL + ts.tv_nsec;
+ rec->timestamp_ns = get_clock();
rec->x1 = x1;
rec->x2 = x2;
rec->x3 = x3;
diff --git a/vl.c b/vl.c
index df414ef5ac..7038952dc6 100644
--- a/vl.c
+++ b/vl.c
@@ -289,30 +289,6 @@ static int default_driver_check(QemuOpts *opts, void *opaque)
/***********************************************************/
/* real time host monotonic timer */
-/* compute with 96 bit intermediate result: (a*b)/c */
-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;
-}
-
/***********************************************************/
/* host time/date access */
void qemu_get_timedate(struct tm *tm, int offset)