Commit 5f1ce9487c7ab600433d6ebf059b45adad267c27
1 parent
05c2a3e7
support for builtin profiler
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1751 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
81 additions
and
5 deletions
cpu-all.h
| @@ -867,4 +867,24 @@ void cpu_tlb_update_dirty(CPUState *env); | @@ -867,4 +867,24 @@ void cpu_tlb_update_dirty(CPUState *env); | ||
| 867 | void dump_exec_info(FILE *f, | 867 | void dump_exec_info(FILE *f, |
| 868 | int (*cpu_fprintf)(FILE *f, const char *fmt, ...)); | 868 | int (*cpu_fprintf)(FILE *f, const char *fmt, ...)); |
| 869 | 869 | ||
| 870 | +/* profiling */ | ||
| 871 | +#ifdef CONFIG_PROFILER | ||
| 872 | +static inline int64_t profile_getclock(void) | ||
| 873 | +{ | ||
| 874 | + int64_t val; | ||
| 875 | + asm volatile ("rdtsc" : "=A" (val)); | ||
| 876 | + return val; | ||
| 877 | +} | ||
| 878 | + | ||
| 879 | +extern int64_t kqemu_time, kqemu_time_start; | ||
| 880 | +extern int64_t qemu_time, qemu_time_start; | ||
| 881 | +extern int64_t tlb_flush_time; | ||
| 882 | +extern int64_t kqemu_exec_count; | ||
| 883 | +extern int64_t dev_time; | ||
| 884 | +extern int64_t kqemu_ret_int_count; | ||
| 885 | +extern int64_t kqemu_ret_excp_count; | ||
| 886 | +extern int64_t kqemu_ret_intr_count; | ||
| 887 | + | ||
| 888 | +#endif | ||
| 889 | + | ||
| 870 | #endif /* CPU_ALL_H */ | 890 | #endif /* CPU_ALL_H */ |
monitor.c
| @@ -296,9 +296,6 @@ static void do_info_history (void) | @@ -296,9 +296,6 @@ static void do_info_history (void) | ||
| 296 | 296 | ||
| 297 | static void do_quit(void) | 297 | static void do_quit(void) |
| 298 | { | 298 | { |
| 299 | -#ifdef USE_KQEMU | ||
| 300 | - kqemu_record_dump(); | ||
| 301 | -#endif | ||
| 302 | exit(0); | 299 | exit(0); |
| 303 | } | 300 | } |
| 304 | 301 | ||
| @@ -960,12 +957,69 @@ static void do_info_kqemu(void) | @@ -960,12 +957,69 @@ static void do_info_kqemu(void) | ||
| 960 | return; | 957 | return; |
| 961 | } | 958 | } |
| 962 | val = env->kqemu_enabled; | 959 | val = env->kqemu_enabled; |
| 963 | - term_printf("kqemu is %s\n", val ? "enabled" : "disabled"); | 960 | + term_printf("kqemu support: "); |
| 961 | + switch(val) { | ||
| 962 | + default: | ||
| 963 | + case 0: | ||
| 964 | + term_printf("disabled\n"); | ||
| 965 | + break; | ||
| 966 | + case 1: | ||
| 967 | + term_printf("enabled for user code\n"); | ||
| 968 | + break; | ||
| 969 | + case 2: | ||
| 970 | + term_printf("enabled for user and kernel code\n"); | ||
| 971 | + break; | ||
| 972 | + } | ||
| 964 | #else | 973 | #else |
| 965 | - term_printf("kqemu support is not compiled\n"); | 974 | + term_printf("kqemu support: not compiled\n"); |
| 966 | #endif | 975 | #endif |
| 967 | } | 976 | } |
| 968 | 977 | ||
| 978 | +#ifdef CONFIG_PROFILER | ||
| 979 | + | ||
| 980 | +int64_t kqemu_time; | ||
| 981 | +int64_t qemu_time; | ||
| 982 | +int64_t kqemu_exec_count; | ||
| 983 | +int64_t dev_time; | ||
| 984 | +int64_t kqemu_ret_int_count; | ||
| 985 | +int64_t kqemu_ret_excp_count; | ||
| 986 | +int64_t kqemu_ret_intr_count; | ||
| 987 | + | ||
| 988 | +static void do_info_profile(void) | ||
| 989 | +{ | ||
| 990 | + int64_t total; | ||
| 991 | + total = qemu_time; | ||
| 992 | + if (total == 0) | ||
| 993 | + total = 1; | ||
| 994 | + term_printf("async time %lld (%0.3f)\n", | ||
| 995 | + dev_time, dev_time / (double)ticks_per_sec); | ||
| 996 | + term_printf("qemu time %lld (%0.3f)\n", | ||
| 997 | + qemu_time, qemu_time / (double)ticks_per_sec); | ||
| 998 | + term_printf("kqemu time %lld (%0.3f %0.1f%%) count=%lld int=%lld excp=%lld intr=%lld\n", | ||
| 999 | + kqemu_time, kqemu_time / (double)ticks_per_sec, | ||
| 1000 | + kqemu_time / (double)total * 100.0, | ||
| 1001 | + kqemu_exec_count, | ||
| 1002 | + kqemu_ret_int_count, | ||
| 1003 | + kqemu_ret_excp_count, | ||
| 1004 | + kqemu_ret_intr_count); | ||
| 1005 | + qemu_time = 0; | ||
| 1006 | + kqemu_time = 0; | ||
| 1007 | + kqemu_exec_count = 0; | ||
| 1008 | + dev_time = 0; | ||
| 1009 | + kqemu_ret_int_count = 0; | ||
| 1010 | + kqemu_ret_excp_count = 0; | ||
| 1011 | + kqemu_ret_intr_count = 0; | ||
| 1012 | +#ifdef USE_KQEMU | ||
| 1013 | + kqemu_record_dump(); | ||
| 1014 | +#endif | ||
| 1015 | +} | ||
| 1016 | +#else | ||
| 1017 | +static void do_info_profile(void) | ||
| 1018 | +{ | ||
| 1019 | + term_printf("Internal profiler not compiled\n"); | ||
| 1020 | +} | ||
| 1021 | +#endif | ||
| 1022 | + | ||
| 969 | static term_cmd_t term_cmds[] = { | 1023 | static term_cmd_t term_cmds[] = { |
| 970 | { "help|?", "s?", do_help, | 1024 | { "help|?", "s?", do_help, |
| 971 | "[cmd]", "show the help" }, | 1025 | "[cmd]", "show the help" }, |
| @@ -1054,6 +1108,8 @@ static term_cmd_t info_cmds[] = { | @@ -1054,6 +1108,8 @@ static term_cmd_t info_cmds[] = { | ||
| 1054 | "", "show guest USB devices", }, | 1108 | "", "show guest USB devices", }, |
| 1055 | { "usbhost", "", usb_host_info, | 1109 | { "usbhost", "", usb_host_info, |
| 1056 | "", "show host USB devices", }, | 1110 | "", "show host USB devices", }, |
| 1111 | + { "profile", "", do_info_profile, | ||
| 1112 | + "", "show profiling information", }, | ||
| 1057 | { NULL, NULL, }, | 1113 | { NULL, NULL, }, |
| 1058 | }; | 1114 | }; |
| 1059 | 1115 |