static void devstats(void) { int dn; long double transfers_per_second; long double busy_seconds; diff_cp_time.cp_user = cp_time.cp_user - old_cp_time.cp_user; diff_cp_time.cp_nice = cp_time.cp_nice - old_cp_time.cp_nice; diff_cp_time.cp_sys = cp_time.cp_sys - old_cp_time.cp_sys; diff_cp_time.cp_intr = cp_time.cp_intr - old_cp_time.cp_intr; diff_cp_time.cp_idle = cp_time.cp_idle - old_cp_time.cp_idle; old_cp_time = cp_time; busy_seconds = compute_etime(cur.busy_time, last.busy_time); for (dn = 0; dn < num_devices; dn++) { int di; if ((dev_select[dn].selected == 0) || (dev_select[dn].selected > maxshowdevs)) continue; di = dev_select[dn].position; if (compute_stats(&cur.dinfo->devices[di], &last.dinfo->devices[di], busy_seconds, NULL, NULL, NULL, NULL, &transfers_per_second, NULL, NULL, NULL) != 0) errx(1, "%s", devstat_errbuf); printf("%3.0Lf ", transfers_per_second); } }
static int devstats(int row, int _col, int dn) { long double transfers_per_second; long double kb_per_transfer, mb_per_second; long double busy_seconds; int di; di = dev_select[dn].position; busy_seconds = compute_etime(cur.busy_time, last.busy_time); if (compute_stats(&cur.dinfo->devices[di], &last.dinfo->devices[di], busy_seconds, NULL, NULL, NULL, &kb_per_transfer, &transfers_per_second, &mb_per_second, NULL, NULL) != 0) errx(1, "%s", devstat_errbuf); if (numbers) { mvwprintw(wnd, row, _col, " %5.2Lf %3.0Lf %5.2Lf ", kb_per_transfer, transfers_per_second, mb_per_second); return(row); } wmove(wnd, row++, _col); histogram(mb_per_second, 50, .5); wmove(wnd, row++, _col); histogram(transfers_per_second, 50, .5); if (kbpt) { wmove(wnd, row++, _col); histogram(kb_per_transfer, 50, .5); } return(row); }
int main(int argc, char **argv) { int c; int hflag = 0, cflag = 0, wflag = 0, nflag = 0; int count = 0, waittime = 0; int headercount; int num_devices_specified; int havelast = 0; maxshowdevs = 3; while ((c = getopt(argc, argv, "c:CdIKM:n:oTw:?")) != -1) { switch(c) { case 'c': cflag++; count = atoi(optarg); if (count < 1) errx(1, "count %d is < 1", count); break; case 'C': Cflag++; break; case 'd': dflag++; break; case 'I': Iflag++; break; case 'K': Kflag++; break; case 'n': nflag++; maxshowdevs = atoi(optarg); if (maxshowdevs < 0) errx(1, "number of devices %d is < 0", maxshowdevs); break; case 'o': oflag++; break; case 'T': Tflag++; break; case 'w': wflag++; waittime = atoi(optarg); if (waittime < 1) errx(1, "wait time is < 1"); break; default: usage(); exit(1); break; } } argc -= optind; argv += optind; /* * Get the Mach private port. */ host_priv_port = mach_host_self(); /* * Get the I/O Kit communication handle. */ IOMasterPort(bootstrap_port, &masterPort); /* * Make sure Tflag and/or Cflag are set if dflag == 0. If dflag is * greater than 0, they may be 0 or non-zero. */ if (dflag == 0) { Cflag = 1; Tflag = 1; } /* * Figure out how many devices we should display if not given * an explicit value. */ if (nflag == 0) { if (oflag > 0) { if ((dflag > 0) && (Cflag == 0) && (Tflag == 0)) maxshowdevs = 5; else if ((dflag > 0) && (Tflag > 0) && (Cflag == 0)) maxshowdevs = 5; else maxshowdevs = 4; } else { if ((dflag > 0) && (Cflag == 0)) maxshowdevs = 4; else maxshowdevs = 3; } } /* * If the user specified any devices on the command line, record * them for monitoring. */ for (num_devices_specified = 0; *argv; ++argv) { if (isdigit(**argv)) break; if (record_one_device(*argv)) errx(1, "can't record '%s' for monitoring"); num_devices_specified++; } if (nflag == 0 && maxshowdevs < num_devices_specified) maxshowdevs = num_devices_specified; /* if no devices were specified, pick them ourselves */ if ((num_devices_specified == 0) && record_all_devices()) err(1, "can't find any devices to display"); /* * Look for the traditional wait time and count arguments. */ if (*argv) { waittime = atoi(*argv); /* Let the user know he goofed, but keep going anyway */ if (wflag != 0) warnx("discarding previous wait interval, using" " %d instead", waittime); wflag++; if (*++argv) { count = atoi(*argv); if (cflag != 0) warnx("discarding previous count, using %d" " instead", count); cflag++; } else count = -1; } /* * If the user specified a count, but not an interval, we default * to an interval of 1 second. */ if ((wflag == 0) && (cflag > 0)) waittime = 1; /* * If the user specified a wait time, but not a count, we want to * go on ad infinitum. This can be redundant if the user uses the * traditional method of specifying the wait, since in that case we * already set count = -1 above. Oh well. */ if ((wflag > 0) && (cflag == 0)) count = -1; cur.tk_nout = 0; cur.tk_nin = 0; /* * Set the busy time to the system boot time, so the stats are * calculated since system boot. */ if (readvar("kern.boottime", &cur_time, sizeof(cur_time)) != 0) exit(1); /* * If the user stops the program (control-Z) and then resumes it, * print out the header again. */ (void)signal(SIGCONT, phdr); for (headercount = 1;;) { long tmp; long double etime; if (Tflag > 0) { if ((readvar("kern.tty_nin", &cur.tk_nin, sizeof(cur.tk_nin)) != 0) || (readvar("kern.tty_nout", &cur.tk_nout, sizeof(cur.tk_nout))!= 0)) { Tflag = 0; warnx("disabling TTY statistics"); } } if (phdr_flag) { phdr_flag = 0; do_phdr(); } if (!--headercount) { do_phdr(); headercount = 20; } last_time = cur_time; gettimeofday(&cur_time, NULL); if (Tflag > 0) { tmp = cur.tk_nin; cur.tk_nin -= last.tk_nin; last.tk_nin = tmp; tmp = cur.tk_nout; cur.tk_nout -= last.tk_nout; last.tk_nout = tmp; } etime = compute_etime(cur_time, last_time); if (etime == 0.0) etime = 1.0; if (Tflag > 0) printf("%4.0Lf%5.0Lf", cur.tk_nin / etime, cur.tk_nout / etime); devstats(hflag, etime, havelast); if (Cflag > 0) cpustats(); printf("\n"); fflush(stdout); if (count >= 0 && --count <= 0) break; sleep(waittime); havelast = 1; } exit(0); }
static void dinfo(int dn, int lc, struct statinfo *now, struct statinfo *then) { long double kb_per_transfer; long double transfers_per_secondr; long double transfers_per_secondw; long double mb_per_secondr; long double mb_per_secondw; long double elapsed_time, device_busy; int di; di = dev_select[dn].position; elapsed_time = compute_etime(now->busy_time, then ? then->busy_time : now->dinfo->devices[di].dev_creation_time); device_busy = compute_etime(now->dinfo->devices[di].busy_time, then ? then->dinfo->devices[di].busy_time : now->dinfo->devices[di].dev_creation_time); if (compute_stats( &now->dinfo->devices[di], (then ? &then->dinfo->devices[di] : NULL), elapsed_time, NULL, NULL, NULL, &kb_per_transfer, NULL, NULL, NULL, NULL) != 0) errx(1, "%s", devstat_errbuf); if (compute_stats_read( &now->dinfo->devices[di], (then ? &then->dinfo->devices[di] : NULL), elapsed_time, NULL, NULL, NULL, NULL, &transfers_per_secondr, &mb_per_secondr, NULL, NULL) != 0) errx(1, "%s", devstat_errbuf); if (compute_stats_write( &now->dinfo->devices[di], (then ? &then->dinfo->devices[di] : NULL), elapsed_time, NULL, NULL, NULL, NULL, &transfers_per_secondw, &mb_per_secondw, NULL, NULL) != 0) errx(1, "%s", devstat_errbuf); if ((device_busy == 0) && (transfers_per_secondr > 5 || transfers_per_secondw > 5)) { /* the device has been 100% busy, fake it because * as long as the device is 100% busy the busy_time * field in the devstat struct is not updated */ device_busy = elapsed_time; } if (device_busy > elapsed_time) { /* this normally happens after one or more periods * where the device has been 100% busy, correct it */ device_busy = elapsed_time; } lc = DISKCOL + lc * 6; putlongdoublez(kb_per_transfer, DISKROW + 1, lc, 5, 2, 0); putlongdoublez(transfers_per_secondr, DISKROW + 2, lc, 5, 0, 0); putlongdoublez(mb_per_secondr, DISKROW + 3, lc, 5, 2, 0); putlongdoublez(transfers_per_secondw, DISKROW + 4, lc, 5, 0, 0); putlongdoublez(mb_per_secondw, DISKROW + 5, lc, 5, 2, 0); putlongdouble(device_busy * 100 / elapsed_time, DISKROW + 6, lc, 5, 0, 0); }