-
-
Notifications
You must be signed in to change notification settings - Fork 673
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for reading thermal stats.
- Loading branch information
1 parent
eb8ebfc
commit a5e7380
Showing
1 changed file
with
164 additions
and
53 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
/* Copyright 2021 Aristocratos ([email protected]) | ||
Copyright 2024 Santhosh Raju ([email protected]) | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
|
@@ -42,13 +43,10 @@ tab-size = 4 | |
#include <sys/siginfo.h> | ||
#include <sys/proc.h> | ||
#include <sys/types.h> | ||
//#include <sys/user.h> | ||
#include <sys/param.h> | ||
#include <sys/ucred.h> | ||
#include <sys/mount.h> | ||
#include <sys/vmmeter.h> | ||
//#include <sys/limits.h> | ||
//#include <sys/sensors.h> | ||
#include <sys/disk.h> | ||
#include <vector> | ||
#include <kvm.h> | ||
|
@@ -264,38 +262,151 @@ namespace Cpu { | |
|
||
bool get_sensors() { | ||
got_sensors = false; | ||
// if (Config::getB("show_coretemp") and Config::getB("check_temp")) { | ||
// if (get_sensor(string("cpu0") , SENSOR_TEMP, 0) > 0) { | ||
// got_sensors = true; | ||
// current_cpu.temp_max = 100; // we don't have this info | ||
// } else { | ||
// Logger::warning("Could not get temp sensor"); | ||
// } | ||
// } | ||
prop_dictionary_t dict; | ||
prop_object_t fields_array; | ||
// List of common thermal sensors in NetBSD. | ||
const string sensors[6] = { | ||
"acpitz0", | ||
"acpitz1", | ||
"coretemp0", | ||
"coretemp1", | ||
"thinkpad0", | ||
"amdzentemp0" | ||
}; | ||
|
||
int fd = open(_PATH_SYSMON, O_RDONLY); | ||
if (fd == -1) { | ||
Logger::warning("failed to open " + string(_PATH_SYSMON)); | ||
return got_sensors; | ||
} | ||
|
||
if (prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &dict) != 0) { | ||
if (fd != -1) { | ||
close(fd); | ||
} | ||
Logger::warning("failed to open envsys dict"); | ||
return got_sensors; | ||
} | ||
|
||
if (prop_dictionary_count(dict) == 0) { | ||
if (fd != -1) { | ||
close(fd); | ||
} | ||
Logger::warning("no drivers registered for envsys"); | ||
return got_sensors; | ||
} | ||
|
||
// Search through a known list of sensors and break the loop on finding the first. | ||
for(const string &sensor : sensors) { | ||
fields_array = prop_dictionary_get(prop_dictionary_t(dict), sensor.c_str()); | ||
if (prop_object_type(fields_array) != PROP_TYPE_ARRAY) { | ||
Logger::warning("unknown device " + sensor); | ||
} else { | ||
Cpu::cpu_sensor = sensor; | ||
break; | ||
} | ||
} | ||
if (prop_object_type(fields_array) != PROP_TYPE_ARRAY) { | ||
if (fd != -1) { | ||
close(fd); | ||
} | ||
return got_sensors; | ||
} | ||
|
||
if (Config::getB("show_coretemp") and Config::getB("check_temp")) { | ||
got_sensors = true; | ||
} | ||
return got_sensors; | ||
} | ||
|
||
#define MUKTOC(v) ((v - 273150000) / 1000000.0) | ||
|
||
void update_sensors() { | ||
// int temp = 0; | ||
// int p_temp = 0; | ||
// | ||
// temp = get_sensor(string("cpu0"), 0); | ||
// if (temp > -1) { | ||
// temp = MUKTOC(temp); | ||
// p_temp = temp; | ||
// for (int i = 0; i < Shared::coreCount; i++) { | ||
// if (cmp_less(i + 1, current_cpu.temp.size())) { | ||
// current_cpu.temp.at(i + 1).push_back(temp); | ||
// if (current_cpu.temp.at(i + 1).size() > 20) | ||
// current_cpu.temp.at(i + 1).pop_front(); | ||
// } | ||
// } | ||
// current_cpu.temp.at(0).push_back(p_temp); | ||
// if (current_cpu.temp.at(0).size() > 20) | ||
// current_cpu.temp.at(0).pop_front(); | ||
// } | ||
int64_t current_temp = -1; | ||
current_cpu.temp_max = 95; | ||
prop_dictionary_t dict, fields, props; | ||
|
||
int fd = open(_PATH_SYSMON, O_RDONLY); | ||
if (fd == -1) { | ||
Logger::warning("failed to open " + string(_PATH_SYSMON)); | ||
return; | ||
} | ||
|
||
if (prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &dict) != 0) { | ||
if (fd != -1) { | ||
close(fd); | ||
} | ||
Logger::warning("failed to open envsys dict"); | ||
return; | ||
} | ||
|
||
if (prop_dictionary_count(dict) == 0) { | ||
if (fd != -1) { | ||
close(fd); | ||
} | ||
Logger::warning("no drivers registered for envsys"); | ||
return; | ||
} | ||
|
||
prop_object_t fields_array = prop_dictionary_get(prop_dictionary_t(dict), Cpu::cpu_sensor.c_str()); | ||
if (prop_object_type(fields_array) != PROP_TYPE_ARRAY) { | ||
if (fd != -1) { | ||
close(fd); | ||
} | ||
Logger::warning("unknown device " + Cpu::cpu_sensor); | ||
return; | ||
} | ||
|
||
prop_object_iterator_t fields_iter = prop_array_iterator(prop_array_t(fields_array)); | ||
if (fields_iter == NULL) { | ||
if (fd != -1) { | ||
close(fd); | ||
} | ||
return; | ||
} | ||
|
||
string prop_description = "no description"; | ||
while ((fields = (prop_dictionary_t) prop_object_iterator_next(prop_object_iterator_t(fields_iter))) != NULL) { | ||
props = (prop_dictionary_t) prop_dictionary_get(fields, "device-properties"); | ||
if (props != NULL) continue; | ||
|
||
prop_object_t cur_value = prop_dictionary_get(fields, "cur-value"); | ||
prop_object_t max_value = prop_dictionary_get(fields, "critical-max"); | ||
prop_object_t description = prop_dictionary_get(fields, "description"); | ||
|
||
if (description == NULL || cur_value == NULL) { | ||
continue; | ||
} | ||
|
||
|
||
prop_description = prop_string_cstring(prop_string_t(description)); | ||
|
||
if (prop_description == "temperature") { | ||
current_temp = prop_number_integer_value(prop_number_t(cur_value)); | ||
if (max_value != NULL) { | ||
current_cpu.temp_max = MUKTOC(prop_number_integer_value(prop_number_t(max_value))); | ||
} | ||
} | ||
} | ||
|
||
prop_object_iterator_release(fields_iter); | ||
prop_object_release(dict); | ||
|
||
if (current_temp > -1) { | ||
current_temp = MUKTOC(current_temp); | ||
for (int i = 0; i < Shared::coreCount; i++) { | ||
if (cmp_less(i + 1, current_cpu.temp.size())) { | ||
current_cpu.temp.at(i + 1).push_back(current_temp); | ||
if (current_cpu.temp.at(i + 1).size() > 20) { | ||
current_cpu.temp.at(i + 1).pop_front(); | ||
} | ||
} | ||
} | ||
current_cpu.temp.at(0).push_back(current_temp); | ||
if (current_cpu.temp.at(0).size() > 20) { | ||
current_cpu.temp.at(0).pop_front(); | ||
} | ||
} | ||
|
||
} | ||
|
||
|
@@ -357,8 +468,8 @@ namespace Cpu { | |
|
||
prop_dictionary_t dict, fields, props; | ||
|
||
int64_t totalCharge = 0; | ||
int64_t totalCapacity = 0; | ||
int64_t total_charge = 0; | ||
int64_t total_capacity = 0; | ||
|
||
int fd = open(_PATH_SYSMON, O_RDONLY); | ||
if (fd == -1) { | ||
|
@@ -385,8 +496,8 @@ namespace Cpu { | |
return {0, 0.0, 0, ""}; | ||
} | ||
|
||
prop_object_t fieldsArray = prop_dictionary_get(prop_dictionary_t(dict), "acpibat0"); | ||
if (prop_object_type(fieldsArray) != PROP_TYPE_ARRAY) { | ||
prop_object_t fields_array = prop_dictionary_get(prop_dictionary_t(dict), "acpibat0"); | ||
if (prop_object_type(fields_array) != PROP_TYPE_ARRAY) { | ||
if (fd != -1) { | ||
close(fd); | ||
} | ||
|
@@ -395,8 +506,8 @@ namespace Cpu { | |
return {0, 0.0, 0, ""}; | ||
} | ||
|
||
prop_object_iterator_t fieldsIter = prop_array_iterator(prop_array_t(fieldsArray)); | ||
if (fieldsIter == NULL) { | ||
prop_object_iterator_t fields_iter = prop_array_iterator(prop_array_t(fields_array)); | ||
if (fields_iter == NULL) { | ||
if (fd != -1) { | ||
close(fd); | ||
} | ||
|
@@ -405,56 +516,56 @@ namespace Cpu { | |
} | ||
|
||
/* only assume battery is not present if explicitly stated */ | ||
bool isBattery = false; | ||
int64_t isPresent = 1; | ||
int64_t curCharge = 0; | ||
int64_t maxCharge = 0; | ||
bool is_battery = false; | ||
int64_t is_present = 1; | ||
int64_t cur_charge = 0; | ||
int64_t max_charge = 0; | ||
string status = "unknown"; | ||
string prop_description = "no description"; | ||
|
||
while ((fields = (prop_dictionary_t) prop_object_iterator_next(prop_object_iterator_t(fieldsIter))) != NULL) { | ||
while ((fields = (prop_dictionary_t) prop_object_iterator_next(prop_object_iterator_t(fields_iter))) != NULL) { | ||
props = (prop_dictionary_t) prop_dictionary_get(fields, "device-properties"); | ||
if (props != NULL) continue; | ||
|
||
prop_object_t curValue = prop_dictionary_get(fields, "cur-value"); | ||
prop_object_t maxValue = prop_dictionary_get(fields, "max-value"); | ||
prop_object_t cur_value = prop_dictionary_get(fields, "cur-value"); | ||
prop_object_t max_value = prop_dictionary_get(fields, "max-value"); | ||
prop_object_t description = prop_dictionary_get(fields, "description"); | ||
|
||
if (description == NULL || curValue == NULL) { | ||
if (description == NULL || cur_value == NULL) { | ||
continue; | ||
} | ||
|
||
|
||
prop_description = prop_string_cstring(prop_string_t(description)); | ||
|
||
if (prop_description == "charge") { | ||
if (maxValue == NULL) { | ||
if (max_value == NULL) { | ||
continue; | ||
} | ||
curCharge = prop_number_integer_value(prop_number_t(curValue)); | ||
maxCharge = prop_number_integer_value(prop_number_t(maxValue)); | ||
cur_charge = prop_number_integer_value(prop_number_t(cur_value)); | ||
max_charge = prop_number_integer_value(prop_number_t(max_value)); | ||
} | ||
|
||
if (prop_description == "present") { | ||
isPresent = prop_number_integer_value(prop_number_t(curValue)); | ||
is_present = prop_number_integer_value(prop_number_t(cur_value)); | ||
} | ||
|
||
if (prop_description == "charging") { | ||
status = prop_description; | ||
string charging_type = prop_string_cstring(prop_string_t(prop_dictionary_get(fields, "type"))); | ||
isBattery = charging_type == "Battery charge" ? true : false; | ||
is_battery = charging_type == "Battery charge" ? true : false; | ||
} | ||
|
||
if (isBattery && isPresent) { | ||
totalCharge += curCharge; | ||
totalCapacity += maxCharge; | ||
if (is_battery && is_present) { | ||
total_charge += cur_charge; | ||
total_capacity += max_charge; | ||
} | ||
} | ||
|
||
prop_object_iterator_release(fieldsIter); | ||
prop_object_iterator_release(fields_iter); | ||
prop_object_release(dict); | ||
|
||
uint32_t percent = ((double)totalCharge / (double)totalCapacity) * 100.0; | ||
uint32_t percent = ((double)total_charge / (double)total_capacity) * 100.0; | ||
|
||
if (percent == 100) { | ||
status = "full"; | ||
|