X-Git-Url: https://git.saurik.com/apple/shell_cmds.git/blobdiff_plain/57cab491e7f6d6f2e4d1854b8d1ee959c064b1bb..b5fe885ee63a0f46dc66d5ba8af23cad26f23e04:/systime/systime.c diff --git a/systime/systime.c b/systime/systime.c index 746a8bd..37cee8b 100644 --- a/systime/systime.c +++ b/systime/systime.c @@ -29,12 +29,16 @@ #include #include #include +#include +#include static void usage(void); static void do_print(void); -static void do_difftime(bool usepercent, uint64_t olduser, uint64_t oldsystem, uint64_t oldidle); +static void do_difftime(bool usepercent, uint64_t *olduser, uint64_t *oldsystem, uint64_t *oldidle); +static void do_piddifftime(bool userpercent, int pid, uint64_t *old_pid_user, uint64_t *old_pid_system, uint64_t *old_pid_time); static kern_return_t get_processor_time(uint64_t *user, uint64_t *sys, uint64_t *idle); static kern_return_t get_processor_count(int *ncpu); +static mach_timebase_info_data_t timebase_info; int main(int argc, char *argv[]) @@ -43,20 +47,36 @@ main(int argc, char *argv[]) const char *optu = NULL; const char *opts = NULL; const char *opti = NULL; + const char *tpid = NULL; + const char *opt_sleep_time = NULL; + int sleep_time = 1; + int target_pid; + bool systemwide_time = false; int pid; int status; uint64_t olduser, oldsystem, oldidle; + uint64_t old_pid_time; + uint64_t old_pid_user, old_pid_system; kern_return_t kret; bool usepercent = false; + bool recurring = false; - while ((ch = getopt(argc, argv, "Ppu:s:i:")) != -1) { + while ((ch = getopt(argc, argv, "PrT:t:pu:s:i:")) != -1) { switch (ch) { case 'P': usepercent = true; break; + case 'r': + recurring = true; + break; + case 't': + opt_sleep_time = optarg; + break; + case 'T': + tpid = optarg; + break; case 'p': - do_print(); - exit(0); + systemwide_time = true; break; case 'u': optu = optarg; @@ -73,6 +93,63 @@ main(int argc, char *argv[]) } } + mach_timebase_info(&timebase_info); + + if (opt_sleep_time) { + char *endstr; + sleep_time = (int)strtoul(opt_sleep_time, &endstr, 0); + if (opt_sleep_time[0] == '\0' || endstr[0] != '\0') + usage(); + } + + if (systemwide_time) { + bool first_pass = true; + olduser = oldsystem = oldidle = 0; + + if (recurring != true) { + do_print(); + exit(0); + } + do { + if (first_pass) { + do_difftime(false, &olduser, &oldsystem, &oldidle); + first_pass = false; + } else { + do_difftime(usepercent, &olduser, &oldsystem, &oldidle); + } + sleep(sleep_time); + } while (recurring); + + exit(0); + } + + + if (tpid) { + char *endstr; + bool first_pass = true; + + target_pid = (int)strtoul(tpid, &endstr, 0); + if (tpid[0] == '\0' || endstr[0] != '\0') + usage(); + + olduser = oldsystem = oldidle = 0; + old_pid_user = old_pid_system = old_pid_time = 0; + + do { + if (first_pass) { + do_difftime(false, &olduser, &oldsystem, &oldidle); + do_piddifftime(false, target_pid, &old_pid_user, &old_pid_system, &old_pid_time); + first_pass = false; + } else { + do_difftime(usepercent, &olduser, &oldsystem, &oldidle); + do_piddifftime(usepercent, target_pid, &old_pid_user, &old_pid_system, &old_pid_time); + } + + sleep(sleep_time); + } while (recurring); + exit(0); + } + if (optu || opts || opti) { char *endstr; @@ -94,7 +171,7 @@ main(int argc, char *argv[]) if (opti[0] == '\0' || endstr[0] != '\0') usage(); - do_difftime(usepercent, olduser, oldsystem, oldidle); + do_difftime(usepercent, &olduser, &oldsystem, &oldidle); exit(0); } @@ -104,28 +181,34 @@ main(int argc, char *argv[]) if (argc == 0) usage(); - kret = get_processor_time(&olduser, &oldsystem, &oldidle); - if (kret) - errx(1, "Error getting processor time: %s (%d)", mach_error_string(kret), kret); + do { + kret = get_processor_time(&olduser, &oldsystem, &oldidle); + if (kret) + errx(1, "Error getting processor time: %s (%d)", mach_error_string(kret), kret); + + switch(pid = vfork()) { + case -1: /* error */ + perror("time"); + exit(1); + /* NOTREACHED */ + case 0: /* child */ + execvp(*argv, argv); + perror(*argv); + _exit((errno == ENOENT) ? 127 : 126); + /* NOTREACHED */ + } - switch(pid = vfork()) { - case -1: /* error */ - perror("time"); - exit(1); - /* NOTREACHED */ - case 0: /* child */ - execvp(*argv, argv); - perror(*argv); - _exit((errno == ENOENT) ? 127 : 126); - /* NOTREACHED */ - } + /* parent */ + (void)signal(SIGINT, SIG_IGN); + (void)signal(SIGQUIT, SIG_IGN); + while (wait(&status) != pid); + (void)signal(SIGINT, SIG_DFL); + (void)signal(SIGQUIT, SIG_DFL); - /* parent */ - (void)signal(SIGINT, SIG_IGN); - (void)signal(SIGQUIT, SIG_IGN); - while (wait(&status) != pid); + do_difftime(usepercent, &olduser, &oldsystem, &oldidle); - do_difftime(usepercent, olduser, oldsystem, oldidle); + sleep(sleep_time); + } while (recurring); exit (WIFEXITED(status) ? WEXITSTATUS(status) : EXIT_FAILURE); @@ -135,9 +218,10 @@ main(int argc, char *argv[]) static void usage(void) { - fprintf(stderr, "usage: systime [-P] utility [argument ...]\n" - " systime -p\n" - " systime [-P] -u user -s sys -i idle\n"); + fprintf(stderr, "usage: systime [-P] [-r] [-t sleep_time] utility [argument ...]\n" + " systime -p [-r] [-t sleep_time]\n" + " systime [-P] -u user -s sys -i idle\n" + " systime [-P] [-r] [-t sleep_time] -T target_pid\n"); exit(1); } @@ -157,7 +241,7 @@ do_print(void) } static void -do_difftime(bool usepercent, uint64_t olduser, uint64_t oldsystem, uint64_t oldidle) +do_difftime(bool usepercent, uint64_t *olduser, uint64_t *oldsystem, uint64_t *oldidle) { uint64_t user, system, idle; uint64_t userelapsed, systemelapsed, idleelapsed, totalelapsed; @@ -167,9 +251,9 @@ do_difftime(bool usepercent, uint64_t olduser, uint64_t oldsystem, uint64_t oldi if (kret) errx(1, "Error getting processor time: %s (%d)", mach_error_string(kret), kret); - userelapsed = user - olduser; - systemelapsed = system - oldsystem; - idleelapsed = idle - oldidle; + userelapsed = user - *olduser; + systemelapsed = system - *oldsystem; + idleelapsed = idle - *oldidle; totalelapsed = userelapsed + systemelapsed + idleelapsed; if (usepercent) { @@ -189,6 +273,51 @@ do_difftime(bool usepercent, uint64_t olduser, uint64_t oldsystem, uint64_t oldi ((double)userelapsed) / 1000, ((double)systemelapsed) / 1000); } + *olduser = user; + *oldsystem = system; + *oldidle = idle; +} + +static void +do_piddifftime(bool usepercent, int pid, uint64_t *old_pid_user, uint64_t *old_pid_system, uint64_t *old_pid_time) +{ + uint64_t pid_user, pid_system, pid_time; + uint64_t userelapsed, systemelapsed, totalelapsed; + struct proc_taskinfo info; + int size; + + size = proc_pidinfo(pid, PROC_PIDTASKINFO, 0, &info, sizeof(info)); + if (size == PROC_PIDTASKINFO_SIZE) { + pid_user = info.pti_total_user; + pid_system = info.pti_total_system; + } else { + fprintf(stderr, "Error in proc_pidinfo(): %s", + strerror(errno)); + exit(1); + } + + pid_time = mach_absolute_time(); + + userelapsed = pid_user - *old_pid_user; + systemelapsed = pid_system - *old_pid_system; + totalelapsed = pid_time - *old_pid_time; + + if (usepercent) { + fprintf(stderr, "Pid %d: %1.02f%% user %1.02f%% sys\n", + pid, + ((double)userelapsed * 100)/totalelapsed, + ((double)systemelapsed * 100)/totalelapsed); + } else { + fprintf(stderr, "Pid %d: %1.02f user %1.02f sys\n", + pid, + (((double)userelapsed) * timebase_info.numer / timebase_info.denom) / 1000000000, + (((double)systemelapsed) * timebase_info.numer / timebase_info.denom) / 1000000000); + } + + *old_pid_user = pid_user; + *old_pid_system = pid_system; + *old_pid_time = pid_time; + } static kern_return_t