ia64/xen-unstable

changeset 9717:7b9dacaf3340

This is a patch for XenMon which only applies to the userspace tools.
The primary purpose of this patch is to add support for non-polling
access to the xen trace buffers. The hypervisor changes have already
been accepted.

Also included are a few bug fixes and some minor new features:

1. If xenmon is run without first allocating trace buffers (via
'setsize') and enabling them (via 'tbctl'), then this is done
automatically using sensible defaults.

2. There was a bug that caused the first second's worth of data output
from xenmon to be erroneous; This has been fixed.

3. There was a bug that caused xenmon to sometimes not display data for
newly created domains; This has also been fixed.

4. The xenmon display has a 'heartbeat' which flickers once per second.
This is to show that xenmon is still alive, even though the display
isn't changing at all, a situation that can happen sometimes when there
is nothing at all happening on a particular cpu.

5. Added cpu utilization display to the top of the xenmon window.

6. Added a bunch of options in xenmon to control exactly which metrics
are displayed, so the screen doesn't get cluttered with stuff you're not
interested in. The new options are:
--allocated
--noallocated
--blocked
--noblocked
--waited
--nowaited
--excount
--noexcount
--iocount
--noiocount

7. Added an option ("--cpu=N") to xenmon to specify which physical cpu
you'd like data displayed for.

8. Updated the README with information about default trace buffer size, etc.

Signed-off-by: Rob Gardner <rob.gardner@hp.com>
author kaf24@firebug.cl.cam.ac.uk
date Fri Apr 14 14:21:12 2006 +0100 (2006-04-14)
parents 3a9d0c29ed72
children 40b124e270ee
files tools/xenmon/README tools/xenmon/xenbaked.c tools/xenmon/xenbaked.h tools/xenmon/xenmon.py
line diff
     1.1 --- a/tools/xenmon/README	Fri Apr 14 14:18:39 2006 +0100
     1.2 +++ b/tools/xenmon/README	Fri Apr 14 14:21:12 2006 +0100
     1.3 @@ -84,6 +84,16 @@ Usage Notes and issues
     1.4     events cause a trace record to be emitted.
     1.5   - To exit xenmon, type 'q'
     1.6   - To cycle the display to other physical cpu's, type 'c'
     1.7 + - The first time xenmon is run, it attempts to allocate xen trace buffers
     1.8 +   using a default size. If you wish to use a non-default value for the
     1.9 +   trace buffer size, run the 'setsize' program (located in tools/xentrace)
    1.10 +   and specify the number of memory pages as a parameter. The default is 20.
    1.11 + - Not well tested with domains using more than 1 virtual cpu
    1.12 + - If you create a lot of domains, or repeatedly kill a domain and restart it,
    1.13 +   and the domain id's get to be bigger than NDOMAINS, then xenmon behaves badly.
    1.14 +   This is a bug that is due to xenbaked's treatment of domain id's vs. domain
    1.15 +   indices in a data array. Will be fixed in a future release; Workaround:
    1.16 +   Increase NDOMAINS in xenbaked and rebuild.
    1.17  
    1.18  Future Work
    1.19  -----------
     2.1 --- a/tools/xenmon/xenbaked.c	Fri Apr 14 14:18:39 2006 +0100
     2.2 +++ b/tools/xenmon/xenbaked.c	Fri Apr 14 14:21:12 2006 +0100
     2.3 @@ -7,6 +7,7 @@
     2.4   *
     2.5   * Copyright (C) 2004 by Intel Research Cambridge
     2.6   * Copyright (C) 2005 by Hewlett Packard, Palo Alto and Fort Collins
     2.7 + * Copyright (C) 2006 by Hewlett Packard Fort Collins
     2.8   *
     2.9   * Authors: Diwaker Gupta, diwaker.gupta@hp.com
    2.10   *          Rob Gardner, rob.gardner@hp.com
    2.11 @@ -42,6 +43,8 @@
    2.12  #include <xenctrl.h>
    2.13  #include <xen/xen.h>
    2.14  #include <string.h>
    2.15 +#include <sys/select.h>
    2.16 +#include <xen/linux/evtchn.h>
    2.17  
    2.18  #include "xc_private.h"
    2.19  typedef struct { int counter; } atomic_t;
    2.20 @@ -81,6 +84,7 @@ settings_t opts;
    2.21  
    2.22  int interrupted = 0; /* gets set if we get a SIGHUP */
    2.23  int rec_count = 0;
    2.24 +int wakeups = 0;
    2.25  time_t start_time;
    2.26  int dom0_flips = 0;
    2.27  
    2.28 @@ -88,8 +92,6 @@ int dom0_flips = 0;
    2.29  _new_qos_data **cpu_qos_data;
    2.30  
    2.31  
    2.32 -#define ID(X) ((X>NDOMAINS-1)?(NDOMAINS-1):X)
    2.33 -
    2.34  // array of currently running domains, indexed by cpu
    2.35  int *running = NULL;
    2.36  
    2.37 @@ -223,6 +225,9 @@ void dump_stats(void)
    2.38      printf("processed %d total records in %d seconds (%ld per second)\n",
    2.39              rec_count, (int)run_time, rec_count/run_time);
    2.40  
    2.41 +    printf("woke up %d times in %d seconds (%ld per second)\n", wakeups,
    2.42 +	   (int) run_time, wakeups/run_time);
    2.43 +
    2.44      check_gotten_sum();
    2.45  }
    2.46  
    2.47 @@ -243,6 +248,112 @@ void log_event(int event_id)
    2.48          stat_map[0].event_count++;	// other
    2.49  }
    2.50  
    2.51 +#define EVTCHN_DEV_NAME  "/dev/xen/evtchn"
    2.52 +#define EVTCHN_DEV_MAJOR 10
    2.53 +#define EVTCHN_DEV_MINOR 201
    2.54 +
    2.55 +int virq_port;
    2.56 +int eventchn_fd = -1;
    2.57 +
    2.58 +/* Returns the event channel handle. */
    2.59 +/* Stolen from xenstore code */
    2.60 +int eventchn_init(void)
    2.61 +{
    2.62 +  struct stat st;
    2.63 +  struct ioctl_evtchn_bind_virq bind;
    2.64 +  int rc;
    2.65 +  
    2.66 +  // to revert to old way:
    2.67 +  if (0)
    2.68 +    return -1;
    2.69 +  
    2.70 +  /* Make sure any existing device file links to correct device. */
    2.71 +  if ((lstat(EVTCHN_DEV_NAME, &st) != 0) || !S_ISCHR(st.st_mode) ||
    2.72 +      (st.st_rdev != makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR)))
    2.73 +    (void)unlink(EVTCHN_DEV_NAME);
    2.74 +  
    2.75 + reopen:
    2.76 +  eventchn_fd = open(EVTCHN_DEV_NAME, O_NONBLOCK|O_RDWR);
    2.77 +  if (eventchn_fd == -1) {
    2.78 +    if ((errno == ENOENT) &&
    2.79 +	((mkdir("/dev/xen", 0755) == 0) || (errno == EEXIST)) &&
    2.80 +	(mknod(EVTCHN_DEV_NAME, S_IFCHR|0600,
    2.81 +	       makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR)) == 0))
    2.82 +      goto reopen;
    2.83 +    return -errno;
    2.84 +  }
    2.85 +  
    2.86 +  if (eventchn_fd < 0)
    2.87 +    perror("Failed to open evtchn device");
    2.88 +  
    2.89 +  bind.virq = VIRQ_TBUF;
    2.90 +  rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_VIRQ, &bind);
    2.91 +  if (rc == -1)
    2.92 +    perror("Failed to bind to domain exception virq port");
    2.93 +  virq_port = rc;
    2.94 +  
    2.95 +  return eventchn_fd;
    2.96 +}
    2.97 +
    2.98 +void wait_for_event(void)
    2.99 +{
   2.100 +  int ret;
   2.101 +  fd_set inset;
   2.102 +  evtchn_port_t port;
   2.103 +  struct timeval tv;
   2.104 +  
   2.105 +  if (eventchn_fd < 0) {
   2.106 +    nanosleep(&opts.poll_sleep, NULL);
   2.107 +    return;
   2.108 +  }
   2.109 +
   2.110 +  FD_ZERO(&inset);
   2.111 +  FD_SET(eventchn_fd, &inset);
   2.112 +  tv.tv_sec = 1;
   2.113 +  tv.tv_usec = 0;
   2.114 +  // tv = millis_to_timespec(&opts.poll_sleep);
   2.115 +  ret = select(eventchn_fd+1, &inset, NULL, NULL, &tv);
   2.116 +  
   2.117 +  if ( (ret == 1) && FD_ISSET(eventchn_fd, &inset)) {
   2.118 +    if (read(eventchn_fd, &port, sizeof(port)) != sizeof(port))
   2.119 +      perror("Failed to read from event fd");
   2.120 +    
   2.121 +    //    if (port == virq_port)
   2.122 +    //      printf("got the event I was looking for\r\n");
   2.123 +    
   2.124 +    if (write(eventchn_fd, &port, sizeof(port)) != sizeof(port))
   2.125 +      perror("Failed to write to event fd");
   2.126 +  }
   2.127 +}
   2.128 +
   2.129 +void enable_tracing_or_die(int xc_handle) 
   2.130 +{
   2.131 +  int enable = 1;
   2.132 +  int tbsize = DEFAULT_TBUF_SIZE;
   2.133 +  
   2.134 +  if (xc_tbuf_enable(xc_handle, enable) != 0) {
   2.135 +    if (xc_tbuf_set_size(xc_handle, tbsize) != 0) {
   2.136 +      perror("set_size Hypercall failure");
   2.137 +      exit(1);
   2.138 +    }
   2.139 +    printf("Set default trace buffer allocation (%d pages)\n", tbsize);
   2.140 +    if (xc_tbuf_enable(xc_handle, enable) != 0) {
   2.141 +      perror("Could not enable trace buffers\n");
   2.142 +      exit(1);
   2.143 +    }
   2.144 +  }
   2.145 +  else
   2.146 +    printf("Tracing enabled\n");
   2.147 +}
   2.148 +
   2.149 +void disable_tracing(void)
   2.150 +{
   2.151 +  int enable = 0;
   2.152 +  int xc_handle = xc_interface_open();
   2.153 +    
   2.154 +  xc_tbuf_enable(xc_handle, enable);
   2.155 +  xc_interface_close(xc_handle);
   2.156 +}
   2.157  
   2.158  
   2.159  /**
   2.160 @@ -258,6 +369,17 @@ void get_tbufs(unsigned long *mfn, unsig
   2.161      int ret;
   2.162      dom0_op_t op;                        /* dom0 op we'll build             */
   2.163      int xc_handle = xc_interface_open(); /* for accessing control interface */
   2.164 +    unsigned int tbsize;
   2.165 +
   2.166 +    enable_tracing_or_die(xc_handle);
   2.167 +
   2.168 +    if (xc_tbuf_get_size(xc_handle, &tbsize) != 0) {
   2.169 +      perror("Failure to get tbuf info from Xen. Guess size is 0?");
   2.170 +      exit(1);
   2.171 +    }
   2.172 +    else
   2.173 +      printf("Current tbuf size: 0x%x\n", tbsize);
   2.174 +    
   2.175  
   2.176      op.cmd = DOM0_TBUFCONTROL;
   2.177      op.interface_version = DOM0_INTERFACE_VERSION;
   2.178 @@ -448,6 +570,11 @@ int monitor_tbufs(void)
   2.179      meta  = init_bufs_ptrs (tbufs_mapped, num, size);
   2.180      data  = init_rec_ptrs(meta, num);
   2.181  
   2.182 +    // Set up event channel for select()
   2.183 +    if (eventchn_init() < 0) {
   2.184 +      fprintf(stderr, "Failed to initialize event channel; Using POLL method\r\n");
   2.185 +    }
   2.186 +
   2.187      /* now, scan buffers for events */
   2.188      while ( !interrupted )
   2.189      {
   2.190 @@ -460,7 +587,8 @@ int monitor_tbufs(void)
   2.191                  meta[i]->cons++;
   2.192              }
   2.193  
   2.194 -        nanosleep(&opts.poll_sleep, NULL);
   2.195 +	wait_for_event();
   2.196 +	wakeups++;
   2.197      }
   2.198  
   2.199      /* cleanup */
   2.200 @@ -640,6 +768,7 @@ int main(int argc, char **argv)
   2.201  
   2.202      dump_stats();
   2.203      msync(new_qos, sizeof(_new_qos_data), MS_SYNC);
   2.204 +    disable_tracing();
   2.205  
   2.206      return ret;
   2.207  }
   2.208 @@ -737,7 +866,9 @@ void qos_update_thread(int cpu, int domi
   2.209          start = new_qos->domain_info[id].start_time;
   2.210          if (start > now) {		// wrapped around
   2.211              run_time = now + (~0ULL - start);
   2.212 -	    printf("warning: start > now\n");
   2.213 +	    // this could happen if there is nothing going on within a cpu;
   2.214 +	    // in this case the idle domain would run forever
   2.215 +	    //        printf("warning: start > now\n");
   2.216          }
   2.217          else
   2.218              run_time = now - start;
   2.219 @@ -746,11 +877,11 @@ void qos_update_thread(int cpu, int domi
   2.220          new_qos->domain_info[id].ns_oncpu_since_boot += run_time;
   2.221          new_qos->domain_info[id].start_time = now;
   2.222          new_qos->domain_info[id].ns_since_boot += time_since_update;
   2.223 -#if 1
   2.224 +
   2.225  	new_qos->qdata[n].ns_gotten[id] += run_time;
   2.226 -	if (domid == 0 && cpu == 1)
   2.227 -	  printf("adding run time for dom0 on cpu1\r\n");
   2.228 -#endif
   2.229 +	//	if (domid == 0 && cpu == 1)
   2.230 +	//	  printf("adding run time for dom0 on cpu1\r\n");
   2.231 +
   2.232      }
   2.233  
   2.234      new_qos->domain_info[id].runnable_at_last_update = domain_runnable(domid);
   2.235 @@ -916,13 +1047,13 @@ void qos_state_runnable(int cpu, int dom
   2.236  {
   2.237      int id = ID(domid);
   2.238  
   2.239 +    qos_update_thread_stats(cpu, domid, now);
   2.240 +
   2.241      if (domain_runnable(id))	// double call?
   2.242          return;
   2.243      new_qos->domain_info[id].runnable = 1;
   2.244      update_blocked_time(domid, now);
   2.245  
   2.246 -    qos_update_thread_stats(cpu, domid, now);
   2.247 -
   2.248      new_qos->domain_info[id].blocked_start_time = 0; /* invalidate */
   2.249      new_qos->domain_info[id].runnable_start_time = now;
   2.250      //  runnable_start_time[id] = now;
   2.251 @@ -951,7 +1082,7 @@ int domain_ok(int cpu, int domid, uint64
   2.252      if (domid == IDLE_DOMAIN_ID)
   2.253          domid = NDOMAINS-1;
   2.254      if (domid < 0 || domid >= NDOMAINS) {
   2.255 -        printf("bad domain id: %d\n", domid);
   2.256 +        printf("bad domain id: %d\r\n", domid);
   2.257          return 0;
   2.258      }
   2.259      if (new_qos->domain_info[domid].in_use == 0)
     3.1 --- a/tools/xenmon/xenbaked.h	Fri Apr 14 14:18:39 2006 +0100
     3.2 +++ b/tools/xenmon/xenbaked.h	Fri Apr 14 14:21:12 2006 +0100
     3.3 @@ -1,5 +1,5 @@
     3.4  /******************************************************************************
     3.5 - * tools/xenbaked.h
     3.6 + * TOOLS/xenbaked.h
     3.7   *
     3.8   * Header file for xenbaked
     3.9   *
    3.10 @@ -30,6 +30,7 @@
    3.11  #define million 1000000LL
    3.12  #define billion 1000000000LL
    3.13  
    3.14 +// caution: don't use QOS_ADD with negative numbers!
    3.15  #define QOS_ADD(N,A) ((N+A)<(NSAMPLES-1) ? (N+A) : A)
    3.16  #define QOS_INCR(N) ((N<(NSAMPLES-2)) ? (N+1) : 0)
    3.17  #define QOS_DECR(N) ((N==0) ? (NSAMPLES-1) : (N-1))
    3.18 @@ -43,6 +44,8 @@
    3.19  /* Number of data points to keep */
    3.20  #define NSAMPLES 100
    3.21  
    3.22 +#define ID(X) ((X>NDOMAINS-1)?(NDOMAINS-1):X)
    3.23 +#define DEFAULT_TBUF_SIZE 20
    3.24  
    3.25  // per domain stuff
    3.26  typedef struct 
     4.1 --- a/tools/xenmon/xenmon.py	Fri Apr 14 14:18:39 2006 +0100
     4.2 +++ b/tools/xenmon/xenmon.py	Fri Apr 14 14:21:12 2006 +0100
     4.3 @@ -5,7 +5,7 @@
     4.4  # There is a curses interface for live monitoring. XenMon also allows
     4.5  # logging to a file. For options, run python xenmon.py -h
     4.6  #
     4.7 -# Copyright (C) 2005 by Hewlett Packard, Palo Alto and Fort Collins
     4.8 +# Copyright (C) 2005,2006 by Hewlett Packard, Palo Alto and Fort Collins
     4.9  # Authors: Lucy Cherkasova, lucy.cherkasova@hp.com
    4.10  #          Rob Gardner, rob.gardner@hp.com
    4.11  #          Diwaker Gupta, diwaker.gupta@hp.com
    4.12 @@ -85,6 +85,33 @@ def setup_cmdline_parser():
    4.13      parser.add_option("--ms_per_sample", dest="mspersample",
    4.14              action="store", type="int", default=100,
    4.15              help = "determines how many ms worth of data goes in a sample")
    4.16 +    parser.add_option("--cpu", dest="cpu", action="store", type="int", default=0,
    4.17 +            help = "specifies which cpu to display data for")
    4.18 +
    4.19 +    parser.add_option("--allocated", dest="allocated", action="store_true",
    4.20 +                      default=False, help="Display allocated time for each domain")
    4.21 +    parser.add_option("--noallocated", dest="allocated", action="store_false",
    4.22 +                      default=False, help="Don't display allocated time for each domain")
    4.23 +
    4.24 +    parser.add_option("--blocked", dest="blocked", action="store_true",
    4.25 +                      default=True, help="Display blocked time for each domain")
    4.26 +    parser.add_option("--noblocked", dest="blocked", action="store_false",
    4.27 +                      default=True, help="Don't display blocked time for each domain")
    4.28 +
    4.29 +    parser.add_option("--waited", dest="waited", action="store_true",
    4.30 +                      default=True, help="Display waiting time for each domain")
    4.31 +    parser.add_option("--nowaited", dest="waited", action="store_false",
    4.32 +                      default=True, help="Don't display waiting time for each domain")
    4.33 +
    4.34 +    parser.add_option("--excount", dest="excount", action="store_true",
    4.35 +                      default=False, help="Display execution count for each domain")
    4.36 +    parser.add_option("--noexcount", dest="excount", action="store_false",
    4.37 +                      default=False, help="Don't display execution count for each domain")
    4.38 +    parser.add_option("--iocount", dest="iocount", action="store_true",
    4.39 +                      default=False, help="Display I/O count for each domain")
    4.40 +    parser.add_option("--noiocount", dest="iocount", action="store_false",
    4.41 +                      default=False, help="Don't display I/O count for each domain")
    4.42 +
    4.43      return parser
    4.44  
    4.45  # encapsulate information about a domain
    4.46 @@ -227,20 +254,18 @@ def display(scr, row, col, str, attr=0):
    4.47  
    4.48  
    4.49  # the live monitoring code
    4.50 -def show_livestats():
    4.51 -    cpu = 0          # cpu of interest to display data for
    4.52 +def show_livestats(cpu):
    4.53      ncpu = 1         # number of cpu's on this platform
    4.54      slen = 0         # size of shared data structure, incuding padding
    4.55 -    global dom_in_use
    4.56 +    cpu_1sec_usage = 0.0
    4.57 +    cpu_10sec_usage = 0.0
    4.58 +    heartbeat = 1
    4.59 +    global dom_in_use, options
    4.60      
    4.61      # mmap the (the first chunk of the) file
    4.62      shmf = open(SHM_FILE, "r+")
    4.63      shm = mmap.mmap(shmf.fileno(), QOS_DATA_SIZE)
    4.64  
    4.65 -    samples = []
    4.66 -    doms = []
    4.67 -    dom_in_use = []
    4.68 -
    4.69      # initialize curses
    4.70      stdscr = _c.initscr()
    4.71      _c.noecho()
    4.72 @@ -253,7 +278,8 @@ def show_livestats():
    4.73      # display in a loop
    4.74      while True:
    4.75  
    4.76 -        for cpuidx in range(0, ncpu):
    4.77 +        cpuidx = 0
    4.78 +        while cpuidx < ncpu:
    4.79  
    4.80              # calculate offset in mmap file to start from
    4.81              idx = cpuidx * slen
    4.82 @@ -261,6 +287,7 @@ def show_livestats():
    4.83  
    4.84              samples = []
    4.85              doms = []
    4.86 +            dom_in_use = []
    4.87  
    4.88              # read in data
    4.89              for i in range(0, NSAMPLES):
    4.90 @@ -279,6 +306,8 @@ def show_livestats():
    4.91  #		dom_in_use.append(in_use)
    4.92                  dom_in_use.append(dom[8])
    4.93                  idx += len
    4.94 +#            print "dom_in_use(cpu=%d): " % cpuidx, dom_in_use
    4.95 +
    4.96  
    4.97              len = struct.calcsize("4i")
    4.98              oldncpu = ncpu
    4.99 @@ -295,6 +324,8 @@ def show_livestats():
   4.100              if cpuidx == cpu:
   4.101                  break
   4.102  
   4.103 +            cpuidx = cpuidx + 1
   4.104 +
   4.105          # calculate starting and ending datapoints; never look at "next" since
   4.106          # it represents live data that may be in transition. 
   4.107          startat = next - 1
   4.108 @@ -312,13 +343,16 @@ def show_livestats():
   4.109          row = 0
   4.110          display(stdscr, row, 1, "CPU = %d" % cpu, _c.A_STANDOUT)
   4.111  
   4.112 -        display(stdscr, row, 10, "%sLast 10 seconds%sLast 1 second" % (6*' ', 30*' '), _c.A_BOLD)
   4.113 +        display(stdscr, row, 10, "%sLast 10 seconds (%3.2f%%)%sLast 1 second (%3.2f%%)" % (6*' ', cpu_10sec_usage, 30*' ', cpu_1sec_usage), _c.A_BOLD)
   4.114          row +=1
   4.115          display(stdscr, row, 1, "%s" % ((maxx-2)*'='))
   4.116  
   4.117          total_h1_cpu = 0
   4.118          total_h2_cpu = 0
   4.119  
   4.120 +        cpu_1sec_usage = 0.0
   4.121 +        cpu_10sec_usage = 0.0
   4.122 +
   4.123          for dom in range(0, NDOMAINS):
   4.124              if not dom_in_use[dom]:
   4.125                  continue
   4.126 @@ -332,92 +366,102 @@ def show_livestats():
   4.127                  display(stdscr, row, col, "%s" % time_scale(h2[dom][0][0]))
   4.128                  col += 12
   4.129                  display(stdscr, row, col, "%3.2f%%" % h2[dom][0][1])
   4.130 +                if dom != NDOMAINS - 1:
   4.131 +                    cpu_10sec_usage += h2[dom][0][1]
   4.132                  col += 12
   4.133                  display(stdscr, row, col, "%s/ex" % time_scale(h2[dom][0][2]))
   4.134                  col += 18
   4.135                  display(stdscr, row, col, "%s" % time_scale(h1[dom][0][0]))
   4.136                  col += 12
   4.137 -                display(stdscr, row, col, "%3.2f%%" % h1[dom][0][1])
   4.138 +                display(stdscr, row, col, "%3.2f%%" % h1[dom][0][1], _c.A_STANDOUT)
   4.139                  col += 12
   4.140                  display(stdscr, row, col, "%s/ex" % time_scale(h1[dom][0][2]))
   4.141                  col += 18
   4.142                  display(stdscr, row, col, "Gotten")
   4.143 +
   4.144 +                if dom != NDOMAINS - 1:
   4.145 +                    cpu_1sec_usage = cpu_1sec_usage + h1[dom][0][1]
   4.146      
   4.147                  # display allocated
   4.148 -                row += 1
   4.149 -                col = 2
   4.150 -                display(stdscr, row, col, "%d" % dom)
   4.151 -                col += 28
   4.152 -                display(stdscr, row, col, "%s/ex" % time_scale(h2[dom][1]))
   4.153 -                col += 42
   4.154 -                display(stdscr, row, col, "%s/ex" % time_scale(h1[dom][1]))
   4.155 -                col += 18
   4.156 -                display(stdscr, row, col, "Allocated")
   4.157 +                if options.allocated:
   4.158 +                    row += 1
   4.159 +                    col = 2
   4.160 +                    display(stdscr, row, col, "%d" % dom)
   4.161 +                    col += 28
   4.162 +                    display(stdscr, row, col, "%s/ex" % time_scale(h2[dom][1]))
   4.163 +                    col += 42
   4.164 +                    display(stdscr, row, col, "%s/ex" % time_scale(h1[dom][1]))
   4.165 +                    col += 18
   4.166 +                    display(stdscr, row, col, "Allocated")
   4.167  
   4.168                  # display blocked
   4.169 -                row += 1
   4.170 -                col = 2
   4.171 -                display(stdscr, row, col, "%d" % dom)
   4.172 -                col += 4
   4.173 -                display(stdscr, row, col, "%s" % time_scale(h2[dom][2][0]))
   4.174 -                col += 12
   4.175 -                display(stdscr, row, col, "%3.2f%%" % h2[dom][2][1])
   4.176 -                col += 12
   4.177 -                display(stdscr, row, col, "%s/io" % time_scale(h2[dom][2][2]))
   4.178 -                col += 18
   4.179 -                display(stdscr, row, col, "%s" % time_scale(h1[dom][2][0]))
   4.180 -                col += 12
   4.181 -                display(stdscr, row, col, "%3.2f%%" % h1[dom][2][1])
   4.182 -                col += 12
   4.183 -                display(stdscr, row, col, "%s/io" % time_scale(h1[dom][2][2]))
   4.184 -                col += 18
   4.185 -                display(stdscr, row, col, "Blocked")
   4.186 +                if options.blocked:
   4.187 +                    row += 1
   4.188 +                    col = 2
   4.189 +                    display(stdscr, row, col, "%d" % dom)
   4.190 +                    col += 4
   4.191 +                    display(stdscr, row, col, "%s" % time_scale(h2[dom][2][0]))
   4.192 +                    col += 12
   4.193 +                    display(stdscr, row, col, "%3.2f%%" % h2[dom][2][1])
   4.194 +                    col += 12
   4.195 +                    display(stdscr, row, col, "%s/io" % time_scale(h2[dom][2][2]))
   4.196 +                    col += 18
   4.197 +                    display(stdscr, row, col, "%s" % time_scale(h1[dom][2][0]))
   4.198 +                    col += 12
   4.199 +                    display(stdscr, row, col, "%3.2f%%" % h1[dom][2][1])
   4.200 +                    col += 12
   4.201 +                    display(stdscr, row, col, "%s/io" % time_scale(h1[dom][2][2]))
   4.202 +                    col += 18
   4.203 +                    display(stdscr, row, col, "Blocked")
   4.204  
   4.205                  # display waited
   4.206 -                row += 1
   4.207 -                col = 2
   4.208 -                display(stdscr, row, col, "%d" % dom)
   4.209 -                col += 4
   4.210 -                display(stdscr, row, col, "%s" % time_scale(h2[dom][3][0]))
   4.211 -                col += 12
   4.212 -                display(stdscr, row, col, "%3.2f%%" % h2[dom][3][1])
   4.213 -                col += 12
   4.214 -                display(stdscr, row, col, "%s/ex" % time_scale(h2[dom][3][2]))
   4.215 -                col += 18
   4.216 -                display(stdscr, row, col, "%s" % time_scale(h1[dom][3][0]))
   4.217 -                col += 12
   4.218 -                display(stdscr, row, col, "%3.2f%%" % h1[dom][3][1])
   4.219 -                col += 12
   4.220 -                display(stdscr, row, col, "%s/ex" % time_scale(h1[dom][3][2]))
   4.221 -                col += 18
   4.222 -                display(stdscr, row, col, "Waited")
   4.223 +                if options.waited:
   4.224 +                    row += 1
   4.225 +                    col = 2
   4.226 +                    display(stdscr, row, col, "%d" % dom)
   4.227 +                    col += 4
   4.228 +                    display(stdscr, row, col, "%s" % time_scale(h2[dom][3][0]))
   4.229 +                    col += 12
   4.230 +                    display(stdscr, row, col, "%3.2f%%" % h2[dom][3][1])
   4.231 +                    col += 12
   4.232 +                    display(stdscr, row, col, "%s/ex" % time_scale(h2[dom][3][2]))
   4.233 +                    col += 18
   4.234 +                    display(stdscr, row, col, "%s" % time_scale(h1[dom][3][0]))
   4.235 +                    col += 12
   4.236 +                    display(stdscr, row, col, "%3.2f%%" % h1[dom][3][1])
   4.237 +                    col += 12
   4.238 +                    display(stdscr, row, col, "%s/ex" % time_scale(h1[dom][3][2]))
   4.239 +                    col += 18
   4.240 +                    display(stdscr, row, col, "Waited")
   4.241  
   4.242                  # display ex count
   4.243 -                row += 1
   4.244 -                col = 2
   4.245 -                display(stdscr, row, col, "%d" % dom)
   4.246 -
   4.247 -                col += 28
   4.248 -                display(stdscr, row, col, "%d/s" % h2[dom][4])
   4.249 -                col += 42
   4.250 -                display(stdscr, row, col, "%d" % h1[dom][4])
   4.251 -                col += 18
   4.252 -                display(stdscr, row, col, "Execution count")
   4.253 +                if options.excount:
   4.254 +                    row += 1
   4.255 +                    col = 2
   4.256 +                    display(stdscr, row, col, "%d" % dom)
   4.257 +                    
   4.258 +                    col += 28
   4.259 +                    display(stdscr, row, col, "%d/s" % h2[dom][4])
   4.260 +                    col += 42
   4.261 +                    display(stdscr, row, col, "%d" % h1[dom][4])
   4.262 +                    col += 18
   4.263 +                    display(stdscr, row, col, "Execution count")
   4.264  
   4.265                  # display io count
   4.266 -                row += 1
   4.267 -                col = 2
   4.268 -                display(stdscr, row, col, "%d" % dom)
   4.269 -                col += 4
   4.270 -                display(stdscr, row, col, "%d/s" % h2[dom][5][0])
   4.271 -                col += 24
   4.272 -                display(stdscr, row, col, "%d/ex" % h2[dom][5][1])
   4.273 -                col += 18
   4.274 -                display(stdscr, row, col, "%d" % h1[dom][5][0])
   4.275 -                col += 24
   4.276 -                display(stdscr, row, col, "%3.2f/ex" % h1[dom][5][1])
   4.277 -                col += 18
   4.278 -                display(stdscr, row, col, "I/O Count")
   4.279 +                if options.iocount:
   4.280 +                    row += 1
   4.281 +                    col = 2
   4.282 +                    display(stdscr, row, col, "%d" % dom)
   4.283 +                    col += 4
   4.284 +                    display(stdscr, row, col, "%d/s" % h2[dom][5][0])
   4.285 +                    col += 24
   4.286 +                    display(stdscr, row, col, "%d/ex" % h2[dom][5][1])
   4.287 +                    col += 18
   4.288 +                    display(stdscr, row, col, "%d" % h1[dom][5][0])
   4.289 +                    col += 24
   4.290 +                    display(stdscr, row, col, "%3.2f/ex" % h1[dom][5][1])
   4.291 +                    col += 18
   4.292 +                    display(stdscr, row, col, "I/O Count")
   4.293  
   4.294              #row += 1
   4.295              #stdscr.hline(row, 1, '-', maxx - 2)
   4.296 @@ -426,6 +470,9 @@ def show_livestats():
   4.297  
   4.298  
   4.299          row += 1
   4.300 +        star = heartbeat * '*'
   4.301 +        heartbeat = 1 - heartbeat
   4.302 +        display(stdscr, row, 1, star)
   4.303          display(stdscr, row, 2, TOTALS % (total_h2_cpu, total_h1_cpu))
   4.304          row += 1
   4.305  #        display(stdscr, row, 2, 
   4.306 @@ -515,11 +562,11 @@ def writelog():
   4.307          outfiles[dom].delayed_write("# passed cpu dom cpu(tot) cpu(%) cpu/ex allocated/ex blocked(tot) blocked(%) blocked/io waited(tot) waited(%) waited/ex ex/s io(tot) io/ex\n")
   4.308  
   4.309      while options.duration == 0 or interval < (options.duration * 1000):
   4.310 -        for cpuidx in range(0, ncpu):
   4.311 +        cpuidx = 0
   4.312 +        while cpuidx < ncpu:
   4.313  
   4.314              idx = cpuidx * slen      # offset needed in mmap file
   4.315  
   4.316 -
   4.317              samples = []
   4.318              doms = []
   4.319              dom_in_use = []
   4.320 @@ -571,6 +618,7 @@ def writelog():
   4.321              curr = time.time()
   4.322              interval += (curr - last) * 1000
   4.323              last = curr
   4.324 +            cpuidx = cpuidx + 1
   4.325          time.sleep(options.interval / 1000.0)
   4.326  
   4.327      for dom in range(0, NDOMAINS):
   4.328 @@ -601,7 +649,7 @@ def main():
   4.329      
   4.330      start_xenbaked()
   4.331      if options.live:
   4.332 -        show_livestats()
   4.333 +        show_livestats(options.cpu)
   4.334      else:
   4.335          try:
   4.336              writelog()