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