diff options
Diffstat (limited to 'Src/jobs.c')
-rw-r--r-- | Src/jobs.c | 110 |
1 files changed, 93 insertions, 17 deletions
diff --git a/Src/jobs.c b/Src/jobs.c index a24208759..0c3960e87 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -80,7 +80,15 @@ static int oldmaxjob; /* 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 */ @@ -93,8 +101,6 @@ int ttyfrozen; /**/ int prev_errflag, prev_breaks, errbrk_saved; -static struct timeval dtimeval, now; - /**/ int numpipestats, pipestats[MAX_PIPESTATS]; @@ -250,6 +256,21 @@ handle_sub(int job, int fg) 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 */ /**/ @@ -257,17 +278,31 @@ 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; - 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 */ +#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 */ - - gettimeofday(&pn->endtime, &dummy_tz); /* record time process exited */ +#endif } /* Update status of job, possibly printing it */ @@ -473,6 +508,8 @@ setprevjob(void) prevjob = -1; } +/**/ +#ifndef HAVE_GETRUSAGE static long clktck = 0; /**/ @@ -501,6 +538,8 @@ set_clktck(void) # endif #endif } +/**/ +#endif /**/ static void @@ -519,9 +558,8 @@ printhhmmss(double secs) fprintf(stderr, "%.3f", secs); } -/**/ static void -printtime(struct timeval *real, struct timeinfo *ti, char *desc) +printtime(struct timeval *real, child_times_t *ti, char *desc) { char *s; double elapsed_time, user_time, system_time; @@ -530,13 +568,21 @@ printtime(struct timeval *real, struct timeinfo *ti, char *desc) if (!desc) desc = ""; - set_clktck(); /* go ahead and compute these, since almost every TIMEFMT will have them */ 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; system_time = ti->st / (double) clktck; percent = 100.0 * (ti->ut + ti->st) / (clktck * real->tv_sec + clktck * real->tv_usec / 1000000.0); +#endif queue_signals(); if (!(s = getsparam("TIMEFMT"))) @@ -598,11 +644,13 @@ static void dumptime(Job jn) { Process pn; + struct timeval dtimeval; if (!jn->procs) return; 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 * @@ -617,7 +665,7 @@ should_report_time(Job j) struct value vbuf; Value v; char *s = "REPORTTIME"; - int reporttime; + zlong reporttime; /* if the time keyword was used */ if (j->stat & STAT_TIMED) @@ -634,8 +682,15 @@ should_report_time(Job j) if (!j->procs) 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(); return ((j->procs->ti.ut + j->procs->ti.st) / clktck >= reporttime); +#endif } /* !(lng & 3) means jobs * @@ -899,10 +954,9 @@ deletejob(Job jn) /**/ void -addproc(pid_t pid, char *text, int aux) +addproc(pid_t pid, char *text, int aux, struct timeval *bgtime) { Process pn, *pnlist; - struct timezone dummy_tz; DPUTS(thisjob == -1, "No valid job in addproc."); pn = (Process) zshcalloc(sizeof *pn); @@ -916,7 +970,7 @@ addproc(pid_t pid, char *text, int aux) if (!aux) { - gettimeofday(&pn->bgtime, &dummy_tz); + pn->bgtime = *bgtime; /* if this is the first process we are adding to * * the job, then it's the group leader. */ if (!jobtab[thisjob].gleader) @@ -1158,18 +1212,40 @@ spawnjob(void) void shelltime(void) { - struct timeinfo ti; 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; +#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); + ti.ut = buf.tms_utime; ti.st = buf.tms_stime; - gettimeofday(&now, &dummy_tz); +#endif 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.st = buf.tms_cstime; - printtime(dtime(&dtimeval, &shtimer, &now), &ti, "children"); +#endif + printtime(&dtimeval, &ti, "children"); + } /* see if jobs need printing */ |