Skip to content

Instantly share code, notes, and snippets.

@niknah
Last active February 3, 2019 01:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save niknah/f754d391e62faa633b0070ff008b5653 to your computer and use it in GitHub Desktop.
Save niknah/f754d391e62faa633b0070ff008b5653 to your computer and use it in GitHub Desktop.
This is a simple alternative to thermald. If you are not happy with thermald, try this instead.
// This software was written by Naoki Shibata in 2018. https://gist.github.com/shibatch
// No copyright is claimed, and the software is hereby placed in the public domain.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int setFreq(double d) {
int c = (int)(d * (1.0 / 1000));
for(int i=0;;i++) {
char fn[256];
sprintf(fn, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_max_freq", i);
FILE *fp = fopen(fn, "w");
if (fp == NULL) return i;
fprintf(fp, "%d", c);
fclose(fp);
}
}
char hwMonFile[FILENAME_MAX];
void getHwMonFile() {
struct stat st;
for(int i=0;i<100;i++) {
sprintf(hwMonFile,"/sys/bus/platform/devices/coretemp.0/hwmon/hwmon%d/temp1_input",i);
if(stat(hwMonFile,&st)==0) {
break;
}
}
}
int readNumber(char *fn) {
FILE *fp = fopen(fn, "r");
if (fp == NULL) abort();
int ret;
if (fscanf(fp, "%d", &ret) != 1) abort();
fclose(fp);
return ret;
}
double getTemp() { return readNumber(hwMonFile) * (1.0 / 1000); }
double getMinFreq() { return readNumber("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq") * 1000.0; }
double getMaxFreq() { return readNumber("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq") * 1000.0; }
double getFreq() { return readNumber("/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq") * 1000.0; }
int main(int argc, char **argv) {
if (argc == 1) {
fprintf(stderr, "This program controls the CPU frequency to make its temperature close to the target\n");
fprintf(stderr, "Usage : %s <target temp in degrees> [<interval in second>] [-]\n", argv[0]);
fprintf(stderr, "\nhttps://gist.github.com/shibatch\n");
exit(-1);
}
double targetTemp = 70.0;
double interval = 10.0;
if (argc > 1) targetTemp = (int)(atof(argv[1]));
if (argc > 2) interval = atof(argv[2]);
int verbose = argc > 3;
double prevTemp = -1;
double C1 = 2000000.0 * interval, C2 = 2000000.0 * interval;
getHwMonFile();
if(verbose) printf("%s\n",hwMonFile);
double curFreq = getFreq();
double maxFreq = getMaxFreq(), minFreq = getMinFreq();
for(;;) {
double curTemp = getTemp();
if (prevTemp == -1) prevTemp = curTemp;
if (verbose) printf("clock = %dMHz, temp = %.2g, target = %.2g\n", (int)(curFreq / 1e+6), curTemp, targetTemp);
double nextFreq = curFreq + C1 * (targetTemp - curTemp) - C2 * (curTemp - prevTemp);
if (nextFreq > maxFreq) nextFreq = maxFreq;
if (nextFreq < minFreq) nextFreq = minFreq;
setFreq(nextFreq);
curFreq = nextFreq;
prevTemp = curTemp;
usleep((useconds_t)(interval * 1000000.0));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment