From ab1fe956eaf87e79ce4d66d9f9f7a2f7091006d3 Mon Sep 17 00:00:00 2001 From: Ole Tange Date: Tue, 19 Jul 2011 16:44:14 +0200 Subject: [PATCH] niceload: --run-* --start-* --io implemented. Testsuite extended (untested). man page updated. --- configure | 20 +- configure.ac | 2 +- doc/release_new_version | 26 +- src/Makefile.am | 2 +- src/Makefile.in | 2 +- src/niceload | 448 +++++++-------------------- src/niceload.pod | 342 ++++++++++++++++++++ src/parallel | 2 +- src/sql | 2 +- testsuite/tests-to-run/niceload01.sh | 48 +++ 10 files changed, 538 insertions(+), 356 deletions(-) create mode 100644 src/niceload.pod diff --git a/configure b/configure index 1def2cca..1055689c 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for parallel 20110622. +# Generated by GNU Autoconf 2.68 for parallel 20110718. # # Report bugs to . # @@ -559,8 +559,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='parallel' PACKAGE_TARNAME='parallel' -PACKAGE_VERSION='20110622' -PACKAGE_STRING='parallel 20110622' +PACKAGE_VERSION='20110718' +PACKAGE_STRING='parallel 20110718' PACKAGE_BUGREPORT='bug-parallel@gnu.org' PACKAGE_URL='' @@ -1176,7 +1176,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures parallel 20110622 to adapt to many kinds of systems. +\`configure' configures parallel 20110718 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1242,7 +1242,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of parallel 20110622:";; + short | recursive ) echo "Configuration of parallel 20110718:";; esac cat <<\_ACEOF @@ -1309,7 +1309,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -parallel configure 20110622 +parallel configure 20110718 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1326,7 +1326,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by parallel $as_me 20110622, which was +It was created by parallel $as_me 20110718, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2141,7 +2141,7 @@ fi # Define the identity of the package. PACKAGE='parallel' - VERSION='20110622' + VERSION='20110718' cat >>confdefs.h <<_ACEOF @@ -2704,7 +2704,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by parallel $as_me 20110622, which was +This file was extended by parallel $as_me 20110718, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -2766,7 +2766,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -parallel config.status 20110622 +parallel config.status 20110718 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 4b398b8e..772129c7 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([parallel], [20110622], [bug-parallel@gnu.org]) +AC_INIT([parallel], [20110719], [bug-parallel@gnu.org]) AM_INIT_AUTOMAKE([-Wall -Werror foreign]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_FILES([ diff --git a/doc/release_new_version b/doc/release_new_version index 555fe9d1..301c98a7 100644 --- a/doc/release_new_version +++ b/doc/release_new_version @@ -178,27 +178,30 @@ available for download at: http://ftp.gnu.org/gnu/parallel/ New in this release: -* niceload: --noswap will slow down a program if the computer is - swapping. - -* niceload: --mem will slow down a program if free memory goes below a - certain limit. - * niceload: --hard will suspend a program if a limit is reached - as opposed to just slowing the program down. * niceload: --soft will slowing the program down - as opposed to suspending the program completely. -( -* niceload: --io will slow down a program if disk io goes above a +* niceload: --run-io will slow down a program if disk io goes above a certain limit. -* niceload: --start-load, --start-noswap, --start-mem, --start-io will +* niceload: --run-load will slow down a program if loadaverage goes + above a certain limit. + +* niceload: --run-mem will slow down a program if free memory goes + below a certain limit. + +* niceload: --run-noswap will slow down a program if the computer is + swapping. + +* niceload: --start-io, --start-load, --start-mem, --start-noswap will defer starting a program until the system is below the limit. +* --io, --load, --mem, and --noswap sets both --run-* and --start-*. + * niceload got a major rewrite and is now object oriented. -) * GNU Parallel was presented at Nordic Perl Workshop 2011. http://conferences.yapceurope.org/npw2011/talk/3416 @@ -210,6 +213,9 @@ New in this release: http://d.hatena.ne.jp/negima1976/20110607/1307412660 http://d.hatena.ne.jp/negima1976/20110628/1309252494 +* Blog post for bioinformatics. Thanks to Chris Miller. + http://chrisamiller.com/science/2010/05/26/use-parallel-for-easy-multi-processor-execution/ + * Bug fixes and man page updates. diff --git a/src/Makefile.am b/src/Makefile.am index b474074b..75d02bee 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -16,7 +16,7 @@ sql.1: sql Makefile niceload.1: niceload Makefile pod2man --release='$(PACKAGE_VERSION)' --center='$(PACKAGE_NAME)' \ - --section=1 $(srcdir)/niceload > $(srcdir)/niceload.1 + --section=1 $(srcdir)/niceload.pod > $(srcdir)/niceload.1 parallel.html: parallel Makefile sem ./sem --fg --id pod2html pod2html $(srcdir)/parallel.pod > $(srcdir)/parallel.html diff --git a/src/Makefile.in b/src/Makefile.in index cf9d0552..a105edf6 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -461,7 +461,7 @@ sql.1: sql Makefile niceload.1: niceload Makefile pod2man --release='$(PACKAGE_VERSION)' --center='$(PACKAGE_NAME)' \ - --section=1 $(srcdir)/niceload > $(srcdir)/niceload.1 + --section=1 $(srcdir)/niceload.pod > $(srcdir)/niceload.1 parallel.html: parallel Makefile sem ./sem --fg --id pod2html pod2html $(srcdir)/parallel.pod > $(srcdir)/parallel.html diff --git a/src/niceload b/src/niceload index 8b35420d..a90534f0 100755 --- a/src/niceload +++ b/src/niceload @@ -1,302 +1,9 @@ #!/usr/bin/perl -w -=head1 NAME - -niceload - slow down a program when the load average is above a certain limit - -=head1 SYNOPSIS - -B [-v] [-n nice] [-l load] [-t time] [-s time|-f factor] command - -B [-v] [-h] [-n nice] [-l load] [-t time] [-s time|-f factor] -p=PID - -=head1 DESCRIPTION - -GNU B will slow down a program when the load average is -above a certain limit. When the limit is reached the program will be -suspended for some time. Then resumed again for some time. Then the -load average is checked again and we start over. - -If the load is 3.00 then the default settings will run a program -like this: - -run 1 second, suspend (3.00-1.00) seconds, run 1 second, suspend -(3.00-1.00) seconds, run 1 second, ... - -=head1 OPTIONS - -=over 9 - -=item B<-f> I - -=item B<--factor> I - -Suspend time factor. Dynamically set B<-s> as max load average over -limit * factor. Default is 1. - - -=item B<-H> - -=item B<--hard> - -Hard limit. B<--hard> will suspend the process until the system is -under the limits. The default is B<--soft>. - - -=item B<-l> I - -=item B<--load> I - -Max load. The maximal load average before suspending command. Default -is 1.00. - - -=item B<--rm> I - -=item B<--runmem> I - -Required free mem. I is computed as free memory + cache. - -I can be postfixed with K, M, G, T, or P which would multiply the -size with 1024, 1048576, 1073741824, or 1099511627776 respectively. - - -=item B<-n> I - -=item B<--nice> I - -Sets niceness. See B(1). - - -=item B<-N> - -=item B<--noswap> - -Do not start new jobs on a given computer if there is both swap-in and -swap-out activity. - -Swap activity is computed as (swap-in)*(swap-out) which in practice is -a good value: swapping out is not a problem, swapping in is not a -problem, but both swapping in and out usually indicates a problem. - - -=item B<-p> I - -=item B<--pid> I - -Process ID of process to suspend. - - -=item B<-s> I - -=item B<--suspend> I - -Suspend time. Suspend the command this many seconds when the max load -average is reached. - - -=item B<-S> - -=item B<--soft> - -Soft limit. B will suspend a process for a while and then -let it run for a second thus only slowing down a process while the -system is over one of the given limits. This is the default. - - -=item B<-t> I - -=item B<--recheck> I - -Recheck load time. Sleep SEC seconds before checking load -again. Default is 1 second. - - -=item B<-v> - -=item B<--verbose> - -Verbose. Print some extra output on what is happening. Use B<-v> until -you know what your are doing. - -=back - -=head1 EXAMPLE: See niceload in action - -In terminal 1 run: top - -In terminal 2 run: - -B>B<50)'> - -This will print a '.' every second for 50 seconds and eat a lot of -CPU. When the load rises to 1.0 the process is suspended. - - -=head1 EXAMPLE: Run updatedb - -Running updatedb can often starve the system for disk I/O and thus result in a high load. - -Run updatedb but suspend updatedb if the load is above 2.00: - -B - - -=head1 EXAMPLE: Run rsync - -rsync can just like updatedb starve the system for disk I/O and thus result in a high load. - -Run rsync but keep load below 3.4. If load reaches 7 sleep for -(7-3.4)*12 seconds: - -B - - -=head1 ENVIRONMENT VARIABLES - -None. In future versions $NICELOAD will be able to contain default settings. - -=head1 EXIT STATUS - -Exit status should be the same as the command being run (untested). - -=head1 REPORTING BUGS - -Report bugs to . - -=head1 AUTHOR - -Copyright (C) 2004-11-19 Ole Tange, http://ole.tange.dk - -Copyright (C) 2005,2006,2006,2008,2009,2010 Ole Tange, http://ole.tange.dk - -Copyright (C) 2010,2011 Ole Tange, http://ole.tange.dk and Free -Software Foundation, Inc. - -=head1 LICENSE - -Copyright (C) 2010 Free Software Foundation, Inc. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3 of the License, or -at your option any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -=head2 Documentation license I - -Permission is granted to copy, distribute and/or modify this documentation -under the terms of the GNU Free Documentation License, Version 1.3 or -any later version published by the Free Software Foundation; with no -Invariant Sections, with no Front-Cover Texts, and with no Back-Cover -Texts. A copy of the license is included in the file fdl.txt. - -=head2 Documentation license II - -You are free: - -=over 9 - -=item B - -to copy, distribute and transmit the work - -=item B - -to adapt the work - -=back - -Under the following conditions: - -=over 9 - -=item B - -You must attribute the work in the manner specified by the author or -licensor (but not in any way that suggests that they endorse you or -your use of the work). - -=item B - -If you alter, transform, or build upon this work, you may distribute -the resulting work only under the same, similar or a compatible -license. - -=back - -With the understanding that: - -=over 9 - -=item B - -Any of the above conditions can be waived if you get permission from -the copyright holder. - -=item B - -Where the work or any of its elements is in the public domain under -applicable law, that status is in no way affected by the license. - -=item B - -In no way are any of the following rights affected by the license: - -=over 2 - -=item * - -Your fair dealing or fair use rights, or other applicable -copyright exceptions and limitations; - -=item * - -The author's moral rights; - -=item * - -Rights other persons may have either in the work itself or in -how the work is used, such as publicity or privacy rights. - -=back - -=back - -=over 9 - -=item B - -For any reuse or distribution, you must make clear to others the -license terms of this work. - -=back - -A copy of the full license is included in the file as cc-by-sa.txt. - -=head1 DEPENDENCIES - -GNU B uses Perl, and the Perl modules POSIX, and -Getopt::Long. - -=head1 SEE ALSO - -B(1), B(1) - - -=cut - use strict; use Getopt::Long; $Global::progname="niceload"; -$Global::version = 20110718; +$Global::version = 20110719; Getopt::Long::Configure("bundling","require_order"); get_options_from_array(\@ARGV) || die_usage(); if($::opt_version) { @@ -312,6 +19,22 @@ if($::opt_factor and $::opt_suspend) { help(); exit; } +if(not (defined $::opt_start_io or defined $::opt_run_io + or defined $::opt_start_load or defined $::opt_run_load + or defined $::opt_start_mem or defined $::opt_run_mem + or defined $::opt_start_noswap or defined $::opt_run_noswap)) { + # Default is --runload=1 + $::opt_run_load = 1; +} + +if(not defined $::opt_start_io) { $::opt_start_io = $::opt_io; } +if(not defined $::opt_run_io) { $::opt_run_io = $::opt_io; } +if(not defined $::opt_start_load) { $::opt_start_load = $::opt_load; } +if(not defined $::opt_run_load) { $::opt_run_load = $::opt_load; } +if(not defined $::opt_start_mem) { $::opt_start_mem = $::opt_mem; } +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_run_noswap) { $::opt_run_noswap = $::opt_noswap; } sub get_options_from_array { # Run GetOptions on @array @@ -332,14 +55,27 @@ sub get_options_from_array { ("debug|D" => \$::opt_debug, "factor|f=s" => \$::opt_factor, "hard|H" => \$::opt_hard, - "load|l=s" => \$::opt_load, + "soft|S" => \$::opt_soft, + + "si|sio|startio|start-io=s" => \$::opt_start_io, + "ri|rio|runio|run-io=s" => \$::opt_run_io, + "io|I=s" => \$::opt_io, + + "sl|startload|start-load=s" => \$::opt_start_load, + "rl|runload|run-load=s" => \$::opt_run_load, + "load|L|l=s" => \$::opt_load, + "sm|startmem|start-mem=s" => \$::opt_start_mem, "rm|runmem|run-mem=s" => \$::opt_run_mem, - "nice|n=i" => \$::opt_nice, + "mem|M=s" => \$::opt_mem, + + "sn|startnoswap|start-noswap|start-no-swap" => \$::opt_start_noswap, + "rn|runnoswap|run-noswap|run-no-swap" => \$::opt_run_noswap, "noswap|N" => \$::opt_noswap, + + "nice|n=i" => \$::opt_nice, "process|pid|p=s" => \$::opt_pid, "suspend|s=s" => \$::opt_suspend, - "soft|S" => \$::opt_soft, "recheck|t=s" => \$::opt_recheck, "help|h" => \$::opt_help, "verbose|v" => \$::opt_verbose, @@ -360,8 +96,8 @@ sub die_usage { sub help { print q{ Usage: - niceload [-v] [-n=niceness] [-l=loadavg] [-t=recheck_sec] - [-s=suspend_sec|-f=factor] [-H] [-S] + niceload [-v] [-n niceness] [-L loadavg] [-I io] [-N] [-M mem] + [-s suspend_sec|-f factor] [-H] [-S] command or -p pid }; } @@ -415,7 +151,7 @@ sub version { "Web site: http://www.gnu.org/software/parallel\n" ); } - + sub multiply_binary_prefix { # Evalualte numbers with binary prefix # 13G = 13*1024*1024*1024 = 13958643712 @@ -450,7 +186,7 @@ my $limit = Limit->new(); my $process = Process->new($::opt_nice,@ARGV); if(not $::opt_pid) { # Wait until limit is below start_limit and run_limit - while($limit->over_start_limit() + while($limit->over_start_limit() or ($limit->hard() and $limit->over_run_limit())) { $limit->sleep_for_recheck(); @@ -492,7 +228,7 @@ sub start { ::debug("Starting @{$self->{'command'}}\n"); if($self->{'pid'} = fork) { # set signal handler to kill children if parent is killed - push @{$self->{'pids'}}, $self->{'pid'}; + push @{$self->{'pids'}}, $self->{'pid'}; $Global::process = $self; $SIG{CHLD} = \&REAPER; $SIG{INT}=\&kill_child_INT; @@ -576,17 +312,27 @@ sub new { my $class = shift; my %limits = @_; my $hard = $::opt_soft ? 0 : $::opt_hard; - my $startmem = $::opt_start_mem ? ::multiply_binary_prefix($::opt_start_mem) : 0; + my $runio = $::opt_run_io ? ::multiply_binary_prefix($::opt_run_io) : 0; + my $startio = $::opt_start_io ? ::multiply_binary_prefix($::opt_start_io) : 0; + my $runload = $::opt_run_load ? ::multiply_binary_prefix($::opt_run_load) : 0; + my $startload = $::opt_start_load ? ::multiply_binary_prefix($::opt_start_load) : 0; my $runmem = $::opt_run_mem ? ::multiply_binary_prefix($::opt_run_mem) : 0; + my $startmem = $::opt_start_mem ? ::multiply_binary_prefix($::opt_start_mem) : 0; + my $runnoswap = $::opt_run_noswap ? ::multiply_binary_prefix($::opt_run_noswap) : 0; + my $startnoswap = $::opt_start_noswap ? ::multiply_binary_prefix($::opt_start_noswap) : 0; return bless { 'hard' => $hard, 'recheck' => 1, # Default 'runtime' => 1, # Default - 'load' => $::opt_load, - 'startmem' => $startmem, + 'runio' => $runio, + 'startio' => $startio, + 'runload' => $runload, + 'startload' => $startload, 'runmem' => $runmem, - 'swap' => $::opt_noswap, + 'startmem' => $startmem, + 'runnoswap' => $runnoswap, + 'startnoswap' => $startnoswap, 'factor' => $::opt_factor || 1, 'recheck' => $::opt_recheck || 1, 'runtime' => 1, @@ -609,7 +355,23 @@ sub over_run_limit { ::debug("Run memory: $self->{'runmem'}/$mem\n"); $status += (::max(1,$self->{'runmem'}/$mem)-1); } - $status += $self->over_general_limit(); + if($self->{'runload'}) { + # load should be between 0-10ish + # 0 load => 0 + my $load = $self->load_status(); + $status += ::max(0,$load - $self->{'runload'}); + } + if($self->{'runnoswap'}) { + # swap should be between 0-10ish + # swap in or swap out or no swap = 0 + # else log(swapin*swapout) + my $swap = $self->swap_status(); + $status += log(::max(1, $swap - $self->{'runnoswap'})); + } + if($self->{'runio'}) { + my $io = $self->io_status(); + $status += max(0,$io - $self->{'runio'}); + } $self->{'over_run_limit'} = $status; if(not $::opt_recheck) { $self->{'recheck'} = $self->{'factor'} * $self->{'over_run_limit'}; @@ -627,6 +389,44 @@ sub over_start_limit { # 50% available => 1 (2-1) # 10% available => 9 (10-1) my $mem = $self->mem_status(); +# $status += (::max(1,$self->{'startmem'}/$mem)-1)*10; + ::debug("Start memory: $self->{'startmem'}/$mem\n"); + $status += (::max(1,$self->{'startmem'}/$mem)-1); + } + if($self->{'startload'}) { + # load should be between 0-10ish + # 0 load => 0 + my $load = $self->load_status(); + $status += ::max(0,$load - $self->{'startload'}); + } + if($self->{'startnoswap'}) { + # swap should be between 0-10ish + # swap in or swap out or no swap = 0 + # else log(swapin*swapout) + my $swap = $self->swap_status(); + $status += log(::max(1, $swap - $self->{'startnoswap'})); + } + if($self->{'startio'}) { + my $io = $self->io_status(); + $status += ::max(0,$io - $self->{'startio'}); + } + $self->{'over_start_limit'} = $status; + if(not $::opt_recheck) { + $self->{'recheck'} = $self->{'factor'} * $self->{'over_start_limit'}; + } + ::debug("over_start_limit: $status\n"); + return $self->{'over_start_limit'}; +} + +sub __over_start_limit { + my $self = shift; + my $status = 0; + if($self->{'startmem'}) { + # mem should be between 0-10ish + # 100% available => 0 (1-1) + # 50% available => 1 (2-1) + # 10% available => 9 (10-1) + my $mem = $self->mem_status(); # $status += (::max(1,$self->{'startmem'}/$mem)-1)*10; $status += (::max(1,$self->{'startmem'}/$mem)-1); } @@ -639,29 +439,12 @@ sub over_start_limit { return $self->{'over_start_limit'}; } -sub over_general_limit { +sub __over_general_limit { # Return: # 0 if under all limits # >0 if over limit my $self = shift; my $status = 0; - if($self->{'load'}) { - # load should be between 0-10ish - # 0 load => 0 - my $load = $self->load_status(); - $status += ::max(0,$load - $self->{'load'}); - } - if($self->{'swap'}) { - # swap should be between 0-10ish - # swap in or swap out or no swap = 0 - # else log(swapin*swapout) - my $swap = $self->swap_status(); - $status += log(::max(1, $swap - $self->{'swap'})); - } - if($self->{'io'}) { - my $io = $self->io_status(); - $status += max(0,$io - $self->{'io'}); - } return $status; } @@ -745,7 +528,7 @@ sub swap_status { if(not defined $self->{'swap_status'} or $self->{'swap_status_cache_time'}+$self->{'recheck'} < time) { my $status = swap_status_linux(); - $self->{'swap_status'} = ::max($status-$self->{'swap'},0); + $self->{'swap_status'} = ::max($status,0); $self->{'swap_status_cache_time'} = time; } ::debug("swap_status: $self->{'swap_status'}\n"); @@ -807,11 +590,14 @@ sub io_status_linux { # sdg 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 my @iostat_out = `LANG=C iostat -x 1 2`; # throw away all execpt the last Device:-section - my @iostat = grep (/1/../Device:/, reverse @iostat_out); - print @iostat; - - my $io = (split(/\s+/,$iostat[2]))[3]; - return $io*1024; +# print @iostat_out; + my @iostat; + for(reverse @iostat_out) { + /Device:/ and last; + push @iostat, (split(/\s+/,$_))[13]; + } + my $io = ::max(@iostat); + return $io/10; } # Keep -w happy diff --git a/src/niceload.pod b/src/niceload.pod new file mode 100644 index 00000000..cd6dc925 --- /dev/null +++ b/src/niceload.pod @@ -0,0 +1,342 @@ +=head1 NAME + +niceload - slow down a program when the load average is above a certain limit + +=head1 SYNOPSIS + +B [-v] [-n nice] [-L load] [-t time] [-s time|-f factor] command + +B [-v] [-h] [-n nice] [-l load] [-t time] [-s time|-f factor] -p=PID + +=head1 DESCRIPTION + +GNU B will slow down a program when the load average is +above a certain limit. When the limit is reached the program will be +suspended for some time. Then resumed again for some time. Then the +load average is checked again and we start over. + +If the load is 3.00 then the default settings will run a program +like this: + +run 1 second, suspend (3.00-1.00) seconds, run 1 second, suspend +(3.00-1.00) seconds, run 1 second, ... + +=head1 OPTIONS + +=over 9 + +=item B<-f> I + +=item B<--factor> I + +Suspend time factor. Dynamically set B<-s> as amount over limit * +factor. Default is 1. + + +=item B<-H> + +=item B<--hard> + +Hard limit. B<--hard> will suspend the process until the system is +under the limits. The default is B<--soft>. + + +=item B<--io> I + +=item B<-I> I + +Limit for I/O. The amount of disk I/O will be computed as a value 0 - +10, where 0 is no I/O and 10 is at least one disk is 100% satuated. + +B<--io> will set both B<--start-io> and B. + + +=item B<--load> I + +=item B<-L> I + +Limit for load average. + +B<--load> will set both B<--start-load> and B. + + +=item B<--mem> I + +=item B<-M> I + +Limit for free memory. This is the amount of bytes available as free ++ cache. This limit is treated opposite other limits: If the system +is above the limit the program will run, if it is below the limit the +program will stop + +I can be postfixed with K, M, G, T, or P which would +multiply the size with 1024, 1048576, 1073741824, or 1099511627776 +respectively. + +B<--mem> will set both B<--start-mem> and B. + + +=item B<--noswap> + +=item B<-N> + +No swapping. If the system is swapping both in and out it is a good +indication that the system is memory stressed. + +B<--noswap> is over limit if the system is swapping both in and out. + +B<--noswap> will set both B<--start-noswap> and B. + + +=item B<-n> I + +=item B<--nice> I + +Sets niceness. See B(1). + + +=item B<-p> I + +=item B<--pid> I + +Process ID of process to suspend. + + +=item B<--run-io> I + +=item B<--ri> I + +=item B<--run-load> I + +=item B<--rl> I + +=item B<--run-mem> I + +=item B<--rm> I + +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>. + + +=item B<--start-io> I + +=item B<--si> I + +=item B<--start-load> I + +=item B<--sl> I + +=item B<--start-mem> I + +=item B<--sm> I + +Start limit. The program will not start until the system is below the +limit. See: B<--io>, B<--load>, B<--mem>, B<--noswap>. + + + +=item B<--suspend> I + +=item B<-s> I + +Suspend time. Suspend the command this many seconds when the max load +average is reached. + + +=item B<--soft> + +=item B<-S> + +Soft limit. B will suspend a process for a while and then +let it run for a second thus only slowing down a process while the +system is over one of the given limits. This is the default. + + +=item B<--recheck> I + +=item B<-t> I + +Recheck load time. Sleep SEC seconds before checking load +again. Default is 1 second. + + +=item B<--verbose> + +=item B<-v> + +Verbose. Print some extra output on what is happening. Use B<-v> until +you know what your are doing. + +=back + +=head1 EXAMPLE: See niceload in action + +In terminal 1 run: top + +In terminal 2 run: + +B>B<50)'> + +This will print a '.' every second for 50 seconds and eat a lot of +CPU. When the load rises to 1.0 the process is suspended. + + +=head1 EXAMPLE: Run updatedb + +Running updatedb can often starve the system for disk I/O and thus result in a high load. + +Run updatedb but suspend updatedb if the load is above 2.00: + +B + + +=head1 EXAMPLE: Run rsync + +rsync can just like updatedb starve the system for disk I/O and thus result in a high load. + +Run rsync but keep load below 3.4. If load reaches 7 sleep for +(7-3.4)*12 seconds: + +B + + +=head1 ENVIRONMENT VARIABLES + +None. In future versions $NICELOAD will be able to contain default settings. + +=head1 EXIT STATUS + +Exit status should be the same as the command being run (untested). + +=head1 REPORTING BUGS + +Report bugs to . + +=head1 AUTHOR + +Copyright (C) 2004-11-19 Ole Tange, http://ole.tange.dk + +Copyright (C) 2005,2006,2006,2008,2009,2010 Ole Tange, http://ole.tange.dk + +Copyright (C) 2010,2011 Ole Tange, http://ole.tange.dk and Free +Software Foundation, Inc. + +=head1 LICENSE + +Copyright (C) 2010 Free Software Foundation, Inc. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +at your option any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +=head2 Documentation license I + +Permission is granted to copy, distribute and/or modify this documentation +under the terms of the GNU Free Documentation License, Version 1.3 or +any later version published by the Free Software Foundation; with no +Invariant Sections, with no Front-Cover Texts, and with no Back-Cover +Texts. A copy of the license is included in the file fdl.txt. + +=head2 Documentation license II + +You are free: + +=over 9 + +=item B + +to copy, distribute and transmit the work + +=item B + +to adapt the work + +=back + +Under the following conditions: + +=over 9 + +=item B + +You must attribute the work in the manner specified by the author or +licensor (but not in any way that suggests that they endorse you or +your use of the work). + +=item B + +If you alter, transform, or build upon this work, you may distribute +the resulting work only under the same, similar or a compatible +license. + +=back + +With the understanding that: + +=over 9 + +=item B + +Any of the above conditions can be waived if you get permission from +the copyright holder. + +=item B + +Where the work or any of its elements is in the public domain under +applicable law, that status is in no way affected by the license. + +=item B + +In no way are any of the following rights affected by the license: + +=over 2 + +=item * + +Your fair dealing or fair use rights, or other applicable +copyright exceptions and limitations; + +=item * + +The author's moral rights; + +=item * + +Rights other persons may have either in the work itself or in +how the work is used, such as publicity or privacy rights. + +=back + +=back + +=over 9 + +=item B + +For any reuse or distribution, you must make clear to others the +license terms of this work. + +=back + +A copy of the full license is included in the file as cc-by-sa.txt. + +=head1 DEPENDENCIES + +GNU B uses Perl, and the Perl modules POSIX, and +Getopt::Long. + +=head1 SEE ALSO + +B(1), B(1) + + +=cut diff --git a/src/parallel b/src/parallel index 9fcf5c16..67e97088 100755 --- a/src/parallel +++ b/src/parallel @@ -456,7 +456,7 @@ sub get_options_from_array { sub parse_options { # Returns: N/A # Defaults: - $Global::version = 20110709; + $Global::version = 20110719; $Global::progname = 'parallel'; $Global::infinity = 2**31; $Global::debug = 0; diff --git a/src/sql b/src/sql index 30536b48..a394ecea 100755 --- a/src/sql +++ b/src/sql @@ -536,7 +536,7 @@ $Global::Initfile && unlink $Global::Initfile; exit ($err); sub parse_options { - $Global::version = 20110622; + $Global::version = 20110719; $Global::progname = 'sql'; # This must be done first as this may exec myself diff --git a/testsuite/tests-to-run/niceload01.sh b/testsuite/tests-to-run/niceload01.sh index 1b2b821c..aed66d70 100644 --- a/testsuite/tests-to-run/niceload01.sh +++ b/testsuite/tests-to-run/niceload01.sh @@ -4,6 +4,54 @@ echo '### Test niceload' niceload -s 1 perl -e '$|=1;do{$l==$r or print "."; $l=$r}until(($r=time-$^T)>10)' echo +echo '### -f and --factor' +niceload -f 0.1 echo f 0.1 +niceload --factor 0.1 echo factor 0.1 + +echo '### -f and --factor' +niceload -f 0.1 echo f 0.1 +niceload --factor 0.1 echo factor 0.1 + +# Force less than 1 GB buffer+cache +MEMAVAIL=$(free | perl -ane '/buffers.cache:/ and print $F[3]') +while [ $MEMAVAIL -gt 1000000 ] ; do + BS=$(echo $MEMAVAIL/10 | bc) + (seq 1 5 | parallel -j0 -N0 timeout 10 nice dd if=/dev/zero of=/dev/null bs=${BS}k &) + sleep 2; + MEMAVAIL=$(free | perl -ane '/buffers.cache:/ and print $F[3]') + echo $MEMAVAIL +done +# free +echo '### --rm and --runmem' +niceload -H --rm 1g free -g | perl -ane '/buffers.cache:/ and print $F[3],"\n"' | grep '[1-9]' >/dev/null && echo OK & +niceload -H --runmem 1.2g free -g | perl -ane '/buffers.cache:/ and print $F[3],"\n"' | grep '[1-9]' >/dev/null && echo OK & +wait +# free + +# Force swapping +MEMAVAIL=$(free | perl -ane '/buffers.cache:/ and print $F[3]') +while [ $MEMAVAIL -gt 1000000 ] ; do + BS=$(echo $MEMAVAIL/10 | bc) + (seq 1 10 | parallel -j0 -N0 timeout 10 nice dd if=/dev/zero of=/dev/null bs=${BS}k &) + sleep 2; + MEMAVAIL=$(free | perl -ane '/buffers.cache:/ and print $F[3]') + echo $MEMAVAIL +done + +echo '### -N and --noswap ' +niceload -D -H -N vmstat 1 2 | tail -n1 | awk '{print $7*$8}' & +niceload -D -H --noswap vmstat 1 2 | tail -n1 | awk '{print $7*$8}' & +wait + + +# force load > 10 +while uptime | grep -v '[1-9][0-9]\.[0-9][0-9],' >/dev/null ; do (timeout 2 nice burnP6 2>/dev/null &) done + +echo '### -H and --hard' +niceload -H -l 9.9 uptime | grep '[1-9][0-9]\.[0-9][0-9],' || echo OK +niceload --hard -l 9 uptime | grep '[1-9][0-9]\.[0-9][0-9],' || echo OK + + #echo '### Test niceload -p' #sleep 3 & #nice-load -v -p $!