Code: Select all
// Copyright 2011 SoftwareGurl
// Simple Cpu speed power management that doesn't care about transition latancy
// A D D G P L S T U F F H E R E
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int vflag = 0,cpuflag = 1,battflag = 0,logflag=0;
char *battvalue = NULL;
char version[5]="0.04";
float cpu_ulow=550000,cpu_low=825000,cpu_high=2200000,cpu_utrig=20,cpu_ltrig=30,cpu_htrig=50,cpu_hfreq=2200000,cpu_hfold=0;
float timeout=1,cpu=0,used=0,oldused=0,cputotal=0,oldcputotal=0,cpuold=0;
char logout[20], logfile[50]="/tmp/mycpuspeed.log";
FILE *meminfo,*cpuinfo,*cpuspeed,*cpulog;
void checkup() {
if((cpuinfo=fopen("/proc/stat","r"))==NULL){
fprintf(stderr,"Error opening stat");
exit(1);
}
unsigned long user,nice,sys,idle,iowait,irq,softirq,virt,virt2;
char buf2[190];
char *p;
int i;
fgets(buf2,190,cpuinfo); strtok(buf2, " ");
p=strtok(NULL, " "); user=strtol(p, NULL, 10);
p=strtok(NULL, " "); nice=strtol(p, NULL, 10);
p=strtok(NULL, " "); sys=strtol(p, NULL, 10);
p=strtok(NULL, " "); idle=strtol(p, NULL, 10);
p=strtok(NULL, " "); iowait=strtol(p, NULL, 10);
p=strtok(NULL, " "); irq=strtol(p, NULL, 10);
p=strtok(NULL, " "); softirq=strtol(p, NULL,10);
p=strtok(NULL, " "); virt=strtol(p, NULL, 10);
p=strtok(NULL, " "); virt2=strtol(p, NULL, 10);
fclose(cpuinfo);
used=(float)(user+nice+sys+irq+softirq+virt+virt2);
cputotal=used+(float)idle+(float)iowait;
cpu=((used-oldused)/(cputotal-oldcputotal))*(float)100;
oldused=used;
oldcputotal=cputotal;
if(vflag==1) {
printf("cpu %.1f total %.1f used %.1f \n",cpu ,cputotal, used);
}
if(cpu<cpu_ltrig){
if(cpu_hfreq>cpu_low) {
cpu_hfreq=cpu_low;
}
}
if(cpu>cpu_ltrig) {
cpu_hfreq=cpu_low;
}
if(cpu<cpu_utrig) {
cpu_hfreq=cpu_ulow;
}
if(cpu>cpu_htrig){
cpu_hfreq=cpu_high;
}
if(cpu!=cpuold) {
if((cpuspeed=fopen("/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq","w"))==NULL){
fprintf(stderr,"Error opening meminfo");
exit(1);
}
fprintf(cpuspeed,"%.0f",cpu_hfreq);
fclose(cpuspeed);
cpuold=cpu;
}
if(vflag==1) {
printf("%.0f %.1f\n", cpu_hfreq, cpu);
}
if(logflag==1) {
if((cpulog=fopen(logfile,"a"))==NULL){
fprintf(stderr,"Error opening meminfo");
exit(1);
}
fprintf(cpulog, "%.0f %.1f\n", cpu_hfreq, cpu);
fclose(cpulog);
}
return;
}
// ###################################################################
int parseopts (int argc, char **argv) {
int index;
int c;
opterr = 0;
while ((c = getopt (argc, argv, "vqlb:c")) != -1)
switch (c)
{
case 'v':
vflag = 1;
break;
case 'q':
vflag = 0;
break;
case 'l':
logflag = 1;
break;
case 'c':
cpuflag = 1;
break;
case 'b':
battvalue = optarg;
break;
case '?':
if (optopt == 'c')
fprintf (stderr, "Option -%c requires an argument.\n", optopt);
else if (isprint (optopt))
fprintf (stderr, "Unknown option `-%c'.\n", optopt);
else
fprintf (stderr,
"Unknown option character `\\x%x'.\n",
optopt);
return 1;
default:
abort ();
}
if(vflag==1) {
printf ("vflag = %d, cpuflag = %d, battvalue = %s\n",
vflag, cpuflag, battvalue);
for (index = optind; index < argc; index++)
printf ("Non-option argument %s\n", argv[index]);
}
return 0;
}
// ###################################################################
int main(int argc, char **argv) {
fprintf(stdout,"hello world. user space cpu speed version %s\n",version);
parseopts(argc,argv);
while(1)
{
// fprintf(stdout,"hello world. user space cpu speed version %s\n",version);
checkup();
sleep(timeout);
}
exit(0);
}
// BIG REMINDER TO SELF
// ADD A VERSION LOG HERE
// O R E L S E
// v0.01 first version. Used watcher from Curaga as a start and stripped most away
// Thanks Curaga.
// v0.02 improve efficiency of cpu if-then block
// more code stripping and cleanup
// v0.03 just code cleanup and debugging
// v0.04 added parseopts subroutine to handle getopt
// from an example on gnu.org
// added this version log
// start doing license stuff
// v0.05 RESERVED FOR FUTURE USE
Code: Select all
g++ -Os -fno-exceptions -o mycpuspeed mycpuspeed.c