home *** CD-ROM | disk | FTP | other *** search
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/timeb.h>
- #include <sys/user.h>
- #include <sys/resource.h>
- #include <kvm.h>
- #include <fcntl.h>
-
- #include "cputt.h"
-
- /*
- MAIN - Computes CPU utilization for all processes from two snapshots
- of the kernel process table taken over a user supplied interval
- (arg1). Sorts and prints the top ten CPU using processes for that
- interval. Execution continues for a user supplied number of
- iterations (arg2).
-
- The kernel process table snapshots are stored in two arrays,
- 'oldproc' and 'newproc'. Resource utilization information is stored
- in two arrays, 'oldusage' and 'newusage'. The command strings for
- each process are stored in a 2D array, 'cmds'. CPU utilization for
- each interval is stored in the 'sdata' array along with pointers to
- the appropriate 'proc' and 'cmds' entries.
- */
-
- main (argc, argv)
-
- int argc; char *argv[];
-
- {
- struct proc *oldproc,*newproc,*tproc;
- struct rusage *oldusage,*newusage,*tusage;
- struct sortdata *sdata;
- struct hashtab *hp;
-
- register long time1,utime1,time2,utime2;
- register long s_delta,p_delta;
- register int i,last,sindex;
-
- struct timeb ot,nt;
- struct hashtab *hashuid();
- int reps,interval,iterations,cmp();
- double percentmem();
- char **cmds;
-
- /* check arguements */
-
- switch(argc)
- {
- case 3:
- interval = atoi(argv[1]);
- iterations = atoi(argv[2]);
- break;
- case 1:
- interval=5;
- iterations=10;
- break;
- default:
- printf("Usage: cputt <interval> <iterations>\n");
- exit(1);
- }
-
- setpriority(PRIO_PROCESS,0,-20);
-
- /* open kernel memory */
-
- if(!(Flkvm = kvm_open(NULL, NULL, NULL, O_RDONLY, "cputt")))
- exit(1);
-
- /* get critical system parameters, build uid hash table */
-
- printf("Initializing..\n");
- init();
- initusers();
-
- /* truncate unused portion of the process table */
-
- Info.i_sproc = Info.i_nproc * sizeof(struct proc);
- if (GROWTH_BUF)
- {
- oldproc = (struct proc *) getcore(Info.i_nproc*sizeof(struct proc));
- readstatus(oldproc);
- for (i=0; i<Info.i_nproc; i++)
- if (oldproc[i].p_stat && getupage(&oldproc[i]))
- {
- last=i;
- }
- free(oldproc);
- if (last+GROWTH_BUF < Info.i_nproc)
- {
- Info.i_nproc = last+GROWTH_BUF;
- Info.i_sproc = Info.i_nproc * sizeof(struct proc);
- }
- }
-
- /* allocate core for internal data structures */
- cmds = (char **) getcore(Info.i_nproc*sizeof(char *));
- for (i=0;i<Info.i_nproc;i++)
- cmds[i] = (char *) getcore(COMMAND_SIZE);
-
- sdata = (struct sortdata *)
- getcore(MAXACTIVE*sizeof(struct sortdata));
- oldusage = (struct rusage *)
- getcore(Info.i_nproc*sizeof(struct rusage));
- newusage = (struct rusage *)
- getcore(Info.i_nproc*sizeof(struct rusage));
- oldproc = (struct proc *) getcore(Info.i_nproc*sizeof(struct proc));
- newproc = (struct proc *) getcore(Info.i_nproc*sizeof(struct proc));
-
- /* get initial time, process table, upage, and command strings */
-
- ftime(&ot);
- readstatus(oldproc);
- for (i=0;i<Info.i_nproc;i++)
- if (oldproc[i].p_stat && getupage(&oldproc[i]))
- {
- oldusage[i] = User.u_us.u_ru;
- getcmd(&oldproc[i],cmds[i]);
- }
-
- /* compare process tables every argv[1] seconds for argv[2] iterations */
-
- for (reps = 0; reps < iterations; reps++)
- {
- sleep(interval); /* sleep for agrv[1] seconds */
- ftime(&nt); /* get new time */
- readstatus(newproc); /* get new process table */
-
- /* find matching pids, compute cpu usage, store results in sdata */
-
- for (sindex=i=0; i<Info.i_nproc; i++)
- if (newproc[i].p_stat && getupage(&newproc[i]))
- {
- last=i; /* record latest proc table location */
- newusage[i] = User.u_us.u_ru;
- if (oldproc[i].p_pid==newproc[i].p_pid)
- {
- time1 = oldusage[i].ru_utime.tv_sec +
- oldusage[i].ru_stime.tv_sec;
- utime1 = oldusage[i].ru_utime.tv_usec +
- oldusage[i].ru_stime.tv_usec;
- time2 = newusage[i].ru_utime.tv_sec +
- newusage[i].ru_stime.tv_sec;
- utime2 = newusage[i].ru_utime.tv_usec +
- newusage[i].ru_stime.tv_usec;
- p_delta = (time2*1000000+utime2) -
- (time1*1000000+utime1);
- if (p_delta)
- {
- s_delta = (nt.time*1000+nt.millitm) -
- (ot.time*1000+ot.millitm);
- sdata[sindex].pctcpu = (p_delta*10)/s_delta;
- sdata[sindex].proc = &oldproc[i];
- sdata[sindex].pr_cmd = i;
-
- if (sindex < MAXACTIVE - 1)
- sindex++;
- else
- printf("\ncputt: MAXACTIVE limit exceeded.\n");
- }
- }
- else
- {
- getcmd(&newproc[i],cmds[i]);
- }
- }
-
- /* check process table variance at each iteration */
-
- if (GROWTH_BUF &&
- (i-last < GROWTH_BUF-MAX_GROW || i-last > GROWTH_BUF+MAX_SHRINK))
- {
- printf("\nProcess table variance greater than %d, restarting..\n",
- MAX_GROW + MAX_SHRINK);
- execvp(argv[0],argv);
- }
-
- /* sort and print results */
-
- qsort(sdata,sindex,sizeof(struct sortdata),cmp);
- printf("\n PID USER CPU MEM COMMANDS - %d %d\n"
- ,sindex,last);
- for (i=--sindex; sindex > -1 && sindex > i-MAXOUT; --sindex)
- {
- printf("%5d ",sdata[sindex].proc->p_pid);
- if (hp = hashuid(sdata[sindex].proc->p_suid))
- printf("%-8.8s ",hp->h_uname);
- else
- printf("user%-4.4d ",sdata[sindex].proc->p_uid);
- printf("%6.2f ",(float)sdata[sindex].pctcpu/100);
- printf("%6.2f ",percentmem(sdata[sindex].proc));
- printf(" %s\n",cmds[sdata[sindex].pr_cmd]);
- }
-
- /* swap old and new pointers */
-
- tusage = oldusage; tproc = oldproc;
- oldusage = newusage; oldproc = newproc;
- newusage = tusage; newproc = tproc;
- ot = nt;
-
- } /* for all iterations.. */
-
- } /* main */
-