Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Feature request: REPORTMEMORY



On Wed, 08 Jun 2016 12:44:36 -0700
Shaun Jackman <sjackman@xxxxxxxxx> wrote:
> The REPORTTIME feature of zsh is super useful. May I make a feature
> request for REPORTMEMORY? Reporting the peak RSS/VSIZE would be
> terribly useful, similar to GNU time.

This is fairly straightforward as long as we restrict ourselves to the
maximum RSS, which is available from getrusage() --- other values are
harder to get at and aren't supported on Linux even though they appear
in the structure so are hard to test for.  Presumably this is good
enough.

The value is in megabytes because that's the same as what the TIMEFMT %M
escape prints, though in principle the OS reports down to kilobytes
(what its actual granularity is is another matter).  Note you need to
add output of %M to TIMEFMT by hand --- I've documented this.

pws

diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo
index d23c459..b02d24e 100644
--- a/Doc/Zsh/params.yo
+++ b/Doc/Zsh/params.yo
@@ -1390,6 +1390,20 @@ item(tt(READNULLCMD) <S>)(
 The command name to assume if a single input redirection
 is specified with no command.  Defaults to tt(more).
 )
+vindex(REPORTMEMORY)
+item(tt(REPORTMEMORY))(
+If nonnegative, commands whose maximum resident set size (roughly
+speaking, main memory usage) in megabytes is greater than this
+value have timing statistics reported.  The format used to output
+statistics is the value of the tt(TIMEFMT) parameter, which is the same
+as for the tt(REPORTTIME) variable and the tt(time) builtin; note that
+by default this does not output memory usage.  Appending
+tt(" max RSS %M") to the value of tt(TIMEFMT) causes it to output the
+value that triggered the report.  If tt(REPORTTIME) is also in use,
+at most a single report is printed for both triggers.  This feature
+requires the tt(getrusage()) system call, commonly supported by modern
+Unix-like systems.
+)
 vindex(REPORTTIME)
 item(tt(REPORTTIME))(
 If nonnegative, commands whose combined user and system execution times
diff --git a/Src/jobs.c b/Src/jobs.c
index 04cb6b3..3db2ed0 100644
--- a/Src/jobs.c
+++ b/Src/jobs.c
@@ -884,37 +884,62 @@ should_report_time(Job j)
     struct value vbuf;
     Value v;
     char *s = "REPORTTIME";
-    zlong reporttime;
+    zlong reporttime = -1;
+#ifdef HAVE_GETRUSAGE
+    char *sm = "REPORTMEMORY";
+    zlong reportmemory = -1;
+#endif
 
     /* if the time keyword was used */
     if (j->stat & STAT_TIMED)
 	return 1;
 
     queue_signals();
-    if (!(v = getvalue(&vbuf, &s, 0)) ||
-	(reporttime = getintvalue(v)) < 0) {
-	unqueue_signals();
-	return 0;
-    }
+    if ((v = getvalue(&vbuf, &s, 0)))
+	reporttime = getintvalue(v);
+#ifdef HAVE_GETRUSAGE
+    if ((v = getvalue(&vbuf, &sm, 0)))
+	reportmemory = getintvalue(v);
+#endif
     unqueue_signals();
+    if (reporttime < 0
+#ifdef HAVE_GETRUSAGE
+	&& reportmemory < 0
+#endif
+	)
+	return 0;
     /* can this ever happen? */
     if (!j->procs)
 	return 0;
     if (zleactive)
 	return 0;
 
+    if (reporttime >= 0)
+    {
 #ifdef HAVE_GETRUSAGE
-    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;
+	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--;
+	if (reporttime <= 0)
+	    return 1;
 #else
-    {
-	clktck = get_clktck();
-	return ((j->procs->ti.ut + j->procs->ti.st) / clktck >= reporttime);
+	{
+	    clktck = get_clktck();
+	    if ((j->procs->ti.ut + j->procs->ti.st) / clktck >= reporttime)
+		return 1;
+	}
+#endif
     }
+
+#ifdef HAVE_GETRUSAGE
+    if (reportmemory >= 0 &&
+	j->procs->ti.ru_maxrss / 1024 > reportmemory)
+	return 1;
 #endif
+
+    return 0;
 }
 
 /* !(lng & 3) means jobs    *



Messages sorted by: Reverse Date, Date, Thread, Author