mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-09-13 01:31:18 +02:00
20462: Use getrusage for timing again.
Time processes from before rather than after fork.
This commit is contained in:
parent
0f7a3eaca5
commit
cc72740775
7 changed files with 148 additions and 38 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
2004-10-07 Peter Stephenson <pws@csr.com>
|
||||||
|
|
||||||
|
* 20462: configure.ac, Src/exec.c, Src/init.c, Src/jobs.c,
|
||||||
|
Src/signals.c, Src/zsh.h: Improve process timing by using
|
||||||
|
getrusage() where available (everywhere?) and by starting
|
||||||
|
the wallclock just before a process is forked.
|
||||||
|
|
||||||
2004-10-07 Wayne Davison <wayned@users.sourceforge.net>
|
2004-10-07 Wayne Davison <wayned@users.sourceforge.net>
|
||||||
|
|
||||||
* unposted: Completion/Unix/Command/_rsync: added options that
|
* unposted: Completion/Unix/Command/_rsync: added options that
|
||||||
|
|
50
Src/exec.c
50
Src/exec.c
|
@ -212,9 +212,10 @@ setlimits(char *nam)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static pid_t
|
static pid_t
|
||||||
zfork(void)
|
zfork(struct timeval *tv)
|
||||||
{
|
{
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
struct timezone dummy_tz;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Is anybody willing to explain this test?
|
* Is anybody willing to explain this test?
|
||||||
|
@ -223,6 +224,8 @@ zfork(void)
|
||||||
zerr("job table full", NULL, 0);
|
zerr("job table full", NULL, 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (tv)
|
||||||
|
gettimeofday(tv, &dummy_tz);
|
||||||
pid = fork();
|
pid = fork();
|
||||||
if (pid == -1) {
|
if (pid == -1) {
|
||||||
zerr("fork failed: %e", NULL, errno);
|
zerr("fork failed: %e", NULL, errno);
|
||||||
|
@ -313,6 +316,7 @@ zfork(void)
|
||||||
int list_pipe = 0, simple_pline = 0;
|
int list_pipe = 0, simple_pline = 0;
|
||||||
|
|
||||||
static pid_t list_pipe_pid;
|
static pid_t list_pipe_pid;
|
||||||
|
static struct timeval list_pipe_start;
|
||||||
static int nowait, pline_level = 0;
|
static int nowait, pline_level = 0;
|
||||||
static int list_pipe_child = 0, list_pipe_job;
|
static int list_pipe_child = 0, list_pipe_job;
|
||||||
static char list_pipe_text[JOBTEXTSIZE];
|
static char list_pipe_text[JOBTEXTSIZE];
|
||||||
|
@ -1101,7 +1105,8 @@ execpline(Estate state, wordcode slcode, int how, int last1)
|
||||||
|
|
||||||
curjob = newjob;
|
curjob = newjob;
|
||||||
DPUTS(!list_pipe_pid, "invalid list_pipe_pid");
|
DPUTS(!list_pipe_pid, "invalid list_pipe_pid");
|
||||||
addproc(list_pipe_pid, list_pipe_text, 0);
|
addproc(list_pipe_pid, list_pipe_text, 0,
|
||||||
|
&list_pipe_start);
|
||||||
|
|
||||||
/* If the super-job contains only the sub-shell, the
|
/* If the super-job contains only the sub-shell, the
|
||||||
sub-shell is the group leader. */
|
sub-shell is the group leader. */
|
||||||
|
@ -1157,9 +1162,13 @@ execpline(Estate state, wordcode slcode, int how, int last1)
|
||||||
(jobtab[list_pipe_job].stat & STAT_STOPPED)))) {
|
(jobtab[list_pipe_job].stat & STAT_STOPPED)))) {
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int synch[2];
|
int synch[2];
|
||||||
|
struct timezone dummy_tz;
|
||||||
|
struct timeval bgtime;
|
||||||
|
|
||||||
pipe(synch);
|
pipe(synch);
|
||||||
|
|
||||||
|
gettimeofday(&bgtime, &dummy_tz);
|
||||||
|
/* Any reason this isn't zfork? */
|
||||||
if ((pid = fork()) == -1) {
|
if ((pid = fork()) == -1) {
|
||||||
trashzle();
|
trashzle();
|
||||||
close(synch[0]);
|
close(synch[0]);
|
||||||
|
@ -1177,6 +1186,7 @@ execpline(Estate state, wordcode slcode, int how, int last1)
|
||||||
lpforked =
|
lpforked =
|
||||||
(killpg(jobtab[list_pipe_job].gleader, 0) == -1 ? 2 : 1);
|
(killpg(jobtab[list_pipe_job].gleader, 0) == -1 ? 2 : 1);
|
||||||
list_pipe_pid = pid;
|
list_pipe_pid = pid;
|
||||||
|
list_pipe_start = bgtime;
|
||||||
nowait = errflag = 1;
|
nowait = errflag = 1;
|
||||||
breaks = loops;
|
breaks = loops;
|
||||||
close(synch[1]);
|
close(synch[1]);
|
||||||
|
@ -1289,8 +1299,12 @@ execpline2(Estate state, wordcode pcode,
|
||||||
* rest of the pipeline in the current shell. */
|
* rest of the pipeline in the current shell. */
|
||||||
if (wc_code(code) >= WC_CURSH && (how & Z_SYNC)) {
|
if (wc_code(code) >= WC_CURSH && (how & Z_SYNC)) {
|
||||||
int synch[2];
|
int synch[2];
|
||||||
|
struct timeval bgtime;
|
||||||
|
struct timezone dummy_tz;
|
||||||
|
|
||||||
pipe(synch);
|
pipe(synch);
|
||||||
|
gettimeofday(&bgtime, &dummy_tz);
|
||||||
|
/* any reason this isn't zfork? */
|
||||||
if ((pid = fork()) == -1) {
|
if ((pid = fork()) == -1) {
|
||||||
close(synch[0]);
|
close(synch[0]);
|
||||||
close(synch[1]);
|
close(synch[1]);
|
||||||
|
@ -1299,7 +1313,7 @@ execpline2(Estate state, wordcode pcode,
|
||||||
char dummy, *text;
|
char dummy, *text;
|
||||||
|
|
||||||
text = getjobtext(state->prog, state->pc);
|
text = getjobtext(state->prog, state->pc);
|
||||||
addproc(pid, text, 0);
|
addproc(pid, text, 0, &bgtime);
|
||||||
close(synch[1]);
|
close(synch[1]);
|
||||||
read(synch[0], &dummy, 1);
|
read(synch[0], &dummy, 1);
|
||||||
close(synch[0]);
|
close(synch[0]);
|
||||||
|
@ -1437,8 +1451,9 @@ closemn(struct multio **mfds, int fd)
|
||||||
char buf[TCBUFSIZE];
|
char buf[TCBUFSIZE];
|
||||||
int len, i;
|
int len, i;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
struct timeval bgtime;
|
||||||
|
|
||||||
if ((pid = zfork())) {
|
if ((pid = zfork(&bgtime))) {
|
||||||
for (i = 0; i < mn->ct; i++)
|
for (i = 0; i < mn->ct; i++)
|
||||||
zclose(mn->fds[i]);
|
zclose(mn->fds[i]);
|
||||||
zclose(mn->pipe);
|
zclose(mn->pipe);
|
||||||
|
@ -1448,7 +1463,7 @@ closemn(struct multio **mfds, int fd)
|
||||||
}
|
}
|
||||||
mn->ct = 1;
|
mn->ct = 1;
|
||||||
mn->fds[0] = fd;
|
mn->fds[0] = fd;
|
||||||
addproc(pid, NULL, 1);
|
addproc(pid, NULL, 1, &bgtime);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* pid == 0 */
|
/* pid == 0 */
|
||||||
|
@ -2108,11 +2123,12 @@ execcmd(Estate state, int input, int output, int how, int last1)
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int synch[2];
|
int synch[2];
|
||||||
char dummy;
|
char dummy;
|
||||||
|
struct timeval bgtime;
|
||||||
|
|
||||||
child_block();
|
child_block();
|
||||||
pipe(synch);
|
pipe(synch);
|
||||||
|
|
||||||
if ((pid = zfork()) == -1) {
|
if ((pid = zfork(&bgtime)) == -1) {
|
||||||
close(synch[0]);
|
close(synch[0]);
|
||||||
close(synch[1]);
|
close(synch[1]);
|
||||||
opts[AUTOCONTINUE] = oautocont;
|
opts[AUTOCONTINUE] = oautocont;
|
||||||
|
@ -2140,7 +2156,7 @@ execcmd(Estate state, int input, int output, int how, int last1)
|
||||||
3 : WC_ASSIGN_NUM(ac) + 2);
|
3 : WC_ASSIGN_NUM(ac) + 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addproc(pid, text, 0);
|
addproc(pid, text, 0, &bgtime);
|
||||||
opts[AUTOCONTINUE] = oautocont;
|
opts[AUTOCONTINUE] = oautocont;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2697,7 +2713,7 @@ entersubsh(int how, int cl, int fake, int revertpgrp)
|
||||||
zleactive = 0;
|
zleactive = 0;
|
||||||
if (cl)
|
if (cl)
|
||||||
clearjobtab(monitor);
|
clearjobtab(monitor);
|
||||||
times(&shtms);
|
get_usage();
|
||||||
forklevel = locallevel;
|
forklevel = locallevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2843,7 +2859,7 @@ getoutput(char *cmd, int qt)
|
||||||
mpipe(pipes);
|
mpipe(pipes);
|
||||||
child_block();
|
child_block();
|
||||||
cmdoutval = 0;
|
cmdoutval = 0;
|
||||||
if ((cmdoutpid = pid = zfork()) == -1) {
|
if ((cmdoutpid = pid = zfork(NULL)) == -1) {
|
||||||
/* fork error */
|
/* fork error */
|
||||||
zclose(pipes[0]);
|
zclose(pipes[0]);
|
||||||
zclose(pipes[1]);
|
zclose(pipes[1]);
|
||||||
|
@ -2979,7 +2995,7 @@ getoutputfile(char *cmd)
|
||||||
child_block();
|
child_block();
|
||||||
fd = open(nam, O_WRONLY | O_CREAT | O_EXCL | O_NOCTTY, 0600);
|
fd = open(nam, O_WRONLY | O_CREAT | O_EXCL | O_NOCTTY, 0600);
|
||||||
|
|
||||||
if (fd < 0 || (cmdoutpid = pid = zfork()) == -1) {
|
if (fd < 0 || (cmdoutpid = pid = zfork(NULL)) == -1) {
|
||||||
/* fork or open error */
|
/* fork or open error */
|
||||||
child_unblock();
|
child_unblock();
|
||||||
return nam;
|
return nam;
|
||||||
|
@ -3040,6 +3056,7 @@ getproc(char *cmd)
|
||||||
int out = *cmd == Inang;
|
int out = *cmd == Inang;
|
||||||
char *pnam;
|
char *pnam;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
struct timeval bgtime;
|
||||||
|
|
||||||
#ifndef PATH_DEV_FD
|
#ifndef PATH_DEV_FD
|
||||||
int fd;
|
int fd;
|
||||||
|
@ -3054,11 +3071,11 @@ getproc(char *cmd)
|
||||||
jobtab[thisjob].filelist = znewlinklist();
|
jobtab[thisjob].filelist = znewlinklist();
|
||||||
zaddlinknode(jobtab[thisjob].filelist, ztrdup(pnam));
|
zaddlinknode(jobtab[thisjob].filelist, ztrdup(pnam));
|
||||||
|
|
||||||
if ((pid = zfork())) {
|
if ((pid = zfork(&bgtime))) {
|
||||||
if (pid == -1)
|
if (pid == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (!out)
|
if (!out)
|
||||||
addproc(pid, NULL, 1);
|
addproc(pid, NULL, 1, &bgtime);
|
||||||
return pnam;
|
return pnam;
|
||||||
}
|
}
|
||||||
closem(0);
|
closem(0);
|
||||||
|
@ -3078,7 +3095,7 @@ getproc(char *cmd)
|
||||||
if (!(prog = parsecmd(cmd)))
|
if (!(prog = parsecmd(cmd)))
|
||||||
return NULL;
|
return NULL;
|
||||||
mpipe(pipes);
|
mpipe(pipes);
|
||||||
if ((pid = zfork())) {
|
if ((pid = zfork(&bgtime))) {
|
||||||
sprintf(pnam, "%s/%d", PATH_DEV_FD, pipes[!out]);
|
sprintf(pnam, "%s/%d", PATH_DEV_FD, pipes[!out]);
|
||||||
zclose(pipes[out]);
|
zclose(pipes[out]);
|
||||||
if (pid == -1)
|
if (pid == -1)
|
||||||
|
@ -3089,7 +3106,7 @@ getproc(char *cmd)
|
||||||
fdtable[pipes[!out]] = 2;
|
fdtable[pipes[!out]] = 2;
|
||||||
if (!out)
|
if (!out)
|
||||||
{
|
{
|
||||||
addproc(pid, NULL, 1);
|
addproc(pid, NULL, 1, &bgtime);
|
||||||
}
|
}
|
||||||
return pnam;
|
return pnam;
|
||||||
}
|
}
|
||||||
|
@ -3116,17 +3133,18 @@ getpipe(char *cmd)
|
||||||
Eprog prog;
|
Eprog prog;
|
||||||
int pipes[2], out = *cmd == Inang;
|
int pipes[2], out = *cmd == Inang;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
struct timeval bgtime;
|
||||||
|
|
||||||
if (!(prog = parsecmd(cmd)))
|
if (!(prog = parsecmd(cmd)))
|
||||||
return -1;
|
return -1;
|
||||||
mpipe(pipes);
|
mpipe(pipes);
|
||||||
if ((pid = zfork())) {
|
if ((pid = zfork(&bgtime))) {
|
||||||
zclose(pipes[out]);
|
zclose(pipes[out]);
|
||||||
if (pid == -1) {
|
if (pid == -1) {
|
||||||
zclose(pipes[!out]);
|
zclose(pipes[!out]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
addproc(pid, NULL, 1);
|
addproc(pid, NULL, 1, &bgtime);
|
||||||
return pipes[!out];
|
return pipes[!out];
|
||||||
}
|
}
|
||||||
entersubsh(Z_ASYNC, 1, 0, 0);
|
entersubsh(Z_ASYNC, 1, 0, 0);
|
||||||
|
|
|
@ -856,7 +856,7 @@ setupvals(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
times(&shtms);
|
get_usage();
|
||||||
|
|
||||||
/* Close the file descriptors we opened to block off 0 to 9 */
|
/* Close the file descriptors we opened to block off 0 to 9 */
|
||||||
for (i = 0; i < 10; i++)
|
for (i = 0; i < 10; i++)
|
||||||
|
|
110
Src/jobs.c
110
Src/jobs.c
|
@ -80,7 +80,15 @@ static int oldmaxjob;
|
||||||
/* shell timings */
|
/* shell timings */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
struct tms shtms;
|
#ifdef HAVE_GETRUSAGE
|
||||||
|
/**/
|
||||||
|
static struct rusage child_usage;
|
||||||
|
/**/
|
||||||
|
#else
|
||||||
|
/**/
|
||||||
|
static struct tms shtms;
|
||||||
|
/**/
|
||||||
|
#endif
|
||||||
|
|
||||||
/* 1 if ttyctl -f has been executed */
|
/* 1 if ttyctl -f has been executed */
|
||||||
|
|
||||||
|
@ -93,8 +101,6 @@ int ttyfrozen;
|
||||||
/**/
|
/**/
|
||||||
int prev_errflag, prev_breaks, errbrk_saved;
|
int prev_errflag, prev_breaks, errbrk_saved;
|
||||||
|
|
||||||
static struct timeval dtimeval, now;
|
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
int numpipestats, pipestats[MAX_PIPESTATS];
|
int numpipestats, pipestats[MAX_PIPESTATS];
|
||||||
|
|
||||||
|
@ -250,6 +256,21 @@ handle_sub(int job, int fg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Get the latest usage information */
|
||||||
|
|
||||||
|
/**/
|
||||||
|
void
|
||||||
|
get_usage(void)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_GETRUSAGE
|
||||||
|
getrusage(RUSAGE_CHILDREN, &child_usage);
|
||||||
|
#else
|
||||||
|
times(shtms);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Update status of process that we have just WAIT'ed for */
|
/* Update status of process that we have just WAIT'ed for */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
@ -257,17 +278,31 @@ void
|
||||||
update_process(Process pn, int status)
|
update_process(Process pn, int status)
|
||||||
{
|
{
|
||||||
struct timezone dummy_tz;
|
struct timezone dummy_tz;
|
||||||
|
#ifdef HAVE_GETRUSAGE
|
||||||
|
struct timeval childs, childu;
|
||||||
|
#else
|
||||||
long childs, childu;
|
long childs, childu;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_GETRUSAGE
|
||||||
|
childs = child_usage.ru_stime;
|
||||||
|
childu = child_usage.ru_utime;
|
||||||
|
#else
|
||||||
childs = shtms.tms_cstime;
|
childs = shtms.tms_cstime;
|
||||||
childu = shtms.tms_cutime;
|
childu = shtms.tms_cutime;
|
||||||
times(&shtms); /* get time-accounting info */
|
#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 */
|
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.st = shtms.tms_cstime - childs; /* compute process system space time */
|
||||||
pn->ti.ut = shtms.tms_cutime - childu; /* compute process user space time */
|
pn->ti.ut = shtms.tms_cutime - childu; /* compute process user space time */
|
||||||
|
#endif
|
||||||
gettimeofday(&pn->endtime, &dummy_tz); /* record time process exited */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update status of job, possibly printing it */
|
/* Update status of job, possibly printing it */
|
||||||
|
@ -473,6 +508,8 @@ setprevjob(void)
|
||||||
prevjob = -1;
|
prevjob = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
#ifndef HAVE_GETRUSAGE
|
||||||
static long clktck = 0;
|
static long clktck = 0;
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
@ -501,6 +538,8 @@ set_clktck(void)
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
/**/
|
||||||
|
#endif
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static void
|
static void
|
||||||
|
@ -519,9 +558,8 @@ printhhmmss(double secs)
|
||||||
fprintf(stderr, "%.3f", secs);
|
fprintf(stderr, "%.3f", secs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**/
|
|
||||||
static void
|
static void
|
||||||
printtime(struct timeval *real, struct timeinfo *ti, char *desc)
|
printtime(struct timeval *real, child_times_t *ti, char *desc)
|
||||||
{
|
{
|
||||||
char *s;
|
char *s;
|
||||||
double elapsed_time, user_time, system_time;
|
double elapsed_time, user_time, system_time;
|
||||||
|
@ -530,13 +568,21 @@ printtime(struct timeval *real, struct timeinfo *ti, char *desc)
|
||||||
if (!desc)
|
if (!desc)
|
||||||
desc = "";
|
desc = "";
|
||||||
|
|
||||||
set_clktck();
|
|
||||||
/* go ahead and compute these, since almost every TIMEFMT will have them */
|
/* go ahead and compute these, since almost every TIMEFMT will have them */
|
||||||
elapsed_time = real->tv_sec + real->tv_usec / 1000000.0;
|
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;
|
||||||
|
percent = 100.0 * (user_time + system_time)
|
||||||
|
/ (real->tv_sec + real->tv_usec / 1000000.0);
|
||||||
|
#else
|
||||||
|
set_clktck();
|
||||||
user_time = ti->ut / (double) clktck;
|
user_time = ti->ut / (double) clktck;
|
||||||
system_time = ti->st / (double) clktck;
|
system_time = ti->st / (double) clktck;
|
||||||
percent = 100.0 * (ti->ut + ti->st)
|
percent = 100.0 * (ti->ut + ti->st)
|
||||||
/ (clktck * real->tv_sec + clktck * real->tv_usec / 1000000.0);
|
/ (clktck * real->tv_sec + clktck * real->tv_usec / 1000000.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
queue_signals();
|
queue_signals();
|
||||||
if (!(s = getsparam("TIMEFMT")))
|
if (!(s = getsparam("TIMEFMT")))
|
||||||
|
@ -598,11 +644,13 @@ static void
|
||||||
dumptime(Job jn)
|
dumptime(Job jn)
|
||||||
{
|
{
|
||||||
Process pn;
|
Process pn;
|
||||||
|
struct timeval dtimeval;
|
||||||
|
|
||||||
if (!jn->procs)
|
if (!jn->procs)
|
||||||
return;
|
return;
|
||||||
for (pn = jn->procs; pn; pn = pn->next)
|
for (pn = jn->procs; pn; pn = pn->next)
|
||||||
printtime(dtime(&dtimeval, &pn->bgtime, &pn->endtime), &pn->ti, pn->text);
|
printtime(dtime(&dtimeval, &pn->bgtime, &pn->endtime), &pn->ti,
|
||||||
|
pn->text);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check whether shell should report the amount of time consumed *
|
/* Check whether shell should report the amount of time consumed *
|
||||||
|
@ -617,7 +665,7 @@ should_report_time(Job j)
|
||||||
struct value vbuf;
|
struct value vbuf;
|
||||||
Value v;
|
Value v;
|
||||||
char *s = "REPORTTIME";
|
char *s = "REPORTTIME";
|
||||||
int reporttime;
|
zlong reporttime;
|
||||||
|
|
||||||
/* if the time keyword was used */
|
/* if the time keyword was used */
|
||||||
if (j->stat & STAT_TIMED)
|
if (j->stat & STAT_TIMED)
|
||||||
|
@ -634,8 +682,15 @@ should_report_time(Job j)
|
||||||
if (!j->procs)
|
if (!j->procs)
|
||||||
return 0;
|
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--;
|
||||||
|
return reporttime <= 0;
|
||||||
|
#else
|
||||||
set_clktck();
|
set_clktck();
|
||||||
return ((j->procs->ti.ut + j->procs->ti.st) / clktck >= reporttime);
|
return ((j->procs->ti.ut + j->procs->ti.st) / clktck >= reporttime);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* !(lng & 3) means jobs *
|
/* !(lng & 3) means jobs *
|
||||||
|
@ -899,10 +954,9 @@ deletejob(Job jn)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
void
|
void
|
||||||
addproc(pid_t pid, char *text, int aux)
|
addproc(pid_t pid, char *text, int aux, struct timeval *bgtime)
|
||||||
{
|
{
|
||||||
Process pn, *pnlist;
|
Process pn, *pnlist;
|
||||||
struct timezone dummy_tz;
|
|
||||||
|
|
||||||
DPUTS(thisjob == -1, "No valid job in addproc.");
|
DPUTS(thisjob == -1, "No valid job in addproc.");
|
||||||
pn = (Process) zshcalloc(sizeof *pn);
|
pn = (Process) zshcalloc(sizeof *pn);
|
||||||
|
@ -916,7 +970,7 @@ addproc(pid_t pid, char *text, int aux)
|
||||||
|
|
||||||
if (!aux)
|
if (!aux)
|
||||||
{
|
{
|
||||||
gettimeofday(&pn->bgtime, &dummy_tz);
|
pn->bgtime = *bgtime;
|
||||||
/* if this is the first process we are adding to *
|
/* if this is the first process we are adding to *
|
||||||
* the job, then it's the group leader. */
|
* the job, then it's the group leader. */
|
||||||
if (!jobtab[thisjob].gleader)
|
if (!jobtab[thisjob].gleader)
|
||||||
|
@ -1158,18 +1212,40 @@ spawnjob(void)
|
||||||
void
|
void
|
||||||
shelltime(void)
|
shelltime(void)
|
||||||
{
|
{
|
||||||
struct timeinfo ti;
|
|
||||||
struct timezone dummy_tz;
|
struct timezone dummy_tz;
|
||||||
|
struct timeval dtimeval, now;
|
||||||
|
#ifdef HAVE_GETRUSAGE
|
||||||
|
struct rusage ru;
|
||||||
|
child_times_t ti;
|
||||||
|
#else
|
||||||
|
struct timeinfo ti;
|
||||||
struct tms buf;
|
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;
|
||||||
|
#else
|
||||||
times(&buf);
|
times(&buf);
|
||||||
|
|
||||||
ti.ut = buf.tms_utime;
|
ti.ut = buf.tms_utime;
|
||||||
ti.st = buf.tms_stime;
|
ti.st = buf.tms_stime;
|
||||||
gettimeofday(&now, &dummy_tz);
|
#endif
|
||||||
printtime(dtime(&dtimeval, &shtimer, &now), &ti, "shell");
|
printtime(dtime(&dtimeval, &shtimer, &now), &ti, "shell");
|
||||||
|
|
||||||
|
#ifdef HAVE_GETRUSAGE
|
||||||
|
getrusage(RUSAGE_CHILDREN, &ru);
|
||||||
|
ti.sys = ru.ru_stime;
|
||||||
|
ti.usr = ru.ru_utime;
|
||||||
|
#else
|
||||||
ti.ut = buf.tms_cutime;
|
ti.ut = buf.tms_cutime;
|
||||||
ti.st = buf.tms_cstime;
|
ti.st = buf.tms_cstime;
|
||||||
printtime(dtime(&dtimeval, &shtimer, &now), &ti, "children");
|
#endif
|
||||||
|
printtime(&dtimeval, &ti, "children");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* see if jobs need printing */
|
/* see if jobs need printing */
|
||||||
|
|
|
@ -484,7 +484,7 @@ zhandler(int sig)
|
||||||
*procsubval = (0200 | WTERMSIG(status));
|
*procsubval = (0200 | WTERMSIG(status));
|
||||||
else
|
else
|
||||||
*procsubval = WEXITSTATUS(status);
|
*procsubval = WEXITSTATUS(status);
|
||||||
times(&shtms);
|
get_usage();
|
||||||
goto cont;
|
goto cont;
|
||||||
}
|
}
|
||||||
if (!es)
|
if (!es)
|
||||||
|
@ -514,7 +514,7 @@ zhandler(int sig)
|
||||||
* children in sub processes anyway: otherwise, this
|
* children in sub processes anyway: otherwise, this
|
||||||
* will get added on to the next found process that terminates.
|
* will get added on to the next found process that terminates.
|
||||||
*/
|
*/
|
||||||
times(&shtms);
|
get_usage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
11
Src/zsh.h
11
Src/zsh.h
|
@ -739,12 +739,21 @@ struct timeinfo {
|
||||||
|
|
||||||
/* node in job process lists */
|
/* node in job process lists */
|
||||||
|
|
||||||
|
#ifdef HAVE_GETRUSAGE
|
||||||
|
typedef struct {
|
||||||
|
struct timeval sys;
|
||||||
|
struct timeval usr;
|
||||||
|
} child_times_t;
|
||||||
|
#else
|
||||||
|
typedef struct timeinfo child_times_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct process {
|
struct process {
|
||||||
struct process *next;
|
struct process *next;
|
||||||
pid_t pid; /* process id */
|
pid_t pid; /* process id */
|
||||||
char text[JOBTEXTSIZE]; /* text to print when 'jobs' is run */
|
char text[JOBTEXTSIZE]; /* text to print when 'jobs' is run */
|
||||||
int status; /* return code from waitpid/wait3() */
|
int status; /* return code from waitpid/wait3() */
|
||||||
struct timeinfo ti;
|
child_times_t ti;
|
||||||
struct timeval bgtime; /* time job was spawned */
|
struct timeval bgtime; /* time job was spawned */
|
||||||
struct timeval endtime; /* time job exited */
|
struct timeval endtime; /* time job exited */
|
||||||
};
|
};
|
||||||
|
|
|
@ -1043,7 +1043,7 @@ AC_CHECK_FUNCS(strftime difftime gettimeofday \
|
||||||
initgroups nis_list \
|
initgroups nis_list \
|
||||||
setuid seteuid setreuid setresuid setsid \
|
setuid seteuid setreuid setresuid setsid \
|
||||||
memcpy memmove strstr strerror \
|
memcpy memmove strstr strerror \
|
||||||
getrlimit \
|
getrlimit getrusage \
|
||||||
setlocale \
|
setlocale \
|
||||||
uname \
|
uname \
|
||||||
signgam \
|
signgam \
|
||||||
|
|
Loading…
Reference in a new issue