/************************************************************************* * ruse.c -- get as much info as possible out of the system about a process, * and print it out. */ #include #include #include #include #include #include #include #include #ifdef __IA64 static inline long msa(int ntimers, int which, clk_t *timers) { return syscall(__NR_sys_msa, ntimers, which, timers); } #else static inline long msa(int ntimers, int which, clk_t *timers) { return syscall(__NR_msa, ntimers, which, timers); } #endif struct { int index; char *name; } names[NR_MICRO_STATES] = { #define X(a) {a, #a} X(UNKNOWN), X(ONCPU_USER), X(ONCPU_SYS), X(INTERRUPTIBLE_SLEEP), X(UNINTERRUPTIBLE_SLEEP), X(ONACTIVEQUEUE), X(ONEXPIREDQUEUE), X(ZOMBIE), X(STOPPED), X(INTERRUPTED), }; int main(int ac, char **av) { clk_t posttimers[NR_MICRO_STATES]; struct rusage usage; pid_t kidpid; int i; int status; struct timeval before; struct timeval after; gettimeofday(&before, NULL); switch(kidpid = fork()) { case -1: perror("fork"); return 1; case 0: { /* child */ for (i = 3; i < 512; i++) close(i); execvp(av[1], &av[1]); perror("exec"); return 1; } default: break; } signal(SIGINT, SIG_IGN); wait4(kidpid, &status, 0, &usage); gettimeofday(&after, NULL); after.tv_sec -= before.tv_sec; while (after.tv_usec < before.tv_usec) { after.tv_sec--; after.tv_usec += 1000000; } after.tv_usec -= before.tv_usec; msa(NR_MICRO_STATES, MSA_CHILDREN, posttimers); printf("%2d.%03d User %2d.%03d Sys %2d.%03d Real\n", usage.ru_utime.tv_sec, usage.ru_utime.tv_usec / 1000, usage.ru_stime.tv_sec, usage.ru_stime.tv_usec / 1000, after.tv_sec, after.tv_usec / 1000); for (i = 0; i < NR_MICRO_STATES; i++) { assert(names[i].index == i); printf("%s %g\n", names[i].name, (double)posttimers[i]/1.0e9); } return status; }