#include #include #include #include #include #include #include #include #include #include extern int optint, opterr; extern char *optarg; #define SAVEFILE ".pidusage" static char *savefile = SAVEFILE; static int savedata = 0; static pid_t savepid = 0; static int printdiff = 0; void look(pid_t); void processargs(int, char **); void print_usage(void); double when(timestruc_t *); int main(int argc, char *argv[]) { processargs(argc, argv); (void) look(savepid); } void processargs(int argc, char *argv[]) { int ch; char *arglist = "sgf:p:"; while ((ch = getopt(argc, argv, arglist)) != -1) { switch (ch) { case 's': savedata = 1; break; case 'g': printdiff = 1; break; case 'f': savefile = optarg; break; case 'p': savepid = atoi(optarg); break; case '?': print_usage(); exit(12); break; } } if (savepid == 0) { fprintf(stderr, "Need to specify a pid to monitor\n"); print_usage(); exit(12); } } void print_usage(void) { fprintf(stderr, "usage: pidusage [args...]\n"); fprintf(stderr, " -s save usage to file\n"); fprintf(stderr, " -g print resource usage since last save\n"); fprintf(stderr, " -f name of file for saving resource usage\n"); fprintf(stderr, " -p process to be measured\n"); } void look(pid_t pid) { char pathname[100]; int fd; prusage_t pup1, pup2, pupd; pstatus_t psp1, psp2, pspd; timestruc_t real, user, sys, cuser, csys; if (printdiff) { if ((fd = open(savefile, O_RDONLY)) < 0) perror(savefile); if (read(fd, &pup1, sizeof(pup1)) != sizeof(pup1)) { fprintf(stderr, "premature end of saved file\n"); exit(12); } if (read(fd, &psp1, sizeof(psp1)) != sizeof(psp1)) { fprintf(stderr, "premature end of saved file\n"); exit(12); } close(fd); } (void) sprintf(pathname, "/proc/%d/usage", (int) pid); if ((fd = open(pathname, O_RDONLY)) < 0) perror(pathname); if (read(fd, &pup2, sizeof(pup2)) != sizeof(pup2)) { fprintf(stderr, "premature end of usage file\n"); exit(12); } close(fd); (void) sprintf(pathname, "/proc/%d/status", (int) pid); if ((fd = open(pathname, O_RDONLY)) < 0) perror(pathname); if (read(fd, &psp2, sizeof(psp2)) != sizeof(psp2)) { fprintf(stderr, "premature end of status file\n"); exit(12); } close(fd); if (savedata) { if ((fd = open(savefile, O_WRONLY|O_CREAT, 0644)) < 0) perror(savefile); if (write(fd, &pup2, sizeof(pup2)) != sizeof(pup2)) { fprintf(stderr, "premature end when saving usage data\n"); exit(12); } if (write(fd, &psp2, sizeof(psp2)) != sizeof(psp2)) { fprintf(stderr, "premature end when saving status data\n"); exit(12); } close(fd); } if (printdiff) { printf("*** Usage Counters ***\n"); printf("Minor Faults: %10lu\n", pup2.pr_minf - pup1.pr_minf); printf("Major Faults: %10lu\n", pup2.pr_majf - pup1.pr_majf); printf("Swaps: %10lu\n", pup2.pr_nswap - pup1.pr_nswap); printf("Input Blocks: %10lu\n", pup2.pr_inblk - pup1.pr_inblk); printf("Output Blocks: %10lu\n", pup2.pr_oublk - pup1.pr_oublk); printf("STREAMS Messages Sent: %10lu\n", pup2.pr_msnd - pup1.pr_msnd); printf("STREAMS Messages Received: %10lu\n", pup2.pr_mrcv - pup1.pr_mrcv); printf("Signals: %10lu\n", pup2.pr_sigs - pup1.pr_sigs); printf("Voluntary Context Switches: %10lu\n", pup2.pr_vctx - pup1.pr_vctx); printf("Involuntary Context Switches: %10lu\n", pup2.pr_ictx - pup1.pr_ictx); printf("System Calls: %10lu\n", pup2.pr_sysc - pup1.pr_sysc); printf("Read/Write Characters: %10lu\n", pup2.pr_ioch - pup1.pr_ioch); printf("\n"); printf("*** State Times ***\n"); printf("Total User Time: %14.3f\n", when(&pup2.pr_utime) - when(&pup1.pr_utime)); printf("Total System Time: %14.3f\n", when(&pup2.pr_stime) - when(&pup1.pr_stime)); printf("Total System Trap Time: %14.3f\n", when(&pup2.pr_ttime) - when(&pup1.pr_ttime)); printf("Text Page Fault Sleep Time: %14.3f\n", when(&pup2.pr_tftime) - when(&pup1.pr_tftime)); printf("Data Page Fault Sleep Time: %14.3f\n", when(&pup2.pr_dftime) - when(&pup1.pr_dftime)); printf("Kernel Page Fault Sleep Time: %14.3f\n", when(&pup2.pr_kftime) - when(&pup1.pr_kftime)); printf("User Lock Wait Sleep Time: %14.3f\n", when(&pup2.pr_ltime) - when(&pup1.pr_ltime)); printf("All Other Sleep Time: %14.3f\n", when(&pup2.pr_slptime) - when(&pup1.pr_slptime)); printf("Time Waiting for a CPU: %14.3f\n", when(&pup2.pr_wtime) - when(&pup1.pr_wtime)); printf("Stopped Time: %14.3f\n", when(&pup2.pr_stoptime) - when(&pup1.pr_stoptime)); printf("Total Child User Time: %14.3f\n", when(&psp2.pr_cutime) - when(&psp1.pr_cutime)); printf("Total Child System Time: %14.3f\n", when(&psp2.pr_cstime) - when(&psp1.pr_cstime)); } } double when(timestruc_t *ts) { return (double) ts->tv_sec + ts->tv_nsec*1e-9; }