1# -*- cperl -*- 2# Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. 3# 4# This program is free software; you can redistribute it and/or modify 5# it under the terms of the GNU General Public License as published by 6# the Free Software Foundation; version 2 of the License. 7# 8# This program is distributed in the hope that it will be useful, 9# but WITHOUT ANY WARRANTY; without even the implied warranty of 10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11# GNU General Public License for more details. 12# 13# You should have received a copy of the GNU General Public License 14# along with this program; if not, write to the Free Software 15# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 16 17 18package My::SysInfo; 19 20use strict; 21use Carp; 22use My::Platform; 23 24use constant DEFAULT_BOGO_MIPS => 2000; 25 26sub _cpuinfo { 27 my ($self)= @_; 28 29 my $info_file= "/proc/cpuinfo"; 30 if ( !( -e $info_file and -f $info_file) ) { 31 return undef; 32 } 33 34 my $F= IO::File->new($info_file) or return undef; 35 36 # Set input separator to blank line 37 local $/ = ''; 38 39 while ( my $cpu_chunk= <$F>) { 40 chomp($cpu_chunk); 41 42 my $cpuinfo = {}; 43 44 foreach my $cpuline ( split(/\n/, $cpu_chunk) ) { 45 my ( $attribute, $value ) = split(/\s*:\s*/, $cpuline); 46 47 $attribute =~ s/\s+/_/; 48 $attribute = lc($attribute); 49 50 if ( $value =~ /^(no|not available|yes)$/ ) { 51 $value = $value eq 'yes' ? 1 : 0; 52 } 53 54 if ( $attribute eq 'flags' ) { 55 @{ $cpuinfo->{flags} } = split / /, $value; 56 } else { 57 $cpuinfo->{$attribute} = $value; 58 } 59 } 60 61 # Make sure bogomips is set to some value 62 $cpuinfo->{bogomips} ||= DEFAULT_BOGO_MIPS; 63 64 # Cpus reported once, but with 'cpu_count' set to the actual number 65 my $cpu_count= $cpuinfo->{cpu_count} || 1; 66 for(1..$cpu_count){ 67 push(@{$self->{cpus}}, $cpuinfo); 68 } 69 } 70 $F= undef; # Close file 71 return $self; 72} 73 74 75sub _kstat { 76 my ($self)= @_; 77 while (1){ 78 my $instance_num= $self->{cpus} ? @{$self->{cpus}} : 0; 79 my $list= `kstat -p -m cpu_info -i $instance_num 2> /dev/null`; 80 my @lines= split('\n', $list) or last; # Break loop 81 82 my $cpuinfo= {}; 83 foreach my $line (@lines) 84 { 85 my ($module, $instance, $name, $statistic, $value)= 86 $line=~ /(\w*):(\w*):(\w*):(\w*)\t(.*)/; 87 88 $cpuinfo->{$statistic}= $value; 89 } 90 91 # Default value, the actual cpu values can be used to decrease this 92 # on slower cpus 93 $cpuinfo->{bogomips}= DEFAULT_BOGO_MIPS; 94 95 push(@{$self->{cpus}}, $cpuinfo); 96 } 97 98 # At least one cpu should have been found 99 # if this method worked 100 if ( $self->{cpus} ) { 101 return $self; 102 } 103 return undef; 104} 105 106 107sub _unamex { 108 my ($self)= @_; 109 # TODO 110 return undef; 111} 112 113 114sub new { 115 my ($class)= @_; 116 117 118 my $self= bless { 119 cpus => (), 120 }, $class; 121 122 my @info_methods = 123 ( 124 \&_cpuinfo, 125 \&_kstat, 126 \&_unamex, 127 ); 128 129 # Detect virtual machines 130 my $isvm= 0; 131 132 if (IS_WINDOWS) { 133 # Detect vmware service 134 $isvm= `tasklist` =~ /vmwareservice/i; 135 } 136 $self->{isvm}= $isvm; 137 138 foreach my $method (@info_methods){ 139 if ($method->($self)){ 140 return $self; 141 } 142 } 143 144 # Push a dummy cpu 145 push(@{$self->{cpus}}, 146 { 147 bogomips => DEFAULT_BOGO_MIPS, 148 model_name => "unknown", 149 }); 150 151 return $self; 152} 153 154 155# Return the list of cpus found 156sub cpus { 157 my ($self)= @_; 158 return @{$self->{cpus}} or 159 confess "INTERNAL ERROR: No cpus in list"; 160} 161 162 163# Return the number of cpus found 164sub num_cpus { 165 my ($self)= @_; 166 return int(@{$self->{cpus}}) or 167 confess "INTERNAL ERROR: No cpus in list"; 168} 169 170 171# Return the smallest bogomips value amongst the processors 172sub min_bogomips { 173 my ($self)= @_; 174 175 my $bogomips; 176 177 foreach my $cpu (@{$self->{cpus}}) { 178 if (!defined $bogomips or $bogomips > $cpu->{bogomips}) { 179 $bogomips= $cpu->{bogomips}; 180 } 181 } 182 183 return $bogomips; 184} 185 186sub isvm { 187 my ($self)= @_; 188 189 return $self->{isvm}; 190} 191 192 193# Prit the cpuinfo 194sub print_info { 195 my ($self)= @_; 196 197 foreach my $cpu (@{$self->{cpus}}) { 198 while ((my ($key, $value)) = each(%$cpu)) { 199 print " ", $key, "= "; 200 if (ref $value eq "ARRAY") { 201 print "[", join(", ", @$value), "]"; 202 } else { 203 print $value; 204 } 205 print "\n"; 206 } 207 print "\n"; 208 } 209} 210 2111; 212