aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorStefan Raspl2017-03-10 06:40:06 -0600
committerPaolo Bonzini2017-03-29 05:01:27 -0500
commit184b2d23b057b35fba7fd4049962a897ef0e3f9d (patch)
treebac84a46b31f5eb514288408cb5f6882f6399e0a /tools
parent692c7f6deb553dde2531102cd10ac17ab61438e4 (diff)
downloadkernel-184b2d23b057b35fba7fd4049962a897ef0e3f9d.tar.gz
kernel-184b2d23b057b35fba7fd4049962a897ef0e3f9d.tar.xz
kernel-184b2d23b057b35fba7fd4049962a897ef0e3f9d.zip
tools/kvm_stat: reduce perceived idle time on filter updates
Whenever a user adds a filter, we * redraw the header immediately for a snappy response * print a message indicating to the user that we're busy while the noticeable delay induced by updating all of the stats objects takes place * update the statistics ASAP (i.e. after 0.25s instead of 3s) to be consistent with behavior on startup To do so, we split the Tui's refresh() method to allow for drawing header and stats separately, and trigger a header refresh whenever we are about to do something that takes a while - like updating filters. Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com> Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
Diffstat (limited to 'tools')
-rwxr-xr-xtools/kvm/kvm_stat/kvm_stat48
1 files changed, 30 insertions, 18 deletions
diff --git a/tools/kvm/kvm_stat/kvm_stat b/tools/kvm/kvm_stat/kvm_stat
index 5c4f24879dc4..3e60d93870c0 100755
--- a/tools/kvm/kvm_stat/kvm_stat
+++ b/tools/kvm/kvm_stat/kvm_stat
@@ -801,6 +801,8 @@ class Stats(object):
801 801
802LABEL_WIDTH = 40 802LABEL_WIDTH = 40
803NUMBER_WIDTH = 10 803NUMBER_WIDTH = 10
804DELAY_INITIAL = 0.25
805DELAY_REGULAR = 3.0
804 806
805 807
806class Tui(object): 808class Tui(object):
@@ -856,13 +858,14 @@ class Tui(object):
856 """Propagates pid selection to stats object.""" 858 """Propagates pid selection to stats object."""
857 self.stats.pid_filter = pid 859 self.stats.pid_filter = pid
858 860
859 def refresh(self, sleeptime): 861 def refresh_header(self, pid=None):
860 """Refreshes on-screen data.""" 862 """Refreshes the header."""
863 if pid is None:
864 pid = self.stats.pid_filter
861 self.screen.erase() 865 self.screen.erase()
862 if self.stats.pid_filter > 0: 866 if pid > 0:
863 self.screen.addstr(0, 0, 'kvm statistics - pid {0}' 867 self.screen.addstr(0, 0, 'kvm statistics - pid {0}'
864 .format(self.stats.pid_filter), 868 .format(pid), curses.A_BOLD)
865 curses.A_BOLD)
866 else: 869 else:
867 self.screen.addstr(0, 0, 'kvm statistics - summary', curses.A_BOLD) 870 self.screen.addstr(0, 0, 'kvm statistics - summary', curses.A_BOLD)
868 self.screen.addstr(2, 1, 'Event') 871 self.screen.addstr(2, 1, 'Event')
@@ -870,7 +873,13 @@ class Tui(object):
870 len('Total'), 'Total') 873 len('Total'), 'Total')
871 self.screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH + 8 - 874 self.screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH + 8 -
872 len('Current'), 'Current') 875 len('Current'), 'Current')
876 self.screen.addstr(4, 1, 'Collecting data...')
877 self.screen.refresh()
878
879 def refresh_body(self, sleeptime):
873 row = 3 880 row = 3
881 self.screen.move(row, 0)
882 self.screen.clrtobot()
874 stats = self.stats.get() 883 stats = self.stats.get()
875 884
876 def sortkey(x): 885 def sortkey(x):
@@ -914,10 +923,12 @@ class Tui(object):
914 regex = self.screen.getstr() 923 regex = self.screen.getstr()
915 curses.noecho() 924 curses.noecho()
916 if len(regex) == 0: 925 if len(regex) == 0:
926 self.refresh_header()
917 return 927 return
918 try: 928 try:
919 re.compile(regex) 929 re.compile(regex)
920 self.stats.fields_filter = regex 930 self.stats.fields_filter = regex
931 self.refresh_header()
921 return 932 return
922 except re.error: 933 except re.error:
923 continue 934 continue
@@ -944,37 +955,38 @@ class Tui(object):
944 955
945 try: 956 try:
946 pid = int(pid) 957 pid = int(pid)
947 958 if pid != 0 and not os.path.isdir(os.path.join('/proc/',
948 if pid == 0: 959 str(pid))):
949 self.update_pid(pid) 960 continue
950 break 961 self.refresh_header(pid)
951 else: 962 self.update_pid(pid)
952 if not os.path.isdir(os.path.join('/proc/', str(pid))): 963 break
953 continue
954 else:
955 self.update_pid(pid)
956 break
957 964
958 except ValueError: 965 except ValueError:
959 continue 966 continue
960 967
961 def show_stats(self): 968 def show_stats(self):
962 """Refreshes the screen and processes user input.""" 969 """Refreshes the screen and processes user input."""
963 sleeptime = 0.25 970 sleeptime = DELAY_INITIAL
971 self.refresh_header()
964 while True: 972 while True:
965 self.refresh(sleeptime) 973 self.refresh_body(sleeptime)
966 curses.halfdelay(int(sleeptime * 10)) 974 curses.halfdelay(int(sleeptime * 10))
967 sleeptime = 3.0 975 sleeptime = DELAY_REGULAR
968 try: 976 try:
969 char = self.screen.getkey() 977 char = self.screen.getkey()
970 if char == 'x': 978 if char == 'x':
979 self.refresh_header()
971 self.update_drilldown() 980 self.update_drilldown()
981 sleeptime = DELAY_INITIAL
972 if char == 'q': 982 if char == 'q':
973 break 983 break
974 if char == 'f': 984 if char == 'f':
975 self.show_filter_selection() 985 self.show_filter_selection()
986 sleeptime = DELAY_INITIAL
976 if char == 'p': 987 if char == 'p':
977 self.show_vm_selection() 988 self.show_vm_selection()
989 sleeptime = DELAY_INITIAL
978 except KeyboardInterrupt: 990 except KeyboardInterrupt:
979 break 991 break
980 except curses.error: 992 except curses.error: