From e088f111e931eb084f123b65ccc314cd593b1309 Mon Sep 17 00:00:00 2001 From: "msvensson@pilot.(none)" <> Date: Sun, 4 May 2008 13:31:40 +0200 Subject: [PATCH] Use SysInfo.pm to find a suitable value for number of workers when --parallel hasn't been specified Add lib/My/SysInfo.pm --- mysql-test/Makefile.am | 1 + mysql-test/lib/My/SysInfo.pm | 181 +++++++++++++++++++++++++++++++++++ mysql-test/mysql-test-run.pl | 17 +++- 3 files changed, 196 insertions(+), 3 deletions(-) create mode 100644 mysql-test/lib/My/SysInfo.pm diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index 02dea1a4466..c37e808faf2 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -42,6 +42,7 @@ nobase_test_DATA = lib/mtr_cases.pm \ lib/My/Platform.pm \ lib/My/SafeProcess.pm \ lib/My/File/Path.pm \ + lib/My/SysInfo.pm \ lib/My/SafeProcess/Base.pm \ lib/My/SafeProcess/safe_process.pl diff --git a/mysql-test/lib/My/SysInfo.pm b/mysql-test/lib/My/SysInfo.pm new file mode 100644 index 00000000000..b764b4548f7 --- /dev/null +++ b/mysql-test/lib/My/SysInfo.pm @@ -0,0 +1,181 @@ +# -*- cperl -*- +# Copyright (C) 2004-2006 MySQL AB +# +# 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; version 2 of the License. +# +# 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +package My::SysInfo; + +use strict; +use Carp; +use My::Platform; + + + +sub _cpuinfo { + my ($self)= @_; + print "_cpuinfo\n"; + + my $info_file= "/proc/cpuinfo"; + if ( !( -e $info_file and -f $info_file) ) { + return undef; + } + + my $F= IO::File->new($info_file) or return undef; + + # Set input separator to blank line + local $/ = ''; + + while ( my $cpu_chunk= <$F>) { + chomp($cpu_chunk); + + my $cpuinfo = {}; + + foreach my $cpuline ( split(/\n/, $cpu_chunk) ) { + my ( $attribute, $value ) = split(/\s*:\s*/, $cpuline); + + $attribute =~ s/\s+/_/; + $attribute = lc($attribute); + + if ( $value =~ /^(no|not available|yes)$/ ) { + $value = $value eq 'yes' ? 1 : 0; + } + + if ( $attribute eq 'flags' ) { + @{ $cpuinfo->{flags} } = split / /, $value; + } else { + $cpuinfo->{$attribute} = $value; + } + } + + push(@{$self->{cpus}}, $cpuinfo); + } + $F= undef; # Close file + return $self; +} + + +sub _kstat { + my ($self)= @_; + while (1){ + my $instance_num= $self->{cpus} ? @{$self->{cpus}} : 0; + my $list= `kstat -p -m cpu_info -i $instance_num`; + my @lines= split('\n', $list) or return undef; + + my $cpuinfo= {}; + foreach my $line (@lines) + { + my ($module, $instance, $name, $statistic, $value)= + $line=~ /(\w*):(\w*):(\w*):(\w*)\t(.*)/; + + $cpuinfo->{$statistic}= $value; + } + + # Default value, the actual cpu values can be used to decrease it + # on slower cpus + $cpuinfo->{bogomips}= 2000; + + push(@{$self->{cpus}}, $cpuinfo); + } + + return $self; +} + + +sub _unamex { + my ($self)= @_; + # TODO + return undef; +} + + +sub new { + my ($class)= @_; + + + my $self= bless { + cpus => (), + }, $class; + + my @info_methods = + ( + \&_cpuinfo, + \&_kstat, + \&_unamex, + ); + + foreach my $method (@info_methods){ + if ($method->($self)){ + return $self; + } + } + + # Push a dummy cpu + push(@{$self->{cpus}}, {bogomips => 2000, model_name => "unknown"}); + + return $self; +} + + +# Return the list of cpus found +sub cpus { + my ($self)= @_; + return @{$self->{cpus}} or + confess "INTERNAL ERROR: No cpus in list"; +} + + +# Return the number of cpus found +sub num_cpus { + my ($self)= @_; + return int(@{$self->{cpus}}) or + confess "INTERNAL ERROR: No cpus in list"; +} + + +# Return the smallest bogomips value amongst the processors +sub min_bogomips { + my ($self)= @_; + + my $bogomips; + + foreach my $cpu (@{$self->{cpus}}) { + if (!defined $bogomips or $bogomips > $cpu->{bogomips}) { + $bogomips= $cpu->{bogomips}; + } + } + + return $bogomips; +} + + +# Prit the cpuinfo +sub print_info { + my ($self)= @_; + + foreach my $cpu (@{$self->{cpus}}) { + while ((my ($key, $value)) = each(%$cpu)) { + print " ", $key, "= "; + if (ref $value eq "ARRAY") { + print "[", join(", ", @$value), "]"; + } else { + print $value; + } + print "\n"; + } + print "\n"; + } +} + +1; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index eb251a93049..40fec215b34 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -49,6 +49,7 @@ use My::SafeProcess; use My::ConfigFactory; use My::Options; use My::Find; +use My::SysInfo; use mtr_cases; use mtr_report; use mtr_match; @@ -206,7 +207,9 @@ $| = 1; # Automatically flush STDOUT main(); + sub main { + report_option('verbose', 0); # This is needed for test log evaluation in "gen-build-status-page" # in all cases where the calling tool does not log the commands @@ -216,8 +219,17 @@ sub main { Getopt::Long::Configure("pass_through"); GetOptions('parallel=i' => \$opt_parallel) or usage("Can't read options"); - if ( not defined $opt_parallel ){ - $opt_parallel= 4; # Default + if ( not defined $opt_parallel ) { + # Try to find a suitable value for number of workers + my $sys_info= My::SysInfo->new(); + $sys_info->print_info(); + + $opt_parallel= $sys_info->num_cpus(); + for my $limit (2000, 1500, 1000, 500){ + $opt_parallel-- if ($sys_info->min_bogomips() < $limit); + } + $opt_parallel= 1 if ($opt_parallel < 1); + mtr_report("Using parallel: $opt_parallel"); } # Create server socket on any free port @@ -241,7 +253,6 @@ sub main { exit(1); } - mtr_report("Started worker, pid: $child_pid"); $children{$child_pid}= 1; }