From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20762 invoked from network); 8 Oct 2004 14:20:01 -0000 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by ns1.primenet.com.au with SMTP; 8 Oct 2004 14:20:01 -0000 Received: (qmail 88234 invoked from network); 8 Oct 2004 14:19:50 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 8 Oct 2004 14:19:50 -0000 Received: (qmail 12659 invoked by alias); 8 Oct 2004 14:19:35 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 20467 Received: (qmail 12646 invoked from network); 8 Oct 2004 14:19:34 -0000 Received: from unknown (HELO a.mx.sunsite.dk) (130.225.247.88) by sunsite.dk with SMTP; 8 Oct 2004 14:19:34 -0000 Received: (qmail 87473 invoked from network); 8 Oct 2004 14:19:05 -0000 Received: from lhuumrelay3.lnd.ops.eu.uu.net (62.189.58.19) by a.mx.sunsite.dk with SMTP; 8 Oct 2004 14:19:04 -0000 Received: from MAILSWEEPER01.csr.com (mailhost1.csr.com [62.189.183.235]) by lhuumrelay3.lnd.ops.eu.uu.net (8.11.0/8.11.0) with ESMTP id i98EIxv26409 for ; Fri, 8 Oct 2004 14:19:00 GMT Received: from EXCHANGE02.csr.com (unverified [192.168.137.45]) by MAILSWEEPER01.csr.com (Content Technologies SMTPRS 4.3.12) with ESMTP id for ; Fri, 8 Oct 2004 15:17:57 +0100 Received: from news01.csr.com ([192.168.143.38]) by EXCHANGE02.csr.com with Microsoft SMTPSVC(5.0.2195.6713); Fri, 8 Oct 2004 15:21:14 +0100 Received: from news01.csr.com (localhost.localdomain [127.0.0.1]) by news01.csr.com (8.12.11/8.12.11) with ESMTP id i98EIuYE009601 for ; Fri, 8 Oct 2004 15:18:56 +0100 Received: from csr.com (pws@localhost) by news01.csr.com (8.12.11/8.12.11/Submit) with ESMTP id i98EIusb009598 for ; Fri, 8 Oct 2004 15:18:56 +0100 Message-Id: <200410081418.i98EIusb009598@news01.csr.com> X-Authentication-Warning: news01.csr.com: pws owned process doing -bs To: zsh-workers@sunsite.dk Subject: Re: bug with for and time In-reply-to: <200410081314.i98DEf3F007925@news01.csr.com> References: <41616CDC.8020701@codesourcery.com> <200410041610.i94GAl92005952@news01.csr.com> <20041005113848.6f3715bd@buddha.localdomain.de> <20041005181820.GC30419@dan.emsphone.com> <20041006134818.089f5218@buddha.localdomain.de> <200410061706.i96H6LTO010315@news01.csr.com> <20041006175328.GB87634@dan.emsphone.com> <200410070937.i979bRaK027278@news01.csr.com> <20041007152539.GA27081@dan.emsphone.com> <200410081314.i98DEf3F007925@news01.csr.com> Date: Fri, 08 Oct 2004 15:18:55 +0100 From: Peter Stephenson X-OriginalArrivalTime: 08 Oct 2004 14:21:14.0249 (UTC) FILETIME=[11466790:01C4AD42] X-Spam-Checker-Version: SpamAssassin 2.63 on a.mx.sunsite.dk X-Spam-Level: X-Spam-Status: No, hits=0.0 required=6.0 tests=none autolearn=no version=2.63 X-Spam-Hits: 0.0 Peter Stephenson wrote: > Still, both wait3() and the > additional rusage elements came from BSD; maybe I can rely on either > both or neither being available and skip the case where we can't tie > usage to individual processes. This is what I've done. I'm not sure doing anything else is necessary or sensible. Enjoy. I replaced the fork()s with zfork()s as threatened. As far as I can see, the only issue is error messages, and they're not very common errors. They should still print something sensible. Index: configure.ac =================================================================== RCS file: /cvsroot/zsh/zsh/configure.ac,v retrieving revision 1.20 diff -u -r1.20 configure.ac --- configure.ac 7 Oct 2004 09:45:43 -0000 1.20 +++ configure.ac 8 Oct 2004 14:13:15 -0000 @@ -1448,6 +1448,32 @@ 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 +#ifdef HAVE_SYS_TIME_H +#include +#endif +#include ]) +fi + + +dnl -------------------------------------------- dnl CHECK FOR DEFAULT PATH (used for command -p) dnl -------------------------------------------- AC_CACHE_VAL(zsh_cv_cs_path, Index: Doc/Zsh/params.yo =================================================================== RCS file: /cvsroot/zsh/zsh/Doc/Zsh/params.yo,v retrieving revision 1.22 diff -u -r1.22 params.yo --- Doc/Zsh/params.yo 22 Jun 2004 13:10:02 -0000 1.22 +++ Doc/Zsh/params.yo 8 Oct 2004 14:13:18 -0000 @@ -1047,7 +1047,9 @@ 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(%)'.) @@ -1055,6 +1057,23 @@ 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(%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() Index: Src/exec.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/exec.c,v retrieving revision 1.73 diff -u -r1.73 exec.c --- Src/exec.c 7 Oct 2004 09:45:46 -0000 1.73 +++ Src/exec.c 8 Oct 2004 14:13:25 -0000 @@ -1162,18 +1162,14 @@ (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 @@ 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; Index: Src/jobs.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/jobs.c,v retrieving revision 1.32 diff -u -r1.32 jobs.c --- Src/jobs.c 7 Oct 2004 09:45:46 -0000 1.32 +++ Src/jobs.c 8 Oct 2004 14:13:28 -0000 @@ -271,6 +271,7 @@ } +#ifndef HAVE_GETRUSAGE /* Update status of process that we have just WAIT'ed for */ /**/ @@ -278,32 +279,19 @@ 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 @@ { char *s; double elapsed_time, user_time, system_time; +#ifdef HAVE_GETRUSAGE + double total_time; +#endif int percent; if (!desc) @@ -572,10 +563,11 @@ 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 @@ 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 @@ 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 @@ { 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 @@ 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; Index: Src/signals.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/signals.c,v retrieving revision 1.31 diff -u -r1.31 signals.c --- Src/signals.c 7 Oct 2004 09:45:46 -0000 1.31 +++ Src/signals.c 8 Oct 2004 14:13:31 -0000 @@ -400,18 +400,6 @@ 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 @@ 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 @@ /* 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; Index: Src/zsh.h =================================================================== RCS file: /cvsroot/zsh/zsh/Src/zsh.h,v retrieving revision 1.63 diff -u -r1.63 zsh.h --- Src/zsh.h 7 Oct 2004 09:45:46 -0000 1.63 +++ Src/zsh.h 8 Oct 2004 14:13:35 -0000 @@ -740,10 +740,7 @@ /* 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 -- Peter Stephenson Software Engineer CSR Ltd., Science Park, Milton Road, Cambridge, CB4 0WH, UK Tel: +44 (0)1223 692070 ********************************************************************** This email and any files transmitted with it are confidential and intended solely for the use of the individual or entity to whom they are addressed. If you have received this email in error please notify the system manager. This footnote also confirms that this email message has been swept by MIMEsweeper for the presence of computer viruses. www.mimesweeper.com **********************************************************************