3 # Copyright (C) 2007,2008,2009,2010,2011 Ole Tange and Free Software
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, see <http://www.gnu.org/licenses/>
18 # or write to the Free Software Foundation, Inc., 51 Franklin St,
19 # Fifth Floor, Boston, MA 02110-1301 USA
21 # SPDX-FileCopyrightText: 2021-2024 Ole Tange, http://ole.tange.dk and Free Software and Foundation, Inc.
22 # SPDX-License-Identifier: GPL-3.0-or-later
26 christmastree - use memory similar to a christmas tree profile
30 B<christmastree> [-s I<per_second>] [-m I<min>] <max>
34 GNU B<christmastree> is a test script that increases and decreases its
35 memory usage. The increase and descrease will happen at random, but
36 the memory usage will grow on average.
42 The maximal amount of memory to use before exitting.
45 =item B<-s> I<per_second>
47 The amount of memory it should grow per second on average. Default to max/10.
52 The minimal amount of memory to use before exitting.
63 B<christmastree> is part of GNU B<parallel>. Report bugs to <bug-parallel@gnu.org>.
68 Copyright (C) 2011 Ole Tange, http://ole.tange.dk and Free
69 Software Foundation, Inc.
73 Copyright (C) 2011 Free Software Foundation, Inc.
75 This program is free software; you can redistribute it and/or modify
76 it under the terms of the GNU General Public License as published by
77 the Free Software Foundation; either version 3 of the License, or
78 at your option any later version.
80 This program is distributed in the hope that it will be useful,
81 but WITHOUT ANY WARRANTY; without even the implied warranty of
82 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
83 GNU General Public License for more details.
85 You should have received a copy of the GNU General Public License
86 along with this program. If not, see <http://www.gnu.org/licenses/>.
88 =head2 Documentation license I
90 Permission is granted to copy, distribute and/or modify this documentation
91 under the terms of the GNU Free Documentation License, Version 1.3 or
92 any later version published by the Free Software Foundation; with no
93 Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
94 Texts. A copy of the license is included in the file fdl.txt.
96 =head2 Documentation license II
104 to copy, distribute and transmit the work
112 Under the following conditions:
118 You must attribute the work in the manner specified by the author or
119 licensor (but not in any way that suggests that they endorse you or
120 your use of the work).
124 If you alter, transform, or build upon this work, you may distribute
125 the resulting work only under the same, similar or a compatible
130 With the understanding that:
136 Any of the above conditions can be waived if you get permission from
137 the copyright holder.
139 =item B<Public Domain>
141 Where the work or any of its elements is in the public domain under
142 applicable law, that status is in no way affected by the license.
144 =item B<Other Rights>
146 In no way are any of the following rights affected by the license:
152 Your fair dealing or fair use rights, or other applicable
153 copyright exceptions and limitations;
157 The author's moral rights;
161 Rights other persons may have either in the work itself or in
162 how the work is used, such as publicity or privacy rights.
168 For any reuse or distribution, you must make clear to others the
169 license terms of this work.
173 A copy of the full license is included in the file as cc-by-sa.txt.
177 B<christmastree> uses Perl.
189 my $start_time = time;
190 my $max = multiply_binary_prefix
(shift);
191 my $min = (multiply_binary_prefix
($::opt_m
) or $max);
192 my $target_max = int(rand($max - $min)) + $min;
193 my $per_second = (multiply_binary_prefix
($::opt_s
) or $target_max/10);
194 my ($memusage,@a,$target,$this_round);
197 $memusage = my_memory_usage
();
198 $target = (time - $start_time)*int($per_second);
199 $this_round = $target - my_memory_usage
();
200 if($this_round > 0) {
201 my $this_size = min
(rand($this_round*3), $target_max-$memusage);
202 my $a = "x"x
$this_size;
207 debug
("$#a memusage $memusage target $target this_round $this_round target_max $target_max\n");
209 } while($memusage < $target_max);
214 # Minimum value of array
219 defined $min or do { $min = $_; next; }; # Set $_ to the first non-undef
220 $min = ($min < $_) ?
$min : $_;
228 $Global::debug
or return;
229 @_ = grep { defined $_ ?
$_ : "" } @_;
230 if($Global::original_stdout
) {
231 print $Global::original_stdout
@_;
238 $Global::version
= 20110822;
239 $Global::progname
= 'christmastree';
241 Getopt
::Long
::Configure
("bundling","require_order");
242 GetOptions
("s=s" => \
$::opt_s
,
245 "debug" => \
$::opt_debug
,
247 "help|h" => \
$::opt_help
,
248 "version|V" => \
$::opt_version
,
251 if(defined $::opt_r
) { srand($::opt_r
); }
252 if(defined $::opt_help
) { die_usage
(); }
253 if(defined $::opt_version
) { version
(); exit(0); }
254 $Global::debug
= $::opt_debug
;
258 # Sleep this many milliseconds.
260 ::debug
("Sleeping ",$secs," millisecs\n");
261 select(undef, undef, undef, $secs/1000);
263 ::debug
(my_dump
($Global::timeoutq
));
264 $Global::timeoutq
->process_timeouts();
278 sub my_memory_usage
{
280 # memory usage if found
286 if(-e
"/proc/$pid/stat") {
287 my $fh = FileHandle
->new("</proc/$pid/stat");
293 my @procinfo = split(/\s+/,$data);
295 return undef_as_zero
($procinfo[22]);
301 sub multiply_binary_prefix
{
302 # Evalualte numbers with binary prefix
303 # k=10^3, m=10^6, g=10^9, t=10^12, p=10^15, e=10^18, z=10^21, y=10^24
304 # K=2^10, M=2^20, G=2^30, T=2^40, P=2^50, E=2^70, Z=2^80, Y=2^80
305 # Ki=2^10, Mi=2^20, Gi=2^30, Ti=2^40, Pi=2^50, Ei=2^70, Zi=2^80, Yi=2^80
306 # ki=2^10, mi=2^20, gi=2^30, ti=2^40, pi=2^50, ei=2^70, zi=2^80, yi=2^80
307 # 13G = 13*1024*1024*1024 = 13958643712
308 my $s = undef_as_empty
(shift);
310 $s =~ s/M/*1000*1000/g;
311 $s =~ s/G/*1000*1000*1000/g;
312 $s =~ s/T/*1000*1000*1000*1000/g;
313 $s =~ s/P/*1000*1000*1000*1000*1000/g;
314 $s =~ s/E/*1000*1000*1000*1000*1000*1000/g;
315 $s =~ s/Z/*1000*1000*1000*1000*1000*1000*1000/g;
316 $s =~ s/Y/*1000*1000*1000*1000*1000*1000*1000*1000/g;
317 $s =~ s/X/*1000*1000*1000*1000*1000*1000*1000*1000*1000/g;
319 $s =~ s/Ki?/*1024/gi;
320 $s =~ s/Mi?/*1024*1024/gi;
321 $s =~ s/Gi?/*1024*1024*1024/gi;
322 $s =~ s/Ti?/*1024*1024*1024*1024/gi;
323 $s =~ s/Pi?/*1024*1024*1024*1024*1024/gi;
324 $s =~ s/Ei?/*1024*1024*1024*1024*1024*1024/gi;
325 $s =~ s/Zi?/*1024*1024*1024*1024*1024*1024*1024/gi;
326 $s =~ s/Yi?/*1024*1024*1024*1024*1024*1024*1024*1024/gi;
327 $s =~ s/Xi?/*1024*1024*1024*1024*1024*1024*1024*1024*1024/gi;