int machine_init(struct statics *statics) { size_t size = sizeof(ncpu); int mib[2], pagesize, cpu; mib[0] = CTL_HW; mib[1] = HW_NCPU; if (sysctl(mib, 2, &ncpu, &size, NULL, 0) == -1) return (-1); cpu_states = calloc(ncpu, CPUSTATES * sizeof(int64_t)); if (cpu_states == NULL) err(1, NULL); cp_time = calloc(ncpu, sizeof(int64_t *)); cp_old = calloc(ncpu, sizeof(int64_t *)); cp_diff = calloc(ncpu, sizeof(int64_t *)); if (cp_time == NULL || cp_old == NULL || cp_diff == NULL) err(1, NULL); for (cpu = 0; cpu < ncpu; cpu++) { cp_time[cpu] = calloc(CPUSTATES, sizeof(int64_t)); cp_old[cpu] = calloc(CPUSTATES, sizeof(int64_t)); cp_diff[cpu] = calloc(CPUSTATES, sizeof(int64_t)); if (cp_time[cpu] == NULL || cp_old[cpu] == NULL || cp_diff[cpu] == NULL) err(1, NULL); } stathz = getstathz(); if (stathz == -1) return (-1); pbase = NULL; pref = NULL; onproc = -1; nproc = 0; /* * get the page size with "getpagesize" and calculate pageshift from * it */ pagesize = getpagesize(); pageshift = 0; while (pagesize > 1) { pageshift++; pagesize >>= 1; } /* we only need the amount of log(2)1024 for our conversion */ pageshift -= LOG1024; /* fill in the statics information */ statics->procstate_names = procstatenames; statics->cpustate_names = cpustatenames; statics->memory_names = memorynames; statics->order_names = ordernames; return (0); }
int main(int argc, char **argv) { int aflag, ch, lflag, status; int exitonsig; pid_t pid; struct rlimit rl; struct rusage ru; struct timeval after; char *ofn = NULL; FILE *out = stderr; (void) setlocale(LC_NUMERIC, ""); decimal_point = localeconv()->decimal_point[0]; aflag = hflag = lflag = pflag = 0; while ((ch = getopt(argc, argv, "ahlo:p")) != -1) switch((char)ch) { case 'a': aflag = 1; break; case 'h': hflag = 1; break; case 'l': lflag = 1; break; case 'o': ofn = optarg; break; case 'p': pflag = 1; break; case '?': default: usage(); } if (!(argc -= optind)) exit(0); argv += optind; if (ofn) { if ((out = fopen(ofn, aflag ? "ae" : "we")) == NULL) err(1, "%s", ofn); setvbuf(out, (char *)NULL, _IONBF, (size_t)0); } (void)gettimeofday(&before_tv, NULL); switch(pid = fork()) { case -1: /* error */ err(1, "time"); /* NOTREACHED */ case 0: /* child */ execvp(*argv, argv); err(errno == ENOENT ? 127 : 126, "%s", *argv); /* NOTREACHED */ } /* parent */ (void)signal(SIGINT, SIG_IGN); (void)signal(SIGQUIT, SIG_IGN); siginfo_recvd = 0; (void)signal(SIGINFO, siginfo); (void)siginterrupt(SIGINFO, 1); while (wait4(pid, &status, 0, &ru) != pid) { if (siginfo_recvd) { siginfo_recvd = 0; (void)gettimeofday(&after, NULL); getrusage(RUSAGE_CHILDREN, &ru); showtime(stdout, &before_tv, &after, &ru); } } (void)gettimeofday(&after, NULL); if ( ! WIFEXITED(status)) warnx("command terminated abnormally"); exitonsig = WIFSIGNALED(status) ? WTERMSIG(status) : 0; showtime(out, &before_tv, &after, &ru); if (lflag) { int hz = getstathz(); u_long ticks; ticks = hz * (ru.ru_utime.tv_sec + ru.ru_stime.tv_sec) + hz * (ru.ru_utime.tv_usec + ru.ru_stime.tv_usec) / 1000000; /* * If our round-off on the tick calculation still puts us at 0, * then always assume at least one tick. */ if (ticks == 0) ticks = 1; fprintf(out, "%10ld %s\n", ru.ru_maxrss, "maximum resident set size"); fprintf(out, "%10ld %s\n", ru.ru_ixrss / ticks, "average shared memory size"); fprintf(out, "%10ld %s\n", ru.ru_idrss / ticks, "average unshared data size"); fprintf(out, "%10ld %s\n", ru.ru_isrss / ticks, "average unshared stack size"); fprintf(out, "%10ld %s\n", ru.ru_minflt, "page reclaims"); fprintf(out, "%10ld %s\n", ru.ru_majflt, "page faults"); fprintf(out, "%10ld %s\n", ru.ru_nswap, "swaps"); fprintf(out, "%10ld %s\n", ru.ru_inblock, "block input operations"); fprintf(out, "%10ld %s\n", ru.ru_oublock, "block output operations"); fprintf(out, "%10ld %s\n", ru.ru_msgsnd, "messages sent"); fprintf(out, "%10ld %s\n", ru.ru_msgrcv, "messages received"); fprintf(out, "%10ld %s\n", ru.ru_nsignals, "signals received"); fprintf(out, "%10ld %s\n", ru.ru_nvcsw, "voluntary context switches"); fprintf(out, "%10ld %s\n", ru.ru_nivcsw, "involuntary context switches"); } /* * If the child has exited on a signal, exit on the same * signal, too, in order to reproduce the child's exit status. * However, avoid actually dumping core from the current process. */ if (exitonsig) { if (signal(exitonsig, SIG_DFL) == SIG_ERR) warn("signal"); else { rl.rlim_max = rl.rlim_cur = 0; if (setrlimit(RLIMIT_CORE, &rl) == -1) warn("setrlimit"); kill(getpid(), exitonsig); } } exit (WIFEXITED(status) ? WEXITSTATUS(status) : EXIT_FAILURE); }