aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2006-02-08 22:40:15 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2006-02-08 22:40:15 +0000
commit5f1ce9487c7ab600433d6ebf059b45adad267c27 (patch)
tree7c7a5c01278df3fe4fb86bc744f9c6b2c013ecfb
parent05c2a3e7313870811c8a7ec9837f5e75d40ea080 (diff)
support for builtin profiler
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1751 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r--cpu-all.h20
-rw-r--r--monitor.c66
2 files changed, 81 insertions, 5 deletions
diff --git a/cpu-all.h b/cpu-all.h
index b374fe86b0..e0b60d96d9 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -867,4 +867,24 @@ void cpu_tlb_update_dirty(CPUState *env);
void dump_exec_info(FILE *f,
int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
+/* profiling */
+#ifdef CONFIG_PROFILER
+static inline int64_t profile_getclock(void)
+{
+ int64_t val;
+ asm volatile ("rdtsc" : "=A" (val));
+ return val;
+}
+
+extern int64_t kqemu_time, kqemu_time_start;
+extern int64_t qemu_time, qemu_time_start;
+extern int64_t tlb_flush_time;
+extern int64_t kqemu_exec_count;
+extern int64_t dev_time;
+extern int64_t kqemu_ret_int_count;
+extern int64_t kqemu_ret_excp_count;
+extern int64_t kqemu_ret_intr_count;
+
+#endif
+
#endif /* CPU_ALL_H */
diff --git a/monitor.c b/monitor.c
index d7acaa420d..6b98cf13f5 100644
--- a/monitor.c
+++ b/monitor.c
@@ -296,9 +296,6 @@ static void do_info_history (void)
static void do_quit(void)
{
-#ifdef USE_KQEMU
- kqemu_record_dump();
-#endif
exit(0);
}
@@ -960,12 +957,69 @@ static void do_info_kqemu(void)
return;
}
val = env->kqemu_enabled;
- term_printf("kqemu is %s\n", val ? "enabled" : "disabled");
+ term_printf("kqemu support: ");
+ switch(val) {
+ default:
+ case 0:
+ term_printf("disabled\n");
+ break;
+ case 1:
+ term_printf("enabled for user code\n");
+ break;
+ case 2:
+ term_printf("enabled for user and kernel code\n");
+ break;
+ }
#else
- term_printf("kqemu support is not compiled\n");
+ term_printf("kqemu support: not compiled\n");
#endif
}
+#ifdef CONFIG_PROFILER
+
+int64_t kqemu_time;
+int64_t qemu_time;
+int64_t kqemu_exec_count;
+int64_t dev_time;
+int64_t kqemu_ret_int_count;
+int64_t kqemu_ret_excp_count;
+int64_t kqemu_ret_intr_count;
+
+static void do_info_profile(void)
+{
+ int64_t total;
+ total = qemu_time;
+ if (total == 0)
+ total = 1;
+ term_printf("async time %lld (%0.3f)\n",
+ dev_time, dev_time / (double)ticks_per_sec);
+ term_printf("qemu time %lld (%0.3f)\n",
+ qemu_time, qemu_time / (double)ticks_per_sec);
+ term_printf("kqemu time %lld (%0.3f %0.1f%%) count=%lld int=%lld excp=%lld intr=%lld\n",
+ kqemu_time, kqemu_time / (double)ticks_per_sec,
+ kqemu_time / (double)total * 100.0,
+ kqemu_exec_count,
+ kqemu_ret_int_count,
+ kqemu_ret_excp_count,
+ kqemu_ret_intr_count);
+ qemu_time = 0;
+ kqemu_time = 0;
+ kqemu_exec_count = 0;
+ dev_time = 0;
+ kqemu_ret_int_count = 0;
+ kqemu_ret_excp_count = 0;
+ kqemu_ret_intr_count = 0;
+#ifdef USE_KQEMU
+ kqemu_record_dump();
+#endif
+}
+#else
+static void do_info_profile(void)
+{
+ term_printf("Internal profiler not compiled\n");
+}
+#endif
+
static term_cmd_t term_cmds[] = {
{ "help|?", "s?", do_help,
"[cmd]", "show the help" },
@@ -1054,6 +1108,8 @@ static term_cmd_t info_cmds[] = {
"", "show guest USB devices", },
{ "usbhost", "", usb_host_info,
"", "show host USB devices", },
+ { "profile", "", do_info_profile,
+ "", "show profiling information", },
{ NULL, NULL, },
};