Sys-Info-Driver-OSX

 view release on metacpan or  search on metacpan

lib/Sys/Info/Driver/OSX/Device/CPU.pm  view on Meta::CPAN

use constant RE_SPACE => qr{\s+}xms;

sub identify {
    my $self = shift;

    if ( ! $self->{META_DATA} ) {
        my($cpu) = system_profiler( 'SPHardwareDataType' );

        my $mcpu = do {
            my $rv;
            my $mcpu = nsysctl('machdep.cpu');
            foreach my $key ( keys %{ $mcpu } ) {
                my @k = split m{[.]}xms, $key;
                my $e = $rv->{ shift @k } ||= {};
                $e = $e->{$_} ||= {} for @k;
                $e->{value} = $mcpu->{ $key };
            }
            $rv->{machdep}{cpu};
        };

        my $mach = $self->uname->{machine} || fsysctl('hw.machine_arch');
        my $arch = $mach =~ m{ i [0-9] 86 }xmsi ? 'x86'
                 : $mach =~ m{ ia64       }xmsi ? 'IA64'
                 : $mach =~ m{ x86_64     }xmsi ? 'AMD-64'
                 :                                 $mach
                 ;

        my $name = fsysctl('hw.model') || q{};
        $name =~ s{\s+}{ }xms;
        my $byteorder = nsysctl('hw.byteorder');

        my @flags;
        foreach my $f ( @{ $mcpu }{ qw/ extfeatures features / } ) {
            next if ref $f ne 'HASH';
            next if ! $f->{value};
            push @flags, split RE_SPACE, __PACKAGE__->trim( $f->{value} );
        }

        $self->{META_DATA} = [];

        my%flag = map { $_ => 1 } @flags;
        # hw.cpu64bit_capable
        if ( $flag{EM64T} || grep { m{x86_64}xms } @flags ) {
            $arch = 'AMD-64';
            push @flags, 'LM';
        }

        my($cps, $c2)   = @{ $cpu }{ qw/ current_processor_speed l2_cache / };
        my($cache_size) = $c2  ? split RE_SPACE, $c2  : 0;
        my($speed)      = $cps ? split RE_SPACE, $cps : 0;
        $cache_size    *= 1024 if $cache_size;
        if ( $speed ) {
            # locale might change the decimal separator
            $speed =~ s{ [,] }{.}xms;
            $speed *= 1000;
        }
        else {
            if ( $arch eq 'arm64' ) {
                if ( $< ) {
                    state $warned_non_root;
                    my $me = getpwuid $<;
                    if ( ! $warned_non_root++ ) {
                        warn "We can't probe for CPU speed for Apple Silicon with the current user $me and need root/sudo to be able to collect more information.";
                    }
                }
                else {
                    my %pm = powermetrics(
                                -s => 'cpu_power',
                                -n => 1,
                                -i => 1,
                            );
                    my %af = map { $_ => $pm{ $_ } }
                            grep { $pm{$_} ne ' 0 MHz' }
                            grep { $_ =~ m{ \QHW active frequency\E }xms }
                            keys %pm;
                    my @clusters_speed = sort { $a <=> $b }
                                            map {
                                                (
                                                    split m{\s+}xms,
                                                        __PACKAGE__->trim( $_ )
                                                )[0]
                                            }
                                            values %af;
                    # get the max. Likely P-N cluster.
                    $speed = $clusters_speed[-1];
                }
            }
        }

        my $proc_num = $cpu->{number_processors};
        $proc_num =~ s/proc (\d+).*/$1/; # M1 asymmetric cores

        push @{ $self->{META_DATA} }, {
            serial_number                => $cpu->{serial_number},
            architecture                 => $arch,
            processor_id                 => 1,
            data_width                   => undef,
            address_width                => undef,
            bus_speed                    => $cpu->{bus_speed},
            speed                        => $speed,
            name                         => $cpu->{chip_type} || $cpu->{cpu_type} || $name,
            family                       => $mcpu->{family}{value},
            manufacturer                 => $mcpu->{vendor}{value},
            model                        => $mcpu->{model}{value},
            stepping                     => $mcpu->{stepping}{value},
            number_of_cores              => $mcpu->{core_count}{value},
            number_of_logical_processors => $mcpu->{cores_per_package}{value},
            L2_cache                     => { max_cache_size => $cache_size },
            flags                        => @flags ? [ sort @flags ] : undef,
            ( $byteorder ? (byteorder    => $byteorder):()),
        } for 1..$proc_num;
    }

    return $self->_serve_from_cache(wantarray);
}

sub load {
    my $self  = shift;
    my $level = shift || 0;
    my $raw   = fsysctl('vm.loadavg') || return;
       $raw   =~ s<[{}]><>xmsg;



( run in 2.456 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )