[BACK]Return to pigs.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / systat

Diff for /src/usr.bin/systat/pigs.c between version 1.21 and 1.22

version 1.21, 2007/09/02 15:19:35 version 1.22, 2008/06/12 22:26:01
Line 30 
Line 30 
  * SUCH DAMAGE.   * SUCH DAMAGE.
  */   */
   
 #ifndef lint  
 #if 0  
 static char sccsid[] = "@(#)pigs.c      8.2 (Berkeley) 9/23/93";  
 #endif  
 static char rcsid[] = "$OpenBSD$";  
 #endif /* not lint */  
   
 /*  /*
  * Pigs display from Bill Reeves at Lucasfilm   * Pigs display from Bill Reeves at Lucasfilm
  */   */
Line 56 
Line 49 
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
   
 #include "extern.h"  
 #include "systat.h"  #include "systat.h"
   
 int compar(const void *, const void *);  int compar(const void *, const void *);
   void print_pg(void);
   int read_pg(void);
   int select_pg(void);
   void showpigs(int k);
   
 static int nproc;  static struct kinfo_proc2 *procbase = NULL;
 static struct p_times {  static int nproc, pigs_cnt, *pb_indices = NULL;
         float pt_pctcpu;  static int onproc = -1;
         struct kinfo_proc2 *pt_kp;  
 } *pt;  
   
 static long stime[CPUSTATES];  static long stime[CPUSTATES];
 static double  lccpu;  static double  lccpu;
   struct loadavg sysload;
   
 WINDOW *  
 openpigs(void)  
 {  
         return (subwin(stdscr, LINES-1-2, 0, 2, 0));  
 }  
   
 void  
 closepigs(WINDOW *w)  
 {  
         if (w == NULL)  
                 return;  
         wclear(w);  
         wrefresh(w);  
         delwin(w);  
 }  
   
   field_def fields_pg[] = {
           {"USER", 6, 16, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0},
           {"NAME", 10, 24, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0},
           {"PID", 5, 8, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
           {"CPU", 5, 8, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
           {"", 30, 60, 1, FLD_ALIGN_BAR, -1, 0, 0, 100},
   };
   
 void  #define FIELD_ADDR(x) (&fields_pg[x])
 showpigs(void)  
 {  
         int i, j, y, k;  
         struct kinfo_proc2 *kp;  
         float total;  
         int factor;  
         char *uname, *pname, pidname[30];  
   
         if (pt == NULL)  #define FLD_PG_USER     FIELD_ADDR(0)
                 return;  #define FLD_PG_NAME     FIELD_ADDR(1)
         /* Accumulate the percent of cpu per user. */  #define FLD_PG_PID      FIELD_ADDR(2)
         total = 0.0;  #define FLD_PG_VALUE    FIELD_ADDR(3)
         for (i = 0; i <= nproc; i++) {  #define FLD_PG_BAR      FIELD_ADDR(4)
                 /* Accumulate the percentage. */  
                 total += pt[i].pt_pctcpu;  
         }  
   
         if (total < 1.0)  /* Define views */
                 total = 1.0;  field_def *view_pg_0[] = {
         factor = 50.0/total;          FLD_PG_PID, FLD_PG_USER, FLD_PG_NAME, FLD_PG_VALUE, FLD_PG_BAR, NULL
   };
   
         qsort(pt, nproc + 1, sizeof (struct p_times), compar);  
         y = 1;  /* Define view managers */
         i = nproc + 1;  struct view_manager pigs_mgr = {
         if (i > wnd->_maxy-1)          "Pigs", select_pg, read_pg, NULL, print_header,
                 i = wnd->_maxy-1;          print_pg, keyboard_callback, NULL, NULL
         for (k = 0; i > 0 && pt[k].pt_pctcpu > 0.01; i--, y++, k++) {  };
                 kp = pt[k].pt_kp;  
                 if (kp == NULL) {  field_view views_pg[] = {
                         uname = "";          {view_pg_0, "pigs", '5', &pigs_mgr},
                         pname = "<idle>";          {NULL, NULL, 0, NULL}
                 } else {  };
                         uname = user_from_uid(kp->p_uid, 0);  
                         pname = kp->p_comm;  
                 }  #ifdef FSCALE
                 wmove(wnd, y, 0);  # define FIXED_LOADAVG FSCALE
                 wclrtoeol(wnd);  # define FIXED_PCTCPU FSCALE
                 mvwaddstr(wnd, y, 0, uname);  #endif
                 snprintf(pidname, sizeof pidname, "%10.10s", pname);  
                 mvwaddstr(wnd, y, 9, pidname);  #ifdef FIXED_PCTCPU
                 wmove(wnd, y, 20);    typedef long pctcpu;
                 for (j = pt[k].pt_pctcpu*factor + 0.5; j > 0; j--)  # define pctdouble(p) ((double)(p) / FIXED_PCTCPU)
                         waddch(wnd, 'X');  #else
         }  typedef double pctcpu;
         wmove(wnd, y, 0); wclrtobot(wnd);  # define pctdouble(p) (p)
   #endif
   
   int
   select_pg(void)
   {
           num_disp = pigs_cnt;
           return (0);
 }  }
   
 struct loadavg sysload;  
   
 int  int
 initpigs(void)  getprocs(void)
 {  {
         static int sysload_mib[] = {CTL_VM, VM_LOADAVG};  
         static int cp_time_mib[] = { CTL_KERN, KERN_CPTIME };  
         static int ccpu_mib[] = { CTL_KERN, KERN_CCPU };  
         size_t size;          size_t size;
         fixpt_t ccpu;          int mib[6] = {CTL_KERN, KERN_PROC2, KERN_PROC_KTHREAD, 0, sizeof(struct kinfo_proc2), 0};
   
           int st;
   
         size = sizeof(stime);          free(procbase);
         (void) sysctl(cp_time_mib, 2, &stime, &size, NULL, 0);          procbase = NULL;
   
         size = sizeof(sysload);          st = sysctl(mib, 6, NULL, &size, NULL, 0);
         (void) sysctl(sysload_mib, 2, &sysload, &size, NULL, 0);          if (st == -1)
                   return (1);
   
         size = sizeof(ccpu);          size = 5 * size / 4;            /* extra slop */
         (void) sysctl(ccpu_mib, 2, &ccpu, &size, NULL, 0);          if ((procbase = malloc(size + 1)) == NULL)
                   return (1);
   
         lccpu = log((double) ccpu / sysload.fscale);          mib[5] = (int)(size / sizeof(struct kinfo_proc2));
           st = sysctl(mib, 6, procbase, &size, NULL, 0);
           if (st == -1)
                   return (1);
   
         return(1);          nproc = (int)(size / sizeof(struct kinfo_proc2));
           return (0);
 }  }
   
 void  
 fetchpigs(void)  int
   read_pg(void)
 {  {
         static int cp_time_mib[] = { CTL_KERN, KERN_CPTIME };          static int cp_time_mib[] = { CTL_KERN, KERN_CPTIME };
         static int lastnproc = 0;  
         struct kinfo_proc2 *kpp;  
         long ctime[CPUSTATES];          long ctime[CPUSTATES];
         double t;          double t;
         int i;          int i, k;
         size_t size;          size_t size;
         float *pctp;  
   
         kpp = kvm_getproc2(kd, KERN_PROC_KTHREAD, 0, sizeof(*kpp), &nproc);          num_disp = pigs_cnt = 0;
         if (kpp == NULL) {  
                 error("%s", kvm_geterr(kd));          if (getprocs()) {
                 if (pt)                  error("Failed to read process info!");
                         free(pt);                  return 1;
                 return;  
         }          }
         if (nproc > lastnproc) {  
                 free(pt);          if (nproc > onproc) {
                 if ((pt = calloc(nproc + 1, sizeof(struct p_times))) == NULL) {                  int *p;
                         error("Out of memory");                  p = realloc(pb_indices, (nproc + 1) * sizeof(int));
                         die();                  if (p == NULL) {
                           error("Out of Memory!");
                           return 1;
                 }                  }
                   pb_indices = p;
                   onproc = nproc;
         }          }
         lastnproc = nproc;  
           memset(&procbase[nproc], 0, sizeof(*procbase));
   
           for (i = 0; i <= nproc; i++)
                   pb_indices[i] = i;
   
         /*          /*
          * calculate %cpu for each proc  
          */  
         for (i = 0; i < nproc; i++) {  
                 pt[i].pt_kp = &kpp[i];  
                 pctp = &pt[i].pt_pctcpu;  
                 if (kpp->p_swtime == 0)  
                         *pctp = 0;  
                 else  
                         *pctp = ((double) kpp->p_pctcpu / sysload.fscale) /  
                             (1.0 - exp(kpp->p_swtime * lccpu));  
         }  
         /*  
          * and for the imaginary "idle" process           * and for the imaginary "idle" process
          */           */
         size = sizeof(ctime);          size = sizeof(ctime);
         (void) sysctl(cp_time_mib, 2, &ctime, &size, NULL, 0);          sysctl(cp_time_mib, 2, &ctime, &size, NULL, 0);
   
         t = 0;          t = 0;
         for (i = 0; i < CPUSTATES; i++)          for (i = 0; i < CPUSTATES; i++)
                 t += ctime[i] - stime[i];                  t += ctime[i] - stime[i];
         if (t == 0.0)          if (t == 0.0)
                 t = 1.0;                  t = 1.0;
         pt[nproc].pt_kp = NULL;  
         pt[nproc].pt_pctcpu = (ctime[CP_IDLE] - stime[CP_IDLE]) / t;          procbase[nproc].p_pctcpu = (ctime[CP_IDLE] - stime[CP_IDLE]) / t / pctdouble(1);
         for (i = 0; i < CPUSTATES; i++)          for (i = 0; i < CPUSTATES; i++)
                 stime[i] = ctime[i];                  stime[i] = ctime[i];
   
           qsort(pb_indices, nproc + 1, sizeof (int), compar);
   
           pigs_cnt = 0;
           for (k = 0; k < nproc + 1; k++) {
                   int i = pb_indices[k];
                   if (pctdouble(procbase[i].p_pctcpu) < 0.01)
                           break;
                   pigs_cnt++;
           }
   
           num_disp = pigs_cnt;
           return 0;
 }  }
   
   
 void  void
 labelpigs(void)  print_pg(void)
 {  {
         wmove(wnd, 0, 0);          int n, count = 0;
         wclrtoeol(wnd);  
         mvwaddstr(wnd, 0, 20,          for (n = dispstart; n < num_disp; n++) {
             "/0   /10  /20  /30  /40  /50  /60  /70  /80  /90  /100");                  showpigs(pb_indices[n]);
                   count++;
                   if (maxprint > 0 && count >= maxprint)
                           break;
           }
 }  }
   
 int  int
   initpigs(void)
   {
           static int sysload_mib[] = {CTL_VM, VM_LOADAVG};
           static int cp_time_mib[] = { CTL_KERN, KERN_CPTIME };
           static int ccpu_mib[] = { CTL_KERN, KERN_CCPU };
           field_view *v;
           size_t size;
           fixpt_t ccpu;
   
           size = sizeof(stime);
           sysctl(cp_time_mib, 2, &stime, &size, NULL, 0);
   
           size = sizeof(sysload);
           sysctl(sysload_mib, 2, &sysload, &size, NULL, 0);
   
           size = sizeof(ccpu);
           sysctl(ccpu_mib, 2, &ccpu, &size, NULL, 0);
   
           lccpu = log((double) ccpu / sysload.fscale);
   
           for (v = views_pg; v->name != NULL; v++)
                   add_view(v);
   
           return(1);
   }
   
   void
   showpigs(int k)
   {
           struct kinfo_proc2 *kp;
           double value;
           char *uname, *pname;
   
           if (procbase == NULL)
                   return;
   
           value = pctdouble(procbase[k].p_pctcpu) * 100;
   
           kp = &procbase[k];
           if (kp->p_comm[0] == '\0') {
                   uname = "";
                   pname = "<idle>";
           } else {
                   uname = user_from_uid(kp->p_uid, 0);
                   pname = kp->p_comm;
                   print_fld_uint(FLD_PG_PID, kp->p_pid);
           }
   
           tb_start();
           tbprintf("%.2f", value);
           print_fld_tb(FLD_PG_VALUE);
   
           print_fld_str(FLD_PG_NAME, pname);
           print_fld_str(FLD_PG_USER, uname);
           print_fld_bar(FLD_PG_BAR, value);
   
           end_line();
   }
   
   
   int
 compar(const void *a, const void *b)  compar(const void *a, const void *b)
 {  {
         return (((struct p_times *)a)->pt_pctcpu >          int i1 = *((int *)a);
             ((struct p_times *)b)->pt_pctcpu) ? -1 : 1;          int i2 = *((int *)b);
   
           return procbase[i1].p_pctcpu >
                   procbase[i2].p_pctcpu ? -1 : 1;
 }  }
   

Legend:
Removed from v.1.21  
changed lines
  Added in v.1.22