mirror of
https://github.com/aristocratos/btop.git
synced 2024-05-18 11:22:46 +12:00
Add support for reading thermal stats.
This commit is contained in:
parent
f9daa22d12
commit
ea0f453a14
|
@ -1,4 +1,5 @@
|
|||
/* Copyright 2021 Aristocratos (jakob@qvantnet.com)
|
||||
Copyright 2024 Santhosh Raju (fox@NetBSD.org)
|
||||
|
||||
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,22 +516,22 @@ 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;
|
||||
}
|
||||
|
||||
|
@ -428,33 +539,33 @@ namespace Cpu {
|
|||
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";
|
||||
|
|
Loading…
Reference in a new issue