Last active
February 3, 2019 01:32
-
-
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 file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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