diff --git a/src/christmastree b/src/christmastree new file mode 100644 index 00000000..f98bcfdd --- /dev/null +++ b/src/christmastree @@ -0,0 +1,313 @@ +#!/usr/bin/perl -w + +# Copyright (C) 2007,2008,2009,2010,2011 Ole Tange and 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 +# or write to the Free Software Foundation, Inc., 51 Franklin St, +# Fifth Floor, Boston, MA 02110-1301 USA + +=head1 NAME + +christmastree - use memory similar to a christmas tree profile + +=head1 SYNOPSIS + +B [-s I] [-m I] + +=head1 DESCRIPTION + +GNU B is a test script that increases and decreases its +memory usage. The increase and descrease will happen at random, but +the memory usage will grow on average. + +=over 9 + +=item I + +The maximal amount of memory to use before exitting. + + +=item B<-s> I + +The amount of memory it should grow per second on average. Default to max/10. + + +=item B<-m> I + +The minimal amount of memory to use before exitting. + +=back + + +=head1 EXAMPLES + + + +=head1 REPORTING BUGS + +B is part of GNU B. Report bugs to . + + +=head1 AUTHOR + +Copyright (C) 2011 Ole Tange, http://ole.tange.dk and Free +Software Foundation, Inc. + +=head1 LICENSE + +Copyright (C) 2011 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 9 + +=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 + +=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 + +B uses Perl. + + +=head1 SEE ALSO + +B(1) + +=cut + +use Getopt::Long; + +parse_options(); +my $start_time = time; +my $max = multiply_binary_prefix(shift); +my $min = (multiply_binary_prefix($::opt_m) or $max); +my $target_max = int(rand($max - $min)) + $min; +my $per_second = (multiply_binary_prefix($::opt_s) or $target_max/10); +my ($memusage,@a,$target,$this_round); + +do { + $memusage = my_memory_usage(); + $target = (time - $start_time)*int($per_second); + $this_round = $target - my_memory_usage(); + if($this_round > 0) { + my $a = "x"x(rand($this_round*3)); + push @a,$a; + } else { + pop @a; + } + debug("memusage $memusage target $target this_round $this_round target_max $target_max\n"); + usleep(500); +} while($memusage < $target_max); + + +sub debug { + # Returns: N/A + $Global::debug or return; + @_ = grep { defined $_ ? $_ : "" } @_; + if($Global::original_stdout) { + print $Global::original_stdout @_; + } else { + print @_; + } +} + +sub parse_options { + $Global::version = 20110822; + $Global::progname = 'christmastree'; + + Getopt::Long::Configure ("bundling","require_order"); + GetOptions("s=s" => \$::opt_s, + "m=s" => \$::opt_m, + "r=s" => \$::opt_r, + "debug" => \$::opt_debug, + # GNU requirements + "help|h" => \$::opt_help, + "version|V" => \$::opt_version, + ) || die_usage(); + + if(defined $::opt_r) { srand($::opt_r); } + if(defined $::opt_help) { die_usage(); } + if(defined $::opt_version) { version(); exit(0); } + $Global::debug = $::opt_debug; +} + +sub usleep { + # Sleep this many milliseconds. + my $secs = shift; + ::debug("Sleeping ",$secs," millisecs\n"); + select(undef, undef, undef, $secs/1000); + if($::opt_timeout) { + ::debug(my_dump($Global::timeoutq)); + $Global::timeoutq->process_timeouts(); + } +} + +sub undef_as_zero { + my $a = shift; + return $a ? $a : 0; +} + +sub undef_as_empty { + my $a = shift; + return $a ? $a : ""; +} + +sub my_memory_usage { + # Returns: + # memory usage if found + # 0 otherwise + use strict; + use FileHandle; + + my $pid = $$; + if(-e "/proc/$pid/stat") { + my $fh = FileHandle->new("; + chomp $data; + $fh->close; + + my @procinfo = split(/\s+/,$data); + + return undef_as_zero($procinfo[22]); + } else { + return 0; + } +} + +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 = undef_as_empty(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; +} + diff --git a/src/parallel b/src/parallel index 9693f507..010eabf7 100755 --- a/src/parallel +++ b/src/parallel @@ -98,9 +98,10 @@ if($::opt_nonall or $::opt_onall) { ((defined $::opt_D) ? "-D" : ""), ); ::debug("| parallel"); - open(PARALLEL,"| parallel $options") || die; + open(PARALLEL,"| $0 $options") || + ::die_bug("This does not run GNU Parallel: $0 $options"); for my $sshlogin (values %Global::host) { - print PARALLEL "parallel $suboptions -j1 -S ". + print PARALLEL "$0 $suboptions -j1 -S ". shell_quote_scalar($sshlogin->string())." ". shell_quote_scalar($command)." :::: @argfiles\n"; }