about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--Doc/Zsh/params.yo14
-rw-r--r--Src/jobs.c53
3 files changed, 58 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog
index f6e70e50e..d5e7e588f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2016-06-13  Peter Stephenson  <p.stephenson@samsung.com>
+
+	* users/21632: Doc/Zsh/params.yo, Src/jobs.c: REPORTMEMORY
+	parameter gives minimum size to trigger usage report.
+
 2016-06-13  Daniel Shahaf  <d.s@daniel.shahaf.name>
 
 	* 38653 + 38657: Doc/Zsh/builtins.yo, Src/exec.c,
diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo
index d23c459a0..b02d24efe 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 04cb6b344..3db2ed01f 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    *