mirror of
https://github.com/zsh-users/zsh
synced 2024-09-16 06:30:26 +00:00
20467: Reintroduce rusage-based escapes for TIMEFMT.
This commit is contained in:
parent
cc72740775
commit
8a67a66a61
|
@ -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,
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
12
Src/exec.c
12
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;
|
||||
|
||||
|
|
133
Src/jobs.c
133
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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
26
configure.ac
26
configure.ac
|
@ -1447,6 +1447,32 @@ if test $zsh_cv_rlimit_vmem_is_as = yes; then
|
|||
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 --------------------------------------------
|
||||
|
|
Loading…
Reference in a new issue