Skip to content

Commit

Permalink
feat: add fail soft option to store valid temperature
Browse files Browse the repository at this point in the history
  • Loading branch information
narugit committed Aug 17, 2024
1 parent b0aba09 commit 46f54c7
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 5 deletions.
11 changes: 8 additions & 3 deletions main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ void usage(char* prog) {
std::cout << " -g : list GPU temperatures (Celsius)" << std::endl;
std::cout << " -h : help" << std::endl;
std::cout << " -l : list all keys and values" << std::endl;
std::cout << " -f : fail-soft mode to store recent valid sensor value" << std::endl;
std::cout << " -v : version" << std::endl;
std::cout << " -n : tries to query the temperature sensors for n times (e.g. -n3)";
std::cout << " (1 second interval) until a valid value is returned" << std::endl;
Expand All @@ -22,9 +23,10 @@ int main(int argc, char *argv[]) {
unsigned int attempts = 1;

kern_return_t result;
int op = smctemp::kOpNone;
int op = smctemp::kOpNone;
bool isFailSoft = false;

while ((c = getopt(argc, argv, "clvhn:g")) != -1) {
while ((c = getopt(argc, argv, "clvfhn:g")) != -1) {
switch(c) {
case 'c':
op = smctemp::kOpReadCpuTemp;
Expand All @@ -44,6 +46,9 @@ int main(int argc, char *argv[]) {
case 'l':
op = smctemp::kOpList;
break;
case 'f':
isFailSoft = true;
break;
case 'v':
std::cout << smctemp::kVersion << std::endl;
return 0;
Expand All @@ -61,7 +66,7 @@ int main(int argc, char *argv[]) {
}

smctemp::SmcAccessor smc_accessor = smctemp::SmcAccessor();
smctemp::SmcTemp smc_temp = smctemp::SmcTemp();
smctemp::SmcTemp smc_temp = smctemp::SmcTemp(isFailSoft);

switch(op) {
case smctemp::kOpList:
Expand Down
48 changes: 47 additions & 1 deletion smctemp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@

#include <IOKit/IOKitLib.h>
#include <libkern/OSAtomic.h>
#include <sys/stat.h>

#include <cerrno>
#include <cmath>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <limits>
Expand Down Expand Up @@ -382,10 +386,36 @@ kern_return_t SmcAccessor::PrintAll() {
return kIOReturnSuccess;
}

SmcTemp::SmcTemp(bool isFailSoft)
: is_fail_soft_(isFailSoft) {
if (is_fail_soft_) {
if (mkdir(storage_path_.c_str(), 0777) && errno != EEXIST) {
std::cerr << "Failed to create directory: " << storage_path_ << std::endl;
}
}
}

bool SmcTemp::IsValidTemperature(double temperature, const std::pair<unsigned int, unsigned int>& limits) {
return temperature > limits.first && temperature < limits.second;
}

bool SmcTemp::StoreValidTemperature(double temperature, std::string file_name) {
if (!is_fail_soft_) {
return false;
}
std::ofstream out_file(storage_path_ + file_name);

if (!out_file) {
std::cerr << "Failed to open the file: " << storage_path_ + file_name << std::endl;
return false;
}

out_file << temperature;
out_file.close();

return true;
}

double SmcTemp::CalculateAverageTemperature(const std::vector<std::string>& sensors,
const std::pair<unsigned int, unsigned int>& limits) {
double temp = 0.0;
Expand All @@ -411,18 +441,22 @@ double SmcTemp::GetCpuTemp() {
// https://github.com/narugit/smctemp/issues/2
temp = smc_accessor_.ReadValue(kSensorTC0D);
if (IsValidTemperature(temp, valid_temperature_limits)) {
StoreValidTemperature(temp, cpu_file_);
return temp;
}
temp = smc_accessor_.ReadValue(kSensorTC0E);
if (IsValidTemperature(temp, valid_temperature_limits)) {
StoreValidTemperature(temp, cpu_file_);
return temp;
}
temp = smc_accessor_.ReadValue(kSensorTC0F);
if (IsValidTemperature(temp, valid_temperature_limits)) {
StoreValidTemperature(temp, cpu_file_);
return temp;
}
temp = smc_accessor_.ReadValue(kSensorTC0P);
if (IsValidTemperature(temp, valid_temperature_limits)) {
StoreValidTemperature(temp, cpu_file_);
return temp;
}
#elif defined(ARCH_TYPE_ARM64)
Expand Down Expand Up @@ -504,11 +538,18 @@ double SmcTemp::GetCpuTemp() {

temp = CalculateAverageTemperature(sensors, valid_temperature_limits);
if (temp > std::numeric_limits<double>::epsilon()) {
if (IsValidTemperature(temp, valid_temperature_limits)) {
StoreValidTemperature(temp, cpu_file_);
}
return temp;
}

temp = CalculateAverageTemperature(aux_sensors, valid_temperature_limits);
if (IsValidTemperature(temp, valid_temperature_limits)) {
StoreValidTemperature(temp, cpu_file_);
}
#endif

return temp;
}

Expand All @@ -518,10 +559,12 @@ double SmcTemp::GetGpuTemp() {
const std::pair<unsigned int, unsigned int> valid_temperature_limits{0, 110};
temp = smc_accessor_.ReadValue(kSensorTG0D);
if (IsValidTemperature(temp, valid_temperature_limits)) {
StoreValidTemperature(temp, gpu_file_);
return temp;
}
temp = smc_accessor_.ReadValue(kSensorTPCD);
if (IsValidTemperature(temp, valid_temperature_limits)) {
if (IsValidTemperature(temp, valid_temperature_limits)) {
StoreValidTemperature(temp, gpu_file_);
return temp;
}
#elif defined(ARCH_TYPE_ARM64)
Expand Down Expand Up @@ -553,6 +596,9 @@ double SmcTemp::GetGpuTemp() {
return temp;
}
temp = CalculateAverageTemperature(sensors, valid_temperature_limits);
if (IsValidTemperature(temp, valid_temperature_limits)) {
StoreValidTemperature(temp, gpu_file_);
}
#endif
return temp;
}
Expand Down
7 changes: 6 additions & 1 deletion smctemp.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,15 @@ class SmcTemp {
double CalculateAverageTemperature(const std::vector<std::string>& sensors,
const std::pair<unsigned int, unsigned int>& limits);
bool IsValidTemperature(double temperature, const std::pair<unsigned int, unsigned int>& limits);
bool StoreValidTemperature(double temperature, std::string file_name);
SmcAccessor smc_accessor_;
bool is_fail_soft_;
const std::string storage_path_ = "/tmp/smctemp/";
const std::string cpu_file_ = "cpu_temperature.txt";
const std::string gpu_file_ = "gpu_temperature.txt";

public:
SmcTemp() = default;
explicit SmcTemp(bool isFailSoft);
~SmcTemp() = default;
double GetCpuTemp();
double GetGpuTemp();
Expand Down

0 comments on commit 46f54c7

Please # to comment.