#!/usr/bin/perl -w use strict; require Getopt::Std; my %opts; my ($user,$nice,$sys,$idle,$apmstate,$charge,$chargenumeral,$acsave,$VERBOSE,$batterypower,$deltaidle,$fullpower); my $baselineidle = 0; # Set initial power expenditure modes system("tpctl --quiet -pma=high > /dev/null"); system("tpctl --quiet -pmb=high > /dev/null"); $fullpower = 1; # Install Signal Handlers $SIG{QUIT} = $SIG{PIPE} = $SIG{INT} = $SIG{USR1} = $SIG{USR2} = \&signalhandler; Getopt::Std::getopt(':v',\%opts); if (exists($opts{v})) { $VERBOSE=1; } else { $VERBOSE=0; } while (1) { # Get CPU status information open(STAT,"/proc/stat") or die $!; $_ = ; close(STAT); # Parse the CPU status information ($user,$nice,$sys,$idle) = /^cpu\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$/; # Get power status information open(APM,"/proc/apm") or die $!; $_ = ; close(APM); # Parse the power status information ($apmstate,$charge) = /^\S+\s+\S+\s+\S+\s+(\S+)\s+\S+\s+\S+\s+(\S+)/; if ($apmstate eq '0x00') { # We're on battery power if (!$batterypower) { # But we weren't before print "apmiser: Now on battery---will start saving power.\n" if $VERBOSE; $batterypower = 1; } } else { # We're on AC power if ($batterypower) { # But we were on battery power before print "apmiser: Now on AC power.\n" if $VERBOSE; $batterypower = 0; } # Find out charge level $chargenumeral = $charge; $chargenumeral =~ s/%//g; if ($chargenumeral < 95) { # We're under 95% charge if (!$acsave) { # But we weren't previously saving power print "apmiser: Will start saving AC power for charging ($charge).\n" if $VERBOSE; $acsave = 1; } } else { # We're at 95% charge or higher if ($acsave) { # And we were previously saving power print "apmiser: Will stop saving AC power for charging ($charge).\n" if $VERBOSE; system("tpctl --quiet -pma=high > /dev/null"); # U-G-L-Y $acsave = 0; } } } # Calculate number of jiffies (well, not quite) we've been idling since last iteration. $deltaidle = $idle - $baselineidle; if ($baselineidle && ($batterypower || $acsave)) { # This isn't the first iteration and we are saving power. if ($deltaidle < 5) { # We're using the CPU intensely if (!$fullpower) { # But we're not at full power print "apmiser: Full power, Mr. Scott! ($deltaidle idle jiffies/200ms)\n" if $VERBOSE; system("tpctl --quiet -pmb=high > /dev/null") if ($batterypower); # U-G-L-Y system("tpctl --quiet -pma=high > /dev/null") if ($acsave); # U-G-L-Y $fullpower = 1; } } else { # We're not using the CPU intensely if ($fullpower) { # But we're at full power print "apmiser: Stand down, Mr. Scott. ($deltaidle idle jiffies/200ms)\n" if $VERBOSE; system("tpctl --quiet -pmb=auto > /dev/null") if ($batterypower); # U-G-L-Y system("tpctl --quiet -pma=auto > /dev/null") if ($acsave); # U-G-L-Y $fullpower = 0; } } } $baselineidle = $idle; # Sleep for 200ms select(undef, undef, undef, 0.2); } sub signalhandler { # It seems a signal was sent # Restore power expenditure modes to defaults print "apmiser: Signal caught---restoring default power expenditure modes and exiting.\n" if $VERBOSE; system("tpctl --quiet -pma=high > /dev/null"); system("tpctl --quiet -pmb=auto > /dev/null"); exit(1); }