mirror of
https://git.savannah.gnu.org/git/parallel.git
synced 2024-11-22 05:57:54 +00:00
Merge branch 'master' of ssh://git.sv.gnu.org/srv/git/parallel
Conflicts: src/niceload
This commit is contained in:
commit
49675bf13a
|
@ -131,11 +131,15 @@ xargs or cat | sh.</description>
|
||||||
<implementation id="sha1new=f5da0850d901d05b9086bf5599d72ba30f7d9685" released="2012-08-23" version="20120822">
|
<implementation id="sha1new=f5da0850d901d05b9086bf5599d72ba30f7d9685" released="2012-08-23" version="20120822">
|
||||||
<manifest-digest sha256="98efd866ca5cf6737922d1caf3802488ce572fadd1b643161a3a0836d8ad1790"/>
|
<manifest-digest sha256="98efd866ca5cf6737922d1caf3802488ce572fadd1b643161a3a0836d8ad1790"/>
|
||||||
<archive extract="parallel-20120822" href="http://ftp.gnu.org/gnu/parallel/parallel-20120822.tar.bz2" size="231076"/>
|
<archive extract="parallel-20120822" href="http://ftp.gnu.org/gnu/parallel/parallel-20120822.tar.bz2" size="231076"/>
|
||||||
|
</implementation>
|
||||||
|
<implementation id="sha1new=7d21f515041cca4aab022a9f7a8bd059361a1fcd" released="2012-10-24" version="20121022">
|
||||||
|
<manifest-digest sha256="14105011185071fe5594d8ce6d796cf1c0d5d34ea375652042168fb8bebea032"/>
|
||||||
|
<archive extract="parallel-20121022" href="http://ftp.gnu.org/gnu/parallel/parallel-20121022.tar.bz2" size="235026"/>
|
||||||
</implementation>
|
</implementation>
|
||||||
</group>
|
</group>
|
||||||
</interface>
|
</interface>
|
||||||
<!-- Base64 Signature
|
<!-- Base64 Signature
|
||||||
iEYEABECAAYFAlBJscUACgkQ/lhgK1iJTtIllwCfUzLETjj1uAhhnACtzfx7zO58XTIAoJ4w4Q1i
|
iEYEABECAAYFAlCH1LMACgkQ/lhgK1iJTtINFACgrOo8ssOGhN0sbogDT0AIGcfi1cIAniXIY3UV
|
||||||
UwqAavHsNrAVB2F3M3jA
|
MisLNJCa/+zhAHH8baOA
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
|
115
src/niceload
115
src/niceload
|
@ -59,6 +59,8 @@ if(not defined $::opt_run_mem) { $::opt_run_mem = $::opt_mem; }
|
||||||
if(not defined $::opt_start_noswap) { $::opt_start_noswap = $::opt_noswap; }
|
if(not defined $::opt_start_noswap) { $::opt_start_noswap = $::opt_noswap; }
|
||||||
if(not defined $::opt_run_noswap) { $::opt_run_noswap = $::opt_noswap; }
|
if(not defined $::opt_run_noswap) { $::opt_run_noswap = $::opt_noswap; }
|
||||||
|
|
||||||
|
if(defined $::opt_load) { multiply_binary_prefix($::opt_load); }
|
||||||
|
|
||||||
my $limit = Limit->new();
|
my $limit = Limit->new();
|
||||||
my $process = Process->new($::opt_nice,@ARGV);
|
my $process = Process->new($::opt_nice,@ARGV);
|
||||||
if($::opt_pid) {
|
if($::opt_pid) {
|
||||||
|
@ -89,6 +91,37 @@ while($process->is_alive()) {
|
||||||
|
|
||||||
exit($::exitstatus);
|
exit($::exitstatus);
|
||||||
|
|
||||||
|
sub multiply_binary_prefix {
|
||||||
|
# Evalualte numbers with binary prefix
|
||||||
|
# k=10^3, m=10^6, g=10^9, t=10^12, p=10^15, e=10^18, z=10^21, y=10^24
|
||||||
|
# K=2^10, M=2^20, G=2^30, T=2^40, P=2^50, E=2^70, Z=2^80, Y=2^80
|
||||||
|
# Ki=2^10, Mi=2^20, Gi=2^30, Ti=2^40, Pi=2^50, Ei=2^70, Zi=2^80, Yi=2^80
|
||||||
|
# ki=2^10, mi=2^20, gi=2^30, ti=2^40, pi=2^50, ei=2^70, zi=2^80, yi=2^80
|
||||||
|
# 13G = 13*1024*1024*1024 = 13958643712
|
||||||
|
my $s = shift;
|
||||||
|
$s =~ s/k/*1000/g;
|
||||||
|
$s =~ s/M/*1000*1000/g;
|
||||||
|
$s =~ s/G/*1000*1000*1000/g;
|
||||||
|
$s =~ s/T/*1000*1000*1000*1000/g;
|
||||||
|
$s =~ s/P/*1000*1000*1000*1000*1000/g;
|
||||||
|
$s =~ s/E/*1000*1000*1000*1000*1000*1000/g;
|
||||||
|
$s =~ s/Z/*1000*1000*1000*1000*1000*1000*1000/g;
|
||||||
|
$s =~ s/Y/*1000*1000*1000*1000*1000*1000*1000*1000/g;
|
||||||
|
$s =~ s/X/*1000*1000*1000*1000*1000*1000*1000*1000*1000/g;
|
||||||
|
|
||||||
|
$s =~ s/Ki?/*1024/gi;
|
||||||
|
$s =~ s/Mi?/*1024*1024/gi;
|
||||||
|
$s =~ s/Gi?/*1024*1024*1024/gi;
|
||||||
|
$s =~ s/Ti?/*1024*1024*1024*1024/gi;
|
||||||
|
$s =~ s/Pi?/*1024*1024*1024*1024*1024/gi;
|
||||||
|
$s =~ s/Ei?/*1024*1024*1024*1024*1024*1024/gi;
|
||||||
|
$s =~ s/Zi?/*1024*1024*1024*1024*1024*1024*1024/gi;
|
||||||
|
$s =~ s/Yi?/*1024*1024*1024*1024*1024*1024*1024*1024/gi;
|
||||||
|
$s =~ s/Xi?/*1024*1024*1024*1024*1024*1024*1024*1024*1024/gi;
|
||||||
|
$s = eval $s;
|
||||||
|
return $s;
|
||||||
|
}
|
||||||
|
|
||||||
sub get_options_from_array {
|
sub get_options_from_array {
|
||||||
# Run GetOptions on @array
|
# Run GetOptions on @array
|
||||||
# Returns:
|
# Returns:
|
||||||
|
@ -229,24 +262,6 @@ sub version {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sub multiply_binary_prefix {
|
|
||||||
# Evalualte numbers with binary prefix
|
|
||||||
# 13G = 13*1024*1024*1024 = 13958643712
|
|
||||||
my $s = shift;
|
|
||||||
$s =~ s/Ki?/*1024/gi;
|
|
||||||
$s =~ s/Mi?/*1024*1024/gi;
|
|
||||||
$s =~ s/Gi?/*1024*1024*1024/gi;
|
|
||||||
$s =~ s/Ti?/*1024*1024*1024*1024/gi;
|
|
||||||
$s =~ s/Pi?/*1024*1024*1024*1024*1024/gi;
|
|
||||||
$s =~ s/Ei?/*1024*1024*1024*1024*1024*1024/gi;
|
|
||||||
$s =~ s/Zi?/*1024*1024*1024*1024*1024*1024*1024/gi;
|
|
||||||
$s =~ s/Yi?/*1024*1024*1024*1024*1024*1024*1024*1024/gi;
|
|
||||||
$s =~ s/Xi?/*1024*1024*1024*1024*1024*1024*1024*1024*1024/gi;
|
|
||||||
$s = eval $s;
|
|
||||||
return $s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub max {
|
sub max {
|
||||||
# Returns:
|
# Returns:
|
||||||
# Maximum value of array
|
# Maximum value of array
|
||||||
|
@ -545,7 +560,7 @@ sub sleep_while_running {
|
||||||
sub nonblockGetLines {
|
sub nonblockGetLines {
|
||||||
# An non-blocking filehandle read that returns an array of lines read
|
# An non-blocking filehandle read that returns an array of lines read
|
||||||
# Returns: ($eof,@lines)
|
# Returns: ($eof,@lines)
|
||||||
|
# Example: --sensor 'vmstat 1 | perl -ane '\''$|=1; 4..0 and print $F[8],"\n"'\'
|
||||||
my ($fh,$timeout) = @_;
|
my ($fh,$timeout) = @_;
|
||||||
|
|
||||||
$timeout = 0 unless defined $timeout;
|
$timeout = 0 unless defined $timeout;
|
||||||
|
@ -559,54 +574,66 @@ sub nonblockGetLines {
|
||||||
return unless vec($rfd,fileno($fh),1);
|
return unless vec($rfd,fileno($fh),1);
|
||||||
my $buf = '';
|
my $buf = '';
|
||||||
my $n = sysread($fh,$buf,1024*1024);
|
my $n = sysread($fh,$buf,1024*1024);
|
||||||
|
|
||||||
|
my $eof = eof($fh);
|
||||||
# If we're done, make sure to send the last unfinished line
|
# If we're done, make sure to send the last unfinished line
|
||||||
return (1,$::nonblockGetLines_last{$fh}) unless $n;
|
return ($eof,$::nonblockGetLines_last{$fh}) unless $n;
|
||||||
# Prepend the last unfinished line
|
# Prepend the last unfinished line
|
||||||
$buf = $::nonblockGetLines_last{$fh}.$buf;
|
$buf = $::nonblockGetLines_last{$fh}.$buf;
|
||||||
# And save any newly unfinished lines
|
# And save any newly unfinished lines
|
||||||
$::nonblockGetLines_last{$fh} =
|
$::nonblockGetLines_last{$fh} =
|
||||||
(substr($buf,-1) !~ /[\r\n]/ && $buf =~ s/([^\r\n]*)$//)
|
(substr($buf,-1) !~ /[\r\n]/ && $buf =~ s/([^\r\n]*)$//)
|
||||||
? $1 : '';
|
? $1 : '';
|
||||||
$buf ? (0,split(/\n/,$buf)) : (0);
|
$buf ? ($eof,split(/\n/,$buf)) : ($eof);
|
||||||
}
|
}
|
||||||
|
|
||||||
# --sensor 'vmstat 1 | perl -ane '\''$|=1; 4..0 and print $F[8],"\n"'\'
|
sub read_sensor {
|
||||||
|
my $self = shift;
|
||||||
|
my $fh = $self->{'sensor_fh'};
|
||||||
|
if(not $fh) {
|
||||||
|
# Start the sensor
|
||||||
|
open($fh, "-|", $::opt_sensor) || ::die_bug("Cannot open: $::opt_sensor");
|
||||||
|
$self->{'sensor_fh'} = $fh;
|
||||||
|
}
|
||||||
|
# Read as much as we can (non_block)
|
||||||
|
my ($eof,@lines) = nonblockGetLines($fh);
|
||||||
|
|
||||||
|
# new load = last full line
|
||||||
|
foreach my $line ( @lines ) {
|
||||||
|
if(defined $line) {
|
||||||
|
print "Pipe saw: $eof [$line]\n";
|
||||||
|
$Global::last_sensor_reading = $line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($eof) { undef($self->{'sensor_fh'}); }
|
||||||
|
|
||||||
|
return $Global::last_sensor_reading;
|
||||||
|
}
|
||||||
|
|
||||||
sub load_status {
|
sub load_status {
|
||||||
# Returns:
|
# Returns:
|
||||||
# loadavg or sensor measurement
|
# loadavg or sensor measurement
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
if($::opt_sensor) {
|
if($::opt_sensor) {
|
||||||
my $fh = $self->{'sensor_fh'};
|
if(not defined $self->{'load_status'} or
|
||||||
if(not defined $fh) {
|
$self->{'load_status_cache_time'} + $self->{'recheck'} < time) {
|
||||||
# Start the sensor
|
$self->{'load_status'} = $self->read_sensor();
|
||||||
::debug("start: $::opt_sensor\n");
|
while (not defined $self->{'load_status'}) {
|
||||||
open($fh, "-|", $::opt_sensor) || ::die_bug("Cannot open: $::opt_sensor");
|
sleep 1;
|
||||||
$self->{'sensor_fh'} = $fh;
|
$self->{'load_status'} = $self->read_sensor();
|
||||||
}
|
}
|
||||||
::debug("sensor: $::opt_sensor");
|
$self->{'load_status_cache_time'} = time;
|
||||||
# Read as much as we can (block for up to 0.02 seconds)
|
|
||||||
my ($eof,@lines) = nonblockGetLines($fh,0.2);
|
|
||||||
my $newval = pop @lines;
|
|
||||||
::debug(" = $newval\n");
|
|
||||||
if(defined $newval) {
|
|
||||||
$newval =~ s/\D*([0-9.]*)(\D.*)?$/$1/;
|
|
||||||
$self->{'load_status'} = undef_as_zero($newval);
|
|
||||||
}
|
|
||||||
if($eof) {
|
|
||||||
close($fh);
|
|
||||||
undef $self->{'sensor_fh'};
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
# Normal load avg
|
# Normal load avg
|
||||||
# Cache for some seconds
|
# Cache for some seconds
|
||||||
if(not defined $self->{'load_status'} or
|
if(not defined $self->{'load_status'} or
|
||||||
$self->{'load_status_cache_time'}+$self->{'recheck'} < time) {
|
$self->{'load_status_cache_time'} + $self->{'recheck'} < time) {
|
||||||
$self->{'load_status'} = load_status_linux();
|
$self->{'load_status'} = load_status_linux();
|
||||||
$self->{'load_status_cache_time'} = time;
|
$self->{'load_status_cache_time'} = time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
::debug("load_status: $self->{'load_status'}\n");
|
::debug("load_status: ".$self->{'load_status'}."\n");
|
||||||
return $self->{'load_status'};
|
return $self->{'load_status'};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -629,7 +656,7 @@ sub load_status_linux {
|
||||||
close IN;
|
close IN;
|
||||||
} elsif (open(IN,"uptime|")) {
|
} elsif (open(IN,"uptime|")) {
|
||||||
my $upString = <IN>;
|
my $upString = <IN>;
|
||||||
if($upString =~ m/average.\s*(\d+\.\d+)/) {
|
if($upString =~ m/averages?.\s*(\d+\.\d+)/) {
|
||||||
$loadavg = $1;
|
$loadavg = $1;
|
||||||
} else {
|
} else {
|
||||||
::die_bug("uptime");
|
::die_bug("uptime");
|
||||||
|
|
|
@ -7,7 +7,8 @@ niceload - slow down a program when the load average is above a certain limit
|
||||||
=head1 SYNOPSIS
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
B<niceload> [-v] [-h] [-n nice] [-I io] [-L load] [-M mem] [-N]
|
B<niceload> [-v] [-h] [-n nice] [-I io] [-L load] [-M mem] [-N]
|
||||||
[-t time] [-s time|-f factor] ( command | -p PID )
|
[--sensor program] [-t time] [-s time|-f factor] ( command | -p PID )
|
||||||
|
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
|
@ -131,6 +132,19 @@ Run limit. The running program will be slowed down if the system is
|
||||||
above the limit. See: B<--io>, B<--load>, B<--mem>, B<--noswap>.
|
above the limit. See: B<--io>, B<--load>, B<--mem>, B<--noswap>.
|
||||||
|
|
||||||
|
|
||||||
|
=item B<--sensor> I<sensor program> (alpha testing)
|
||||||
|
|
||||||
|
Read sensor. Use I<sensor program> to read a sensor.
|
||||||
|
|
||||||
|
This will keep the CPU temperature below 80 deg C on GNU/Linux:
|
||||||
|
|
||||||
|
niceload -l 80000 -f 0.001 --sensor 'sort -n /sys/devices/platform/coretemp*/temp*_input' gzip *
|
||||||
|
|
||||||
|
This will stop if the disk space < 100000.
|
||||||
|
|
||||||
|
niceload -H -l -100000 --sensor "df . | awk '{ print \$4 }'" echo
|
||||||
|
|
||||||
|
|
||||||
=item B<--start-io> I<iolimit>
|
=item B<--start-io> I<iolimit>
|
||||||
|
|
||||||
=item B<--si> I<iolimit>
|
=item B<--si> I<iolimit>
|
||||||
|
|
|
@ -17,7 +17,7 @@ niceload - slow down a program when the load average is above a certain limit
|
||||||
@anchor{SYNOPSIS}
|
@anchor{SYNOPSIS}
|
||||||
|
|
||||||
@strong{niceload} [-v] [-h] [-n nice] [-I io] [-L load] [-M mem] [-N]
|
@strong{niceload} [-v] [-h] [-n nice] [-I io] [-L load] [-M mem] [-N]
|
||||||
[-t time] [-s time|-f factor] ( command | -p PID )
|
[--sensor program] [-t time] [-s time|-f factor] ( command | -p PID )
|
||||||
|
|
||||||
@chapter DESCRIPTION
|
@chapter DESCRIPTION
|
||||||
@anchor{DESCRIPTION}
|
@anchor{DESCRIPTION}
|
||||||
|
@ -156,6 +156,23 @@ $, >, and " that should not be interpreted by the shell.
|
||||||
Run limit. The running program will be slowed down if the system is
|
Run limit. The running program will be slowed down if the system is
|
||||||
above the limit. See: @strong{--io}, @strong{--load}, @strong{--mem}, @strong{--noswap}.
|
above the limit. See: @strong{--io}, @strong{--load}, @strong{--mem}, @strong{--noswap}.
|
||||||
|
|
||||||
|
@item @strong{--sensor} @emph{sensor program} (alpha testing)
|
||||||
|
@anchor{@strong{--sensor} @emph{sensor program} (alpha testing)}
|
||||||
|
|
||||||
|
Read sensor. Use @emph{sensor program} to read a sensor.
|
||||||
|
|
||||||
|
This will keep the CPU temperature below 80 deg C on GNU/Linux:
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
niceload -l 80000 -f 0.001 --sensor 'sort -n /sys/devices/platform/coretemp*/temp*_input' gzip *
|
||||||
|
@end verbatim
|
||||||
|
|
||||||
|
This will stop if the disk space < 100000.
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
niceload -H -l -100000 --sensor "df . | awk '{ print \$4 }'" echo
|
||||||
|
@end verbatim
|
||||||
|
|
||||||
@item @strong{--start-io} @emph{iolimit}
|
@item @strong{--start-io} @emph{iolimit}
|
||||||
@anchor{@strong{--start-io} @emph{iolimit}}
|
@anchor{@strong{--start-io} @emph{iolimit}}
|
||||||
|
|
||||||
|
|
|
@ -2395,7 +2395,7 @@ sub loadavg {
|
||||||
my $uptime_out = <$uptime_fh>;
|
my $uptime_out = <$uptime_fh>;
|
||||||
close $uptime_fh;
|
close $uptime_fh;
|
||||||
# load average: 0.76, 1.53, 1.45
|
# load average: 0.76, 1.53, 1.45
|
||||||
if($uptime_out =~ /load average: (\d+.\d+)/) {
|
if($uptime_out =~ /load averages?: (\d+.\d+)/) {
|
||||||
$self->{'loadavg'} = $1;
|
$self->{'loadavg'} = $1;
|
||||||
::debug("New loadavg: ".$self->{'loadavg'});
|
::debug("New loadavg: ".$self->{'loadavg'});
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in a new issue