On Mon, Apr 25, 2005 at 10:24:45PM +0200, Jonas Maebe wrote:
> 
> On 25 Apr 2005, at 22:17, Massimo Dal Zotto wrote:
> 
> >In the meantime until we find a better solution could you give us some
> >explanation on why using a microseconds clock from gettimeofday instead
> >of rdtsc the guest os clock runs always 20% slower?
> 
> Because a system call (which gettimeofday is) is very slow (two context 
> switches).
> 

No, it has nothing to do with the speed of gettimeofday, which on my pc
takes only a few microsecons to execute.

The problem seems in (rounding?) errors in computations of ticks_per_sec
and/or next_transition_time and was solved (om my 600/1800 laptop) by
replacing the following instruction in my previous patch

    return get_clock();

with

    return get_clock()<<12;

It seems that simply changing the scale of ticks values reduces the
computation errors in the timer code, which must be somewhere even
if I haven't been able to find them.

The clock in the guest os is now running at the correct speed and the
sleep(1) command takes the exact real time to execute at any cpu speed.

The following patch should be then the correct one.

-- 
Massimo Dal Zotto
--- qemu-0.6.2cvs20050425.orig/vl.c     2005-04-08 00:20:28.000000000 +0200
+++ qemu-0.6.2cvs20050425/vl.c  2005-04-25 23:03:57.096969536 +0200
@@ -135,6 +135,10 @@
 int prep_enabled = 0;
 int rtc_utc = 1;
 int cirrus_vga_enabled = 1;
+#ifdef __i386__
+static int notsc = 0;
+extern int64_t get_clock(void);
+#endif
 #ifdef TARGET_SPARC
 int graphic_width = 1024;
 int graphic_height = 768;
@@ -502,6 +506,9 @@
 int64_t cpu_get_real_ticks(void)
 {
     int64_t val;
+    if (notsc) {
+       return get_clock()<<12;
+    }
     asm volatile ("rdtsc" : "=A" (val));
     return val;
 }
@@ -590,6 +597,7 @@
     usec = get_clock() - usec;
     ticks = cpu_get_real_ticks() - ticks;
     ticks_per_sec = (ticks * 1000000LL + (usec >> 1)) / usec;
+    //printf("ticks_per_sec=%lld\n",ticks_per_sec);
 }
 
 /* compute with 96 bit intermediate result: (a*b)/c */
@@ -2792,6 +2800,9 @@
 #ifdef USE_CODE_COPY
            "-no-code-copy   disable code copy acceleration\n"
 #endif
+#ifdef __i386__
+           "-no-tsc         disable tsc as clock source\n"
+#endif
 #ifdef TARGET_I386
            "-isa            simulate an ISA-only system (default is PCI 
system)\n"
            "-std-vga        simulate a standard VGA card with VESA Bochs 
Extensions\n"
@@ -2863,6 +2874,7 @@
     QEMU_OPTION_hdachs,
     QEMU_OPTION_L,
     QEMU_OPTION_no_code_copy,
+    QEMU_OPTION_no_tsc,
     QEMU_OPTION_pci,
     QEMU_OPTION_isa,
     QEMU_OPTION_prep,
@@ -2931,6 +2943,9 @@
 #ifdef USE_KQEMU
     { "no-kqemu", 0, QEMU_OPTION_no_kqemu },
 #endif
+#ifdef __i386__
+    { "no-tsc", 0, QEMU_OPTION_no_tsc },
+#endif
 #ifdef TARGET_PPC
     { "prep", 0, QEMU_OPTION_prep },
 #endif
@@ -3216,6 +3231,11 @@
             case QEMU_OPTION_no_code_copy:
                 code_copy_enabled = 0;
                 break;
+#ifdef __i386__
+            case QEMU_OPTION_no_tsc:
+                notsc = 1;
+                break;
+#endif
             case QEMU_OPTION_nics:
                 nb_nics = atoi(optarg);
                 if (nb_nics < 0 || nb_nics > MAX_NICS) {
_______________________________________________
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel

Reply via email to