diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | Doc/Zsh/params.yo | 24 | ||||
-rw-r--r-- | Src/exec.c | 12 | ||||
-rw-r--r-- | Src/jobs.c | 133 | ||||
-rw-r--r-- | Src/signals.c | 39 | ||||
-rw-r--r-- | Src/zsh.h | 5 | ||||
-rw-r--r-- | configure.ac | 26 |
7 files changed, 189 insertions, 57 deletions
diff --git a/ChangeLog b/ChangeLog index 453ec96da..76c06cdaa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2004-10-08 Peter Stephenson <pws@csr.com> + + * 20467: configure.ac, Doc/Zsh/params.yo, Src/exec.c, Src/jobs.c, + Src/signals.c, Src/zsh.h: Finally reintroduce the + TIMEFMT escapes from struct rusage removed ages ago. Uses more + sophisticated autconf tests to make configuration seamless. + 2004-10-07 Peter Stephenson <pws@csr.com> * 20462: configure.ac, Src/exec.c, Src/init.c, Src/jobs.c, diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo index fd12b4f20..d9ab5c1f3 100644 --- a/Doc/Zsh/params.yo +++ b/Doc/Zsh/params.yo @@ -1047,14 +1047,34 @@ vindex(TIMEFMT) item(tt(TIMEFMT))( The format of process time reports with the tt(time) keyword. The default is `tt(%E real %U user %S system %P %J)'. -Recognizes the following escape sequences: +Recognizes the following escape sequences, although not all +may be available on all systems, and some that are available +may not be useful: startsitem() sitem(tt(%%))(A `tt(%)'.) sitem(tt(%U))(CPU seconds spent in user mode.) sitem(tt(%S))(CPU seconds spent in kernel mode.) sitem(tt(%E))(Elapsed time in seconds.) -sitem(tt(%P))(The CPU percentage, computed as (tt(%U)PLUS()tt(%S))/tt(%E).) +sitem(tt(%P))(The CPU percentage, computed as +(100*tt(%U)PLUS()tt(%S))/tt(%E).) +sitem(tt(%W))(Number of times the process was swapped.) +sitem(tt(%X))(The average amount in (shared) text space used in Kbytes.) +sitem(tt(%D))(The average amount in (unshared) data/stack space used in +Kbytes.) +sitem(tt(%K))(The total space used (%X+%D) in Kbytes.) +sitem(tt(%M))(The maximum memory the process had in use at any time in +Kbytes.) +sitem(tt(%F))(The number of major page faults (page needed to be brought +from disk).) +sitem(tt(%R))(The number of minor page faults.) +sitem(tt(%I))(The number of input operations.) +sitem(tt(%O))(The number of output operations.) +sitem(tt(%r))(The number of socket messages received.) +sitem(tt(%s))(The number of socket messages sent.) +sitem(tt(%k))(The number of signals received.) +sitem(tt(%w))(Number of voluntary context switches (waits).) +sitem(tt(%c))(Number of involuntary context switches.) sitem(tt(%J))(The name of this job.) endsitem() diff --git a/Src/exec.c b/Src/exec.c index 47d20bb93..437233bad 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -1162,18 +1162,14 @@ execpline(Estate state, wordcode slcode, int how, int last1) (jobtab[list_pipe_job].stat & STAT_STOPPED)))) { pid_t pid; int synch[2]; - struct timezone dummy_tz; struct timeval bgtime; pipe(synch); - gettimeofday(&bgtime, &dummy_tz); - /* Any reason this isn't zfork? */ - if ((pid = fork()) == -1) { + if ((pid = zfork(&bgtime)) == -1) { trashzle(); close(synch[0]); close(synch[1]); - putc('\n', stderr); fprintf(stderr, "zsh: job can't be suspended\n"); fflush(stderr); makerunning(jn); @@ -1300,15 +1296,11 @@ execpline2(Estate state, wordcode pcode, if (wc_code(code) >= WC_CURSH && (how & Z_SYNC)) { int synch[2]; struct timeval bgtime; - struct timezone dummy_tz; pipe(synch); - gettimeofday(&bgtime, &dummy_tz); - /* any reason this isn't zfork? */ - if ((pid = fork()) == -1) { + if ((pid = zfork(&bgtime)) == -1) { close(synch[0]); close(synch[1]); - zerr("fork failed: %e", NULL, errno); } else if (pid) { char dummy, *text; diff --git a/Src/jobs.c b/Src/jobs.c index 0c3960e87..9bb8bbbd7 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -271,6 +271,7 @@ get_usage(void) } +#ifndef HAVE_GETRUSAGE /* Update status of process that we have just WAIT'ed for */ /**/ @@ -278,32 +279,19 @@ void update_process(Process pn, int status) { struct timezone dummy_tz; -#ifdef HAVE_GETRUSAGE - struct timeval childs, childu; -#else long childs, childu; -#endif -#ifdef HAVE_GETRUSAGE - childs = child_usage.ru_stime; - childu = child_usage.ru_utime; -#else childs = shtms.tms_cstime; childu = shtms.tms_cutime; -#endif /* get time-accounting info */ get_usage(); gettimeofday(&pn->endtime, &dummy_tz); /* record time process exited */ pn->status = status; /* save the status returned by WAIT */ -#ifdef HAVE_GETRUSAGE - dtime(&pn->ti.sys, &childs, &child_usage.ru_stime); - dtime(&pn->ti.usr, &childu, &child_usage.ru_utime); -#else pn->ti.st = shtms.tms_cstime - childs; /* compute process system space time */ pn->ti.ut = shtms.tms_cutime - childu; /* compute process user space time */ -#endif } +#endif /* Update status of job, possibly printing it */ @@ -563,6 +551,9 @@ printtime(struct timeval *real, child_times_t *ti, char *desc) { char *s; double elapsed_time, user_time, system_time; +#ifdef HAVE_GETRUSAGE + double total_time; +#endif int percent; if (!desc) @@ -572,10 +563,11 @@ printtime(struct timeval *real, child_times_t *ti, char *desc) elapsed_time = real->tv_sec + real->tv_usec / 1000000.0; #ifdef HAVE_GETRUSAGE - user_time = ti->usr.tv_sec + ti->usr.tv_usec / 1000000.0; - system_time = ti->sys.tv_sec + ti->sys.tv_usec / 1000000.0; + user_time = ti->ru_utime.tv_sec + ti->ru_utime.tv_usec / 1000000.0; + system_time = ti->ru_stime.tv_sec + ti->ru_stime.tv_usec / 1000000.0; percent = 100.0 * (user_time + system_time) / (real->tv_sec + real->tv_usec / 1000000.0); + total_time = user_time + system_time; #else set_clktck(); user_time = ti->ut / (double) clktck; @@ -620,6 +612,97 @@ printtime(struct timeval *real, child_times_t *ti, char *desc) case 'P': fprintf(stderr, "%d%%", percent); break; +#ifdef HAVE_STRUCT_RUSAGE_RU_NSWAP + case 'W': + fprintf(stderr, "%ld", ti->ru_nswap); + break; +#endif +#ifdef HAVE_STRUCT_RUSAGE_RU_IXRSS + case 'X': + fprintf(stderr, "%ld", (long)(ti->ru_ixrss / total_time)); + break; +#endif +#ifdef HAVE_STRUCT_RUSAGE_RU_IDRSS + case 'D': + fprintf(stderr, "%ld", + (long) ((ti->ru_idrss +#ifdef HAVE_STRUCT_RUSAGE_RU_ISRSS + + ti->ru_isrss +#endif + ) / total_time)); + break; +#endif +#if defined(HAVE_STRUCT_RUSAGE_RU_IDRSS) || \ + defined(HAVE_STRUCT_RUSAGE_RU_ISRSS) || \ + defined(HAVE_STRUCT_RUSAGE_RU_IXRSS) + case 'K': + /* treat as D if X not available */ + fprintf(stderr, "%ld", + (long) (( +#ifdef HAVE_STRUCT_RUSAGE_RU_IXRSS + ti->ru_ixrss +#else + 0 +#endif +#ifdef HAVE_STRUCT_RUSAGE_RU_IDRSS + + ti->ru_idrss +#endif +#ifdef HAVE_STRUCT_RUSAGE_RU_ISRSS + + ti->ru_isrss +#endif + ) / total_time)); + break; +#endif +#ifdef HAVE_STRUCT_RUSAGE_RU_MAXRSS + case 'M': + fprintf(stderr, "%ld", ti->ru_maxrss / 1024); + break; +#endif +#ifdef HAVE_STRUCT_RUSAGE_RU_MAJFLT + case 'F': + fprintf(stderr, "%ld", ti->ru_majflt); + break; +#endif +#ifdef HAVE_STRUCT_RUSAGE_RU_MINFLT + case 'R': + fprintf(stderr, "%ld", ti->ru_minflt); + break; +#endif +#ifdef HAVE_STRUCT_RUSAGE_RU_INBLOCK + case 'I': + fprintf(stderr, "%ld", ti->ru_inblock); + break; +#endif +#ifdef HAVE_STRUCT_RUSAGE_RU_OUBLOCK + case 'O': + fprintf(stderr, "%ld", ti->ru_oublock); + break; +#endif +#ifdef HAVE_STRUCT_RUSAGE_RU_MSGRCV + case 'r': + fprintf(stderr, "%ld", ti->ru_msgrcv); + break; +#endif +#ifdef HAVE_STRUCT_RUSAGE_RU_MSGSND + case 's': + fprintf(stderr, "%ld", ti->ru_msgsnd); + break; +#endif +#ifdef HAVE_STRUCT_RUSAGE_RU_NSIGNALS + case 'k': + fprintf(stderr, "%ld", ti->ru_nsignals); + break; +#endif +#ifdef HAVE_STRUCT_RUSAGE_RU_NVCSW + case 'w': + fprintf(stderr, "%ld", ti->ru_nvcsw); + break; +#endif +#ifdef HAVE_STRUCT_RUSAGE_RU_NIVCSW + case 'c': + fprintf(stderr, "%ld", ti->ru_nivcsw); + break; +#endif case 'J': fprintf(stderr, "%s", desc); break; @@ -683,8 +766,9 @@ should_report_time(Job j) return 0; #ifdef HAVE_GETRUSAGE - reporttime -= j->procs->ti.usr.tv_sec + j->procs->ti.sys.tv_sec; - if (j->procs->ti.usr.tv_usec + j->procs->ti.sys.tv_usec >= 1000000) + reporttime -= j->procs->ti.ru_utime.tv_sec + j->procs->ti.ru_stime.tv_sec; + if (j->procs->ti.ru_utime.tv_usec + + j->procs->ti.ru_stime.tv_usec >= 1000000) reporttime--; return reporttime <= 0; #else @@ -1214,20 +1298,15 @@ shelltime(void) { struct timezone dummy_tz; struct timeval dtimeval, now; -#ifdef HAVE_GETRUSAGE - struct rusage ru; child_times_t ti; -#else - struct timeinfo ti; +#ifndef HAVE_GETRUSAGE struct tms buf; #endif gettimeofday(&now, &dummy_tz); #ifdef HAVE_GETRUSAGE - getrusage(RUSAGE_SELF, &ru); - ti.sys = ru.ru_stime; - ti.usr = ru.ru_utime; + getrusage(RUSAGE_SELF, &ti); #else times(&buf); @@ -1237,9 +1316,7 @@ shelltime(void) printtime(dtime(&dtimeval, &shtimer, &now), &ti, "shell"); #ifdef HAVE_GETRUSAGE - getrusage(RUSAGE_CHILDREN, &ru); - ti.sys = ru.ru_stime; - ti.usr = ru.ru_utime; + getrusage(RUSAGE_CHILDREN, &ti); #else ti.ut = buf.tms_cutime; ti.st = buf.tms_cstime; diff --git a/Src/signals.c b/Src/signals.c index df9120d2d..fd5d47e71 100644 --- a/Src/signals.c +++ b/Src/signals.c @@ -400,18 +400,6 @@ signal_suspend(int sig, int sig2) return ret; } -/* What flavor of waitpid/wait3/wait shall we use? */ - -#ifdef HAVE_WAITPID -# define WAIT(pid, statusp, options) waitpid(pid, statusp, options) -#else -# ifdef HAVE_WAIT3 -# define WAIT(pid, statusp, options) wait3((void *) statusp, options, NULL) -# else -# define WAIT(pid, statusp, options) wait(statusp) -# endif -#endif - /* the signal handler */ /**/ @@ -471,7 +459,25 @@ zhandler(int sig) int *procsubval = &cmdoutval; struct execstack *es = exstack; - pid = WAIT(-1, &status, WNOHANG|WUNTRACED); /* reap the child process */ + /* + * Reap the child process. + * If we want usage information, we need to use wait3. + */ +#ifdef HAVE_WAIT3 +# ifdef HAVE_GETRUSAGE + struct rusage ru; + + pid = wait3((void *)&status, WNOHANG|WUNTRACED, &ru); +# else + pid = wait3((void *)&status, WNOHANG|WUNTRACED, NULL); +# endif +#else +# ifdef HAVE_WAITPID + pid = waitpid(-1, &status, WNOHANG|WUNTRACED); +# else + pid = wait(&status); +# endif +#endif if (!pid) /* no more children to reap */ break; @@ -504,7 +510,14 @@ zhandler(int sig) /* Find the process and job containing this pid and update it. */ if (findproc(pid, &jn, &pn, 0)) { +#if defined(HAVE_WAIT3) && defined(HAVE_GETRUSAGE) + struct timezone dummy_tz; + gettimeofday(&pn->endtime, &dummy_tz); + pn->status = status; + pn->ti = ru; +#else update_process(pn, status); +#endif update_job(jn); } else if (findproc(pid, &jn, &pn, 1)) { pn->status = status; diff --git a/Src/zsh.h b/Src/zsh.h index bde274d9b..8d27e2014 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -740,10 +740,7 @@ struct timeinfo { /* node in job process lists */ #ifdef HAVE_GETRUSAGE -typedef struct { - struct timeval sys; - struct timeval usr; -} child_times_t; +typedef struct rusage child_times_t; #else typedef struct timeinfo child_times_t; #endif diff --git a/configure.ac b/configure.ac index 11b97b9da..3bb6e3b35 100644 --- a/configure.ac +++ b/configure.ac @@ -1448,6 +1448,32 @@ fi dnl -------------------------------------------- +dnl Check for members of struct rusage +dnl -------------------------------------------- +if test $ac_cv_func_getrusage = yes; then + AC_CHECK_MEMBERS([struct rusage.ru_maxrss, + struct rusage.ru_ixrss, + struct rusage.ru_idrss, + struct rusage.ru_isrss, + struct rusage.ru_minflt, + struct rusage.ru_majflt, + struct rusage.ru_nswap, + struct rusage.ru_inblock, + struct rusage.ru_oublock, + struct rusage.ru_msgsnd, + struct rusage.ru_msgrcv, + struct rusage.ru_nsignals, + struct rusage.ru_nvcsw, + struct rusage.ru_nivcsw],,, +[#include <sys/types.h> +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif +#include <sys/resource.h>]) +fi + + +dnl -------------------------------------------- dnl CHECK FOR DEFAULT PATH (used for command -p) dnl -------------------------------------------- AC_CACHE_VAL(zsh_cv_cs_path, |