Repository 32bit  Forum
Repository 64bit  Wiki

Cpuscaling

Da Slacky.eu.
Versione delle 12:51, 5 ott 2006, autore: Gallows (Discussione | contributi)

(diff) ← Versione meno recente | Versione attuale (diff) | Versione più recente → (diff)

Descrizione

Cpuscaling, script che permette di settare (tramite scrittura sul sysfs) un determinato range di frequenze per la cpu oppure di selezionare una modalità di comportamento predefinita tra quelle disponibili dal kernel, le quali vanno dal risparmio dell'energia (powersave), al pieno sfruttamento della cpu (performance), passando per governor intermedi che aumentano la frequenza della cpu in relazione ai programmi in esecuzione. Ovviamente tali feature devono essere presenti nel kernel (anche non built-in, ci pensa lo script a caricare i moduli).

Script

#
#       cpuscaling 0.1.1
# 
#  Copyright (c) 2006 Sergio Perticone <gall0ws@tiscali.it>.
#  All rights reserved.
#
#  Redistribution and use of this script, with or without modification,
#  are permitted provided that this copyright notice and the following
#  disclaimer are retained.
#
#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## #
#
# for limited, but trusted, users you can use sudo(8), it works fine.
#
# add in your /etc/sudoers something like this:
#  -------------------------------------------------------
#   %group  ALL=(ALL)   NOPASSWD: /usr/sbin/cpuscaling 
#  -------------------------------------------------------
# so:
#     myhost% sudo /usr/sbin/cpuscaling [ options ]
#
#     see sudoers(5) for more info.
#
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## #

use warnings;
use Getopt::Long;

## set some global variables:
$SYSDIR = "/sys/devices/system/cpu/cpu0/cpufreq";
$AVAILABLE_GOVERNORS = "$SYSDIR/scaling_available_governors";
$GOVERNOR = "$SYSDIR/scaling_governor";
$FREQMAX_FILE = "$SYSDIR/scaling_max_freq";
$FREQMIN_FILE = "$SYSDIR/scaling_min_freq";
$FREQCUR = "$SYSDIR/scaling_cur_freq";
$FREQS = "$SYSDIR/scaling_available_frequencies";


sub usage
{
    print <<EoF;

 cpuscaling <governor>
 cpuscaling [ -a, --frequence-max <freq> ] [ -b, --frequence-min <freq> ]
 cpuscaling [ -f, --freqs ] [ -s, --state ]

     conservative	Tune governor to conservative
     ondemand		Tune governor to ondemand
     performance	Tune governor to performance
     powersave		Tune governor to powersave
     userspace		Tune governor to userspace

     -a, --frequence-max <freq>	Set max frequence
     -b, --frequence-min <freq>	Set min frequence
     -f, --freqs		Print frequences supported by your CPU
     -s, --state		Show current state

     -h, --help		Print this help and exit

Report bugs to <gall0ws\@tiscali.it>.

EoF

    exit 0;
}


sub only_root
{
    print "only superuser can do it.\n";
    exit 2;
}


sub something_wrong
{
    print "Failed. Please check your kernel setting.\n";
    exit 1;
}


sub no_freq
{
    print "Please choose a frequence.\n";
    exit 1;
}


sub show_state
{
    open(GOVERNOR_FILE, "< $GOVERNOR") || something_wrong();
    $_ = <GOVERNOR_FILE>;
    chop;
    close(GOVERNOR_FILE);
    print "governor:\t $_\n";
    
    open(FREQCUR_FILE, "< $FREQCUR") || something_wrong();
    $_ = <FREQCUR_FILE>;
    chop;
    close(FREQCUR_FILE);
    print "current :\t $_ Hz\n";

    exit 0 if ("$GOVERNOR" eq "performance");

    open(FREQMIN_FILE, "< $FREQMIN_FILE") || something_wrong();
    $_ = <FREQMIN_FILE>;
    chop;
    close(FREQMIN_FILE);
    print "freq min:\t $_ Hz\n";

    open(FREQMAX_FILE, "< $FREQMAX_FILE") || something_wrong();
    $_ = <FREQMAX_FILE>;
    chop;
    close(FREQMAX_FILE);
    print "freq max:\t $_ Hz\n";

    exit 0;
}


sub show_freqs
{
    open(FREQS, "< $FREQS") || something_wrong();
    $_ = <FREQS>;
    close(FREQS);
    print;

    exit 0;
}

 
sub change_freq
{
    only_root() if("$<" != "0"); # $< is UID

    my ($new_frequence, $file) = @_;

    open(FREQ, "> $file") || something_wrong();
    print FREQ "$new_frequence";
    close(FREQ);

    show_state();
}



sub available
{
    my ($governor) = @_;

    open(AV_GOVS, "< $AVAILABLE_GOVERNORS");
      $_ = <AV_GOVS>;
      chop;
    close(AV_GOVS);

    my @govs = split(' ', $_);
    my $i = 0;

    foreach (@govs) {
	return 1 if ( "$govs[$i]" eq "$governor" );
	$i++;
    }
    
    return 0; ## governor is n/a
}


sub set_governor
{
    only_root() if("$<" != "0");

    my ($new_governor) = @_;

    ## if governor seems to be not available then we try to load module:
    if ( ! available($new_governor) ) {
	`/sbin/modprobe $new_governor` || something_wrong();
    }

    open(GOVS_FILE, "> $GOVERNOR");
    print GOVS_FILE "$new_governor";
    close(GOVS_FILE);

    show_state();
}

sub wtf
{
    print "Try \`cpuscaling --help' for more information.\n";
    exit 1;
}

GetOptions(
	   "freqs"           => \$freqs,
	   "f"               => \$freqs,
	   "frequence-max=i" => \$freq_max,
	   "a=i"             => \$freq_max,
	   "frequence-min=i" => \$freq_min,
	   "b=i"             => \$freq_min,
	   "state"           => \$show_state,
	   "s"               => \$show_state,
	   "help"            => \$usage,
	   "h"               => \$usage,
	   ) || wtf();

usage() if (defined $usage);

show_freqs() if (defined $freqs);
show_state() if (defined $show_state);

change_freq($freq_max, $FREQMAX_FILE) if (defined $freq_max);
change_freq($freq_min, $FREQMIN_FILE) if (defined $freq_min);

if ( defined @ARGV ) {
    set_governor(@ARGV);
}
else {
    print "cpuscaling: too few arguments\n";
    wtf();
}

# EOF
  • Data: 05 Oct 2006
  • Autore: Gallows
  • Versione: 0.1.1
Strumenti personali
Namespace

Varianti