$OpenBSD: patch-stats_c,v 1.9 2018/06/01 14:20:19 sthen Exp $

If devinfo.type != AUDIO_MIXER_CLASS is true, xstatbar will never make
progress and loop forever. Fix it by trying the next device.

Index: stats.c
--- stats.c.orig
+++ stats.c
@@ -101,8 +101,10 @@ volume_init()
    devinfo.index = 0;
    while (ioctl(volume.dev_fd, AUDIO_MIXER_DEVINFO, &devinfo) >= 0) {
 
-      if (devinfo.type != AUDIO_MIXER_CLASS)
+      if (devinfo.type != AUDIO_MIXER_CLASS) {
+         devinfo.index++;
          continue;
+      }
 
       if (strncmp(devinfo.label.name, AudioCoutputs, MAX_AUDIO_DEV_LEN) == 0)
          oclass_idx = devinfo.index;
@@ -358,7 +360,7 @@ sysinfo_init(int hist_size)
       err(1, "sysinfo init: memory calloc failed");
 
    for (i = 0; i < hist_size; i++) {
-      if ((sysinfo.memory[i] = calloc(3, sizeof(int))) == NULL)
+      if ((sysinfo.memory[i] = calloc(4, sizeof(int))) == NULL)
          err(1, "sysinfo init: memory[%d] calloc failed", i);
 
       for (j = 0; j < 3; j++)
@@ -405,9 +407,11 @@ sysinfo_update()
    static int mib_nprocs[] = { CTL_KERN, KERN_NPROCS };
    static int mib_vm[] = { CTL_VM, VM_METER };
    static int mib_cpus[] = { CTL_KERN, 0, 0 };
+   static int mib_bcstats[] = {CTL_VFS, VFS_GENERIC, VFS_BCACHESTAT};
    static int diffs[CPUSTATES] = { 0 };
    struct vmtotal vminfo;
    struct swapent *swapdev;
+   struct bcachestats bcstats;
    size_t    size;
    int       cpu, state;
    int       cur, prev;
@@ -431,9 +435,16 @@ sysinfo_update()
    if (sysctl(mib_vm, 2, &vminfo, &size, NULL, 0) < 0)
       err(1, "sysinfo update: VM.METER failed");
 
+   /* update bufcache statistics */
+   size = sizeof(bcstats);
+   if (sysctl(mib_bcstats, 3, &bcstats, &size, NULL, 0) < 0)
+      err(1, "sysinfo update: VFS_BCACHESTAT failed");
+
+
    sysinfo.memory[cur][MEM_ACT] = vminfo.t_arm << sysinfo.pageshift;
    sysinfo.memory[cur][MEM_TOT] = vminfo.t_rm << sysinfo.pageshift;
    sysinfo.memory[cur][MEM_FRE] = vminfo.t_free << sysinfo.pageshift;
+   sysinfo.memory[cur][MEM_CCH] = bcstats.numbufpages << sysinfo.pageshift;
 
    /* get swap status */
    if ((nswaps = swapctl(SWAP_NSWAP, 0, 0)) == 0)
@@ -509,9 +520,9 @@ int
 cpu_draw(int cpu, XColor color, int x, int y)
 {
    static char  str[1000];
-   static char *cpuStateNames[] = { "u", "n", "s", "i", "I" };
+   static char *cpuStateNames[] = { "u", "n", "s", "p", "i", "I" };
    static XColor *cpuStateColors[] = {
-      &COLOR_RED, &COLOR_BLUE, &COLOR_YELLOW, &COLOR_MAGENTA, &COLOR_GREEN
+      &COLOR_RED, &COLOR_BLUE, &COLOR_YELLOW, &COLOR_CYAN, &COLOR_MAGENTA, &COLOR_GREEN
    };
    int state, startx, time, col, h, i;
 
@@ -531,7 +542,7 @@ cpu_draw(int cpu, XColor color, int x, int y)
 
       /* user time */
       h = 0;
-      for (i = 0; i < 4; i++) h += sysinfo.cpu_pcnts[cpu][time][i];
+      for (i = 0; i < 5; i++) h += sysinfo.cpu_pcnts[cpu][time][i];
       h = h * XINFO.height / 100;
       XSetForeground(XINFO.disp, XINFO.gc, COLOR_RED.pixel);
       XDrawLine(XINFO.disp, XINFO.buf, XINFO.gc,
@@ -540,7 +551,7 @@ cpu_draw(int cpu, XColor color, int x, int y)
 
       /* nice time */
       h = 0;
-      for (i = 1; i < 4; i++) h += sysinfo.cpu_pcnts[cpu][time][i];
+      for (i = 1; i < 5; i++) h += sysinfo.cpu_pcnts[cpu][time][i];
       h = h * XINFO.height / 100;
       XSetForeground(XINFO.disp, XINFO.gc, COLOR_BLUE.pixel);
       XDrawLine(XINFO.disp, XINFO.buf, XINFO.gc,
@@ -549,15 +560,24 @@ cpu_draw(int cpu, XColor color, int x, int y)
 
       /* system time */
       h = 0;
-      for (i = 2; i < 4; i++) h += sysinfo.cpu_pcnts[cpu][time][i];
+      for (i = 2; i < 5; i++) h += sysinfo.cpu_pcnts[cpu][time][i];
       h = h * XINFO.height / 100;
       XSetForeground(XINFO.disp, XINFO.gc, COLOR_YELLOW.pixel);
       XDrawLine(XINFO.disp, XINFO.buf, XINFO.gc,
          x + col, XINFO.height - h,
          x + col, XINFO.height);
 
+      /* spin time */
+      h = 0;
+      for (i = 3; i < 5; i++) h += sysinfo.cpu_pcnts[cpu][time][i];
+      h = h * XINFO.height / 100;
+      XSetForeground(XINFO.disp, XINFO.gc, COLOR_CYAN.pixel);
+      XDrawLine(XINFO.disp, XINFO.buf, XINFO.gc,
+         x + col, XINFO.height - h,
+         x + col, XINFO.height);
+
       /* interrupt time */
-      h = sysinfo.cpu_pcnts[cpu][time][3];
+      h = sysinfo.cpu_pcnts[cpu][time][4];
       h = h * XINFO.height / 100;
       XSetForeground(XINFO.disp, XINFO.gc, COLOR_MAGENTA.pixel);
       XDrawLine(XINFO.disp, XINFO.buf, XINFO.gc,
@@ -594,7 +614,8 @@ mem_draw(XColor color, int x, int y)
    /* determine total memory */
    total = sysinfo.memory[cur][MEM_ACT]
          + sysinfo.memory[cur][MEM_TOT]
-         + sysinfo.memory[cur][MEM_FRE];
+         + sysinfo.memory[cur][MEM_FRE]
+         + sysinfo.memory[cur][MEM_CCH];
 
    /* start drawing ... */
    x += render_text(color, x, y, "mem:") + 1;
@@ -610,7 +631,8 @@ mem_draw(XColor color, int x, int y)
 
       if ((sysinfo.memory[time][MEM_ACT] != 0)
       ||  (sysinfo.memory[time][MEM_TOT] != 0)
-      ||  (sysinfo.memory[time][MEM_FRE] != 0)) {
+      ||  (sysinfo.memory[time][MEM_FRE] != 0)
+      ||  (sysinfo.memory[time][MEM_CCH] != 0)) {
 
 
          /* draw yellow (total) bar */
@@ -627,6 +649,13 @@ mem_draw(XColor color, int x, int y)
          XDrawLine(XINFO.disp, XINFO.buf, XINFO.gc,
             x + col, XINFO.height - h,
             x + col, XINFO.height);
+
+         /* draw magenta (cache) bar */
+         h = sysinfo.memory[time][MEM_CCH] * XINFO.height / total;
+         XSetForeground(XINFO.disp, XINFO.gc, COLOR_MAGENTA.pixel);
+         XDrawLine(XINFO.disp, XINFO.buf, XINFO.gc,
+            x + col, XINFO.height - h,
+            x + col, XINFO.height);
       }
 
       time = (time + 1) % sysinfo.hist_size;
@@ -639,6 +668,8 @@ mem_draw(XColor color, int x, int y)
    x += render_text(COLOR_YELLOW, x, y, fmtmem(sysinfo.memory[cur][MEM_TOT]));
    x += render_text(color, x, y, "/");
    x += render_text(COLOR_GREEN, x, y, fmtmem(sysinfo.memory[cur][MEM_FRE]));
+   x += render_text(color, x, y, "/");
+   x += render_text(COLOR_MAGENTA, x, y, fmtmem(sysinfo.memory[cur][MEM_CCH]));
 
    /* draw swap, if any is used */
    if (sysinfo.swap_used > 0) {
