home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume26 / cputt-2.3 / part01 / cputt.c next >
Encoding:
C/C++ Source or Header  |  1993-04-05  |  7.1 KB  |  205 lines

  1. #include     <sys/types.h>
  2. #include     <sys/stat.h>
  3. #include     <sys/timeb.h>
  4. #include     <sys/user.h>
  5. #include     <sys/resource.h>
  6. #include     <kvm.h>
  7. #include     <fcntl.h>
  8.  
  9. #include     "cputt.h"
  10.  
  11. /*
  12.    MAIN - Computes CPU utilization for all processes from two snapshots
  13.    of the kernel process table taken over a user supplied interval
  14.    (arg1).  Sorts and prints the top ten CPU using processes for that
  15.    interval.  Execution continues for a user supplied number of
  16.    iterations (arg2).
  17.  
  18.    The kernel process table snapshots are stored in two arrays,
  19.    'oldproc' and 'newproc'.  Resource utilization information is stored
  20.    in two arrays, 'oldusage' and 'newusage'.  The command strings for
  21.    each process are stored in a 2D array, 'cmds'.  CPU utilization for
  22.    each interval is stored in the 'sdata' array along with pointers to
  23.    the appropriate 'proc' and 'cmds' entries.
  24. */
  25.  
  26. main (argc, argv)
  27.  
  28. int argc; char *argv[];
  29.  
  30. {
  31.      struct proc              *oldproc,*newproc,*tproc;
  32.      struct rusage            *oldusage,*newusage,*tusage;
  33.      struct sortdata          *sdata;
  34.      struct hashtab           *hp;
  35.  
  36.      register long             time1,utime1,time2,utime2;
  37.      register long             s_delta,p_delta;
  38.      register int              i,last,sindex;
  39.  
  40.      struct timeb              ot,nt;
  41.      struct hashtab           *hashuid();
  42.      int                       reps,interval,iterations,cmp();
  43.      double                    percentmem();
  44.      char                     **cmds;
  45.  
  46.      /* check arguements */
  47.  
  48.      switch(argc) 
  49.      {
  50.          case 3:
  51.             interval = atoi(argv[1]);
  52.             iterations = atoi(argv[2]);
  53.             break;
  54.          case 1:
  55.             interval=5;
  56.             iterations=10;
  57.             break;
  58.          default:
  59.             printf("Usage: cputt <interval> <iterations>\n");
  60.             exit(1);
  61.      }
  62.  
  63.      setpriority(PRIO_PROCESS,0,-20);
  64.  
  65.      /* open kernel memory  */
  66.  
  67.      if(!(Flkvm = kvm_open(NULL, NULL, NULL, O_RDONLY, "cputt")))
  68.         exit(1);
  69.  
  70.      /* get critical system parameters, build uid hash table */
  71.  
  72.      printf("Initializing..\n");
  73.      init();
  74.      initusers();
  75.  
  76.      /* truncate unused portion of the process table */
  77.  
  78.      Info.i_sproc = Info.i_nproc * sizeof(struct proc);
  79.      if (GROWTH_BUF)
  80.      {
  81.          oldproc = (struct proc *) getcore(Info.i_nproc*sizeof(struct proc));
  82.          readstatus(oldproc);
  83.          for (i=0; i<Info.i_nproc; i++)
  84.               if (oldproc[i].p_stat && getupage(&oldproc[i]))
  85.               {
  86.                   last=i;
  87.               }
  88.          free(oldproc);
  89.          if (last+GROWTH_BUF < Info.i_nproc)
  90.          {
  91.              Info.i_nproc = last+GROWTH_BUF;
  92.              Info.i_sproc = Info.i_nproc * sizeof(struct proc);
  93.          }
  94.      }
  95.  
  96.      /* allocate core for internal data structures */
  97.      cmds = (char **) getcore(Info.i_nproc*sizeof(char *));
  98.      for (i=0;i<Info.i_nproc;i++)
  99.           cmds[i] = (char *) getcore(COMMAND_SIZE);
  100.  
  101.      sdata     = (struct sortdata *)
  102.                   getcore(MAXACTIVE*sizeof(struct sortdata));
  103.      oldusage  = (struct rusage *)
  104.                   getcore(Info.i_nproc*sizeof(struct rusage));
  105.      newusage  = (struct rusage *)
  106.                   getcore(Info.i_nproc*sizeof(struct rusage));
  107.      oldproc   = (struct proc *) getcore(Info.i_nproc*sizeof(struct proc));
  108.      newproc   = (struct proc *) getcore(Info.i_nproc*sizeof(struct proc));
  109.  
  110.      /* get initial time, process table, upage, and command strings */
  111.  
  112.      ftime(&ot);
  113.      readstatus(oldproc);
  114.      for (i=0;i<Info.i_nproc;i++) 
  115.           if (oldproc[i].p_stat && getupage(&oldproc[i]))
  116.              {
  117.               oldusage[i] = User.u_us.u_ru;
  118.               getcmd(&oldproc[i],cmds[i]);
  119.              }
  120.  
  121.      /* compare process tables every argv[1] seconds for argv[2] iterations */
  122.  
  123.      for (reps = 0; reps < iterations; reps++)
  124.      {    
  125.           sleep(interval);         /* sleep for agrv[1] seconds */
  126.           ftime(&nt);                  /* get new time          */
  127.           readstatus(newproc);         /* get new process table */
  128.  
  129.           /* find matching pids, compute cpu usage, store results in sdata */
  130.  
  131.           for (sindex=i=0; i<Info.i_nproc; i++)
  132.                if (newproc[i].p_stat && getupage(&newproc[i]))
  133.                {
  134.                    last=i; /* record latest proc table location */
  135.                    newusage[i] = User.u_us.u_ru;
  136.                    if (oldproc[i].p_pid==newproc[i].p_pid)
  137.                    {
  138.                        time1 =   oldusage[i].ru_utime.tv_sec +
  139.                                  oldusage[i].ru_stime.tv_sec;
  140.                        utime1 =  oldusage[i].ru_utime.tv_usec +
  141.                                  oldusage[i].ru_stime.tv_usec;
  142.                        time2 =   newusage[i].ru_utime.tv_sec +
  143.                                  newusage[i].ru_stime.tv_sec;
  144.                        utime2 =  newusage[i].ru_utime.tv_usec +
  145.                                  newusage[i].ru_stime.tv_usec;
  146.                        p_delta = (time2*1000000+utime2) -
  147.                                  (time1*1000000+utime1);
  148.                        if (p_delta)
  149.                        {
  150.                            s_delta = (nt.time*1000+nt.millitm) -
  151.                                      (ot.time*1000+ot.millitm);
  152.                            sdata[sindex].pctcpu = (p_delta*10)/s_delta;
  153.                            sdata[sindex].proc   = &oldproc[i];
  154.                            sdata[sindex].pr_cmd = i;
  155.  
  156.                            if (sindex < MAXACTIVE - 1)
  157.                                sindex++;
  158.                            else
  159.                                printf("\ncputt: MAXACTIVE limit exceeded.\n");
  160.                        }
  161.                    }
  162.                    else
  163.                    {
  164.                        getcmd(&newproc[i],cmds[i]);
  165.                    }
  166.                } 
  167.  
  168.           /* check process table variance at each iteration */
  169.  
  170.           if (GROWTH_BUF &&
  171.              (i-last < GROWTH_BUF-MAX_GROW || i-last > GROWTH_BUF+MAX_SHRINK))
  172.           {
  173.               printf("\nProcess table variance greater than %d, restarting..\n",
  174.                       MAX_GROW + MAX_SHRINK);
  175.               execvp(argv[0],argv);
  176.           }
  177.  
  178.           /* sort and print results */
  179.  
  180.           qsort(sdata,sindex,sizeof(struct sortdata),cmp); 
  181.           printf("\n  PID USER        CPU    MEM  COMMANDS - %d %d\n"
  182.                  ,sindex,last);
  183.           for (i=--sindex; sindex > -1 && sindex > i-MAXOUT; --sindex)
  184.           {
  185.                printf("%5d ",sdata[sindex].proc->p_pid);
  186.                if (hp = hashuid(sdata[sindex].proc->p_suid))
  187.                    printf("%-8.8s ",hp->h_uname);
  188.                else
  189.                    printf("user%-4.4d ",sdata[sindex].proc->p_uid);
  190.                printf("%6.2f ",(float)sdata[sindex].pctcpu/100);
  191.                printf("%6.2f ",percentmem(sdata[sindex].proc));
  192.                printf(" %s\n",cmds[sdata[sindex].pr_cmd]);
  193.           }
  194.        
  195.           /* swap old and new pointers */
  196.  
  197.           tusage   = oldusage;   tproc   = oldproc;
  198.           oldusage = newusage;   oldproc = newproc;
  199.           newusage = tusage;     newproc = tproc;
  200.           ot = nt;
  201.  
  202.      }    /* for all iterations.. */
  203.  
  204. }    /* main */
  205.