From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3300 invoked by alias); 9 Jun 2016 10:25:46 -0000 Mailing-List: contact zsh-users-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Users List List-Post: List-Help: X-Seq: 21632 Received: (qmail 3423 invoked from network); 9 Jun 2016 10:25:44 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.1 X-AuditID: cbfec7f4-f796c6d000001486-f3-575941c71e76 Date: Thu, 09 Jun 2016 11:15:32 +0100 From: Peter Stephenson To: zsh-users@zsh.org Subject: Re: Feature request: REPORTMEMORY Message-id: <20160609111532.480f2810@pwslap01u.europe.root.pri> In-reply-to: References: Organization: Samsung Cambridge Solution Centre X-Mailer: Claws Mail 3.7.9 (GTK+ 2.22.0; i386-redhat-linux-gnu) MIME-version: 1.0 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7bit X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrALMWRmVeSWpSXmKPExsVy+t/xK7rHHSPDDY50KFrsOLmS0YHRY9XB D0wBjFFcNimpOZllqUX6dglcGc8nTWApWCxfsbm/l72B8YhEFyMnh4SAicS9zUuZIWwxiQv3 1rN1MXJxCAksZZR4M3MrM4QzjUni/NrH7BDOaUaJi6+fQGXOMEo0P1sC1s8ioCpxYNNxFhCb TcBQYuqm2YwgtoiAqMTyFZvZQWxhAS2JtocdQHEODl4Be4meZekgYU4BL4kfa2aDjRES8JT4 9HY/E4jNL6AvcfXvJyaI8+wlZl45AzaSV0BQ4sfke2CrmIFGbt7WxAphy0tsXvMWao66xI27 u9knMArPQtIyC0nLLCQtCxiZVzGKppYmFxQnpeca6hUn5haX5qXrJefnbmKEhPOXHYyLj1kd YhTgYFTi4dVMiQgXYk0sK67MPcQowcGsJML7wzwyXIg3JbGyKrUoP76oNCe1+BCjNAeLkjjv 3F3vQ4QE0hNLUrNTUwtSi2CyTBycUg2MadLSDUwG/CUy/DrHNX/fz5/79kXl4ql1IVU7G1jz 4sJfuZRKy3pIBiY0/941iaV/6uE6vsz53s9uHhX54buzTuOQfcpenZVttrN6Zvc2LZE1y5Sd YKtY+dTdUrmGa6WcZNtxj+0u2VvLbi0/02DnES38YlNF9QWL18V7/grZ9qqp7upfHanEUpyR aKjFXFScCADZj4o7YwIAAA== On Wed, 08 Jun 2016 12:44:36 -0700 Shaun Jackman 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) )( 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 *