From b06ee71b1d25c46c8338c4cb134344adc665836c Mon Sep 17 00:00:00 2001 From: Eric Jacobsen Date: Fri, 26 May 2017 20:33:30 -0700 Subject: [PATCH] Output memory as KB, MB, GB. Accept memory arguments as KB, MB, GB. --- README | 29 ++++++++++++++++------------- timeout | 36 ++++++++++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 17 deletions(-) diff --git a/README b/README index 4369080..2a4aa05 100644 --- a/README +++ b/README @@ -88,7 +88,9 @@ Advanced options: code or signal+128. This also makes timeout to wait until the controlled process is terminated. Without this option, the script returns zero. -* `--memlimit-rss`, `-s` - monitor RSS (resident set size) memory limit +* `--memlimit-rss`, `-s` - monitor RSS (resident set size) memory limit. +Memory limits may be specified as KB (default), MB, or GB. +E.g. 900KB, 100MB, 1.2GB More options may be read in the script itself. More documentation will be added in the future releases! @@ -108,26 +110,30 @@ EXAMPLES Since you already have Perl to run the script itself, the examples will utilize it. -Basic time limiting: +Basic CPU time limiting: ./timeout -t 2 perl -e 'while ($i<100000000) {$i++;}' Outputs: TIMEOUT 2.04 CPU -Basic memory limiting (100M of virtual memory): +Basic memory limiting (100MB of virtual memory): - ./timeout -m 1000000 perl -e 'while ($i<100000000) {$a->{$i} = $i++;}' + ./timeout -m 100MB perl -e 'while ($i<100000000) {$a->{$i} = $i++;}' Outputs: - MEM 8.55 + MEM CPU 0.41 MEM 119236 KB 116 MB 0 GB MAXMEM 119236 KB 116 MB 0 GB STALE 0 MAXMEM_RSS 100432 KB 98 MB 0 GB + -Limit both time and memory (adjust number to match the command above): +Limit both CPU time and memory (adjust number to match the command above). Note that the decision to kill the process is based on the logical OR of the limits: - ./timeout -m 1000000 -t 9 perl -e 'while ($i<100000000) {$x->{$i} = $i++;}' + ./timeout -m 100mb -t 2 perl -e 'while ($i<100000000) {$i++;}' Outputs: - MEM 8.57 - ./timeout -m 1000000 -t 8 perl -e 'while ($i<100000000) {$x->{$i} = $i++;}' + TIMEOUT CPU 2.05 MEM 20552 KB 20 MB 0 GB MAXMEM 20552 KB 20 MB 0 GB STALE 0 MAXMEM_RSS 1748 KB 1 MB 0 GB + + + ./timeout -m 100mb -t 9 perl -e 'while ($i<100000000) {$x->{$i} = $i++;}' Outputs: - TIMEOUT 8.02 CPU + MEM CPU 0.41 MEM 124252 KB 121 MB 0 GB MAXMEM 124252 KB 121 MB 0 GB STALE 0 MAXMEM_RSS 108616 KB 106 MB 0 GB + Limit time with a lot of short child processes: @@ -208,6 +214,3 @@ The script was initially developed in the Institute for System Programming of Russian Academy of Sciences (http://ispras.ru/en/) for Linux Driver Verification project (http://forge.ispras.ru/projects/ldv) in 2010-2011 by Pavel Shved with some contributions from Alexander Strakh. - - - diff --git a/timeout b/timeout index 7be8c90..6221cc8 100755 --- a/timeout +++ b/timeout @@ -23,7 +23,10 @@ sub usage{ print STDERR <\$kill_stale, # allow-hangups is kept for backward compatibility. 'allow-hangups!'=>\$kill_stale, - 'memlimit|m=i'=>\$memlimit, - 'memlimit-rss|s=i'=>\$memlimit_rss, + 'memlimit|m=s'=>\$memlimit, + 'memlimit-rss|s=s'=>\$memlimit_rss, 'frequency|x=i'=>\$frequency, 'pattern|p=s'=>\$strpat, 'output|o=s'=>\$output, @@ -76,6 +79,9 @@ GetOptions( @ARGV or usage; +$memlimit = parse_memory_arg($memlimit); +$memlimit_rss = parse_memory_arg($memlimit_rss); + my $uinfo = get_patterns($strpat); my $uwait = int (1_000_000 / $frequency); @@ -446,7 +452,7 @@ sub print_uinfo my $reason = shift; # Print generic information to STDERR my $ticks = $timeinfo->{ticks_stale} || 0; - printf STDERR "${id_str}%s CPU %.2f MEM %d MAXMEM %d STALE %d MAXMEM_RSS %d\n", $reason, $timeinfo->{total}, $meminfo, $maxmem, ceil($ticks/$frequency), $maxmem_rss if ($reason ne 'FINISHED') || $info_on_success; + printf STDERR "${id_str}%s CPU %.2f MEM %d KB %d MB %d GB MAXMEM %d KB %d MB %d GB STALE %d MAXMEM_RSS %d KB %d MB %d GB\n", $reason, $timeinfo->{total}, $meminfo, $meminfo/1024, $meminfo/1024/1024, $maxmem, $maxmem/1024, $maxmem/1024/1024, ceil($ticks/$frequency), $maxmem_rss, $maxmem_rss/1024, $maxmem_rss/1024/1024 if ($reason ne 'FINISHED') || $info_on_success; if (defined $output){ open(FIL,">>", $output) or die "Can't open output file: $!\n"; @@ -516,3 +522,25 @@ sub child_status_to_exit_code return $child_retv >> 8; } } + +# Allow memory arguments to specified as bytes, KB, MB, or GB. +sub parse_memory_arg +{ + my ($mem) = @_; + if (defined($mem)) { + if ($mem =~ /^\d+$/) { + $mem = int($mem); + } elsif ($mem =~ /(^\d*\.{0,1}\d*)kb$/i) { + $mem = int($1); + } elsif ($mem =~ /(^\d*\.{0,1}\d*)mb$/i) { + $mem = int($1*1024); + } elsif ($mem =~ /(^\d*\.{0,1}\d*)gb$/i) { + $mem = int($1*1024*1024); + } else { + print STDERR "Error: Unrecognized memory argument: '$mem'.\n"; + usage(); + } + printf STDERR "mem : %d KB = %.1f MB = %.1f GB\n", $mem, $mem/1024., $mem/1024./1024. if $debug; + } + return $mem; +}