qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] intentinoal slowing down qemu - brake
@ 2006-11-30 14:56 Miroslav Novak
  2006-12-01 15:41 ` Martin Guy
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Miroslav Novak @ 2006-11-30 14:56 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 857 bytes --]

This patch adds support for slowing down qemu and saving cpu load.
The '-brake' command line parameter or monitor command 'brake' 
determines how long to wait in the main_loop with respect to duration of 
time that qemu used for the emulation itself.
Thus e.g. zero value runs at full speed, 1 at 1/2 speed, 10 at 1/11 
speed, etc.

A drawback of this approach is that the timer interrupt can be missed if 
raised too often. This happens if the loop_main divided by (1+brake) is 
less than the frequency of PIC interrupts.
In such case the time of emulated system runs slowly.

This problem occurs mainly for Linux emulation where kernel parameter HZ 
is of several hunderds.
For DOS emulation, where the timer interrupts are raised usualy at 18Hz, 
this approach works nice, and one can play old DOS games at reasonable 
speed and save batteries.


Mirek


[-- Attachment #2: brake.patch --]
[-- Type: text/x-patch, Size: 4905 bytes --]

diff -aur ../../orig/qemu-0.8.2/monitor.c ./monitor.c
--- ../../orig/qemu-0.8.2/monitor.c	2006-07-22 19:23:34.000000000 +0200
+++ ./monitor.c	2006-11-27 18:11:34.000000000 +0100
@@ -276,6 +276,14 @@
         term_printf("Invalid CPU index\n");
 }
 
+static void do_brake_set(int multiplier)
+{
+    if (multiplier < 0)
+        term_printf("Current brake multiplier %d\n", brake_mult);
+    else
+        brake_mult = multiplier;
+}
+
 static void do_info_jit(void)
 {
     dump_exec_info(NULL, monitor_fprintf);
@@ -1198,6 +1206,8 @@
 #endif
      { "stopcapture", "i", do_stop_capture,
        "capture index", "stop capture" },
+    { "brake", "i", do_brake_set, 
+      "multiplier", "set brake multiplier (non-negative integer), negative value prints actual setting" },
     { NULL, NULL, }, 
 };
 
diff -aur ../../orig/qemu-0.8.2/vl.c ./vl.c
--- ../../orig/qemu-0.8.2/vl.c	2006-07-22 19:23:34.000000000 +0200
+++ ./vl.c	2006-11-27 18:25:22.000000000 +0100
@@ -156,6 +156,7 @@
 #endif
 int acpi_enabled = 1;
 int fd_bootchk = 1;
+int brake_mult = 0;
 
 /***********************************************************/
 /* x86 ISA bus support */
@@ -5045,8 +5046,39 @@
 
 static CPUState *cur_cpu;
 
+
+int timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y) {
+	/* Perform the carry for the later subtraction by updating y. */
+	if (x->tv_usec < y->tv_usec) {
+		int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
+		y->tv_usec -= 1000000 * nsec;
+		y->tv_sec += nsec;
+	}
+	if (x->tv_usec - y->tv_usec > 1000000) {
+		int nsec = (x->tv_usec - y->tv_usec) / 1000000;
+		y->tv_usec += 1000000 * nsec;
+		y->tv_sec -= nsec;
+	}
+
+	/* Compute the time remaining to wait.
+	 *      tv_usec is certainly positive. */
+	result->tv_sec = x->tv_sec - y->tv_sec;
+	result->tv_usec = x->tv_usec - y->tv_usec;
+
+	/* Return 1 if result is negative. */
+	return x->tv_sec < y->tv_sec;
+}
+
+
 int main_loop(void)
 {
+    struct timeval tti, tti2, tti3, ttix;
+//#define BRAKE_DEBUG
+#ifdef BRAKE_DEBUG
+    int64_t mti, mti1, mti2, mti3;
+    int prcnt=0;
+#endif
+
     int ret, timeout;
 #ifdef CONFIG_PROFILER
     int64_t ti;
@@ -5055,6 +5087,11 @@
 
     cur_cpu = first_cpu;
     for(;;) {
+
+        gettimeofday(&tti, NULL);
+#ifdef BRAKE_DEBUG
+        mti = profile_getclock();
+#endif
         if (vm_running) {
 
             env = cur_cpu;
@@ -5113,6 +5150,41 @@
 #ifdef CONFIG_PROFILER
         dev_time += profile_getclock() - ti;
 #endif
+
+        gettimeofday(&tti2, NULL);
+#ifdef BRAKE_DEBUG
+        mti2 = profile_getclock();
+#endif
+
+        {
+            struct timespec ts;
+            int delus, delunc=0;
+            sigset_t sis, osis;
+
+            timeval_subtract(&ttix, &tti2, &tti);
+            delus = ttix.tv_usec*brake_mult - delunc;
+            ts.tv_sec=0;
+            ts.tv_nsec=delus*1000;
+
+            sigfillset(&sis);
+            sigprocmask(SIG_BLOCK, &sis, &osis);
+            if (delus>0) while (nanosleep(&ts, &ts));
+            sigprocmask(SIG_SETMASK, &osis, NULL);
+#ifdef BRAKE_DEBUG
+            mti3 = profile_getclock();
+#endif
+            gettimeofday(&tti3, NULL);
+
+            timeval_subtract(&ttix, &tti3, &tti2);
+            delunc = ttix.tv_usec-delus; 
+#ifdef BRAKE_DEBUG
+            if (!((++prcnt)%128)) {
+                printf("cycles %qd, \t%qd, \t%qd, \t%qd \%\n", (mti1 - mti), (mti2 - mti1), (mti3 - mti2), (100*(mti1 - mti))/(mti3-mti) );
+                //printf("del[us] %d, \t%d\n", delus, delunc);
+                //printf("ts[ns] = %d\n", ts.tv_nsec);
+            }
+#endif
+        }
     }
     cpu_disable_ticks();
     return ret;
@@ -5224,6 +5296,7 @@
 #endif
            "-loadvm file    start right away with a saved state (loadvm in monitor)\n"
 	   "-vnc display    start a VNC server on display\n"
+           "-brake multiplier    enables brake system which slows down qemu `multiplier'-times\n"
            "\n"
            "During emulation, the following keys are useful:\n"
            "ctrl-alt-f      toggle full screen\n"
@@ -5302,6 +5375,7 @@
     QEMU_OPTION_smp,
     QEMU_OPTION_vnc,
     QEMU_OPTION_no_acpi,
+    QEMU_OPTION_brake,
 };
 
 typedef struct QEMUOption {
@@ -5378,6 +5452,7 @@
     { "usb", 0, QEMU_OPTION_usb },
     { "cirrusvga", 0, QEMU_OPTION_cirrusvga },
     { "no-acpi", 0, QEMU_OPTION_no_acpi },
+    { "brake", 1, QEMU_OPTION_brake },
     { NULL },
 };
 
@@ -6021,6 +6096,9 @@
             case QEMU_OPTION_no_acpi:
                 acpi_enabled = 0;
                 break;
+	    case QEMU_OPTION_brake:
+		brake_mult = atoi(optarg);
+		break;
             }
         }
     }
diff -aur ../../orig/qemu-0.8.2/vl.h ./vl.h
--- ../../orig/qemu-0.8.2/vl.h	2006-07-22 19:23:34.000000000 +0200
+++ ./vl.h	2006-11-27 18:09:41.000000000 +0100
@@ -1177,4 +1177,6 @@
 
 void kqemu_record_dump(void);
 
+extern int brake_mult;
+
 #endif /* VL_H */

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2006-12-06  9:52 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-11-30 14:56 [Qemu-devel] [PATCH] intentinoal slowing down qemu - brake Miroslav Novak
2006-12-01 15:41 ` Martin Guy
2006-12-01 15:43   ` Martin Guy
2006-12-01 19:35   ` Johannes Schindelin
2006-12-01 21:59     ` SoftICE under DOS16, anybody? __/__ " Martin Bochnig
2006-12-01 23:43       ` Martin Bochnig
2006-12-05 16:54 ` Miroslav Novak
2006-12-05 21:29 ` Miroslav Novak
2006-12-06  7:03   ` Manish Gajbhiye
2006-12-06  9:52     ` Network problem, was " Johannes Schindelin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).