diff --git a/src/netbsd/btop_collect.cpp b/src/netbsd/btop_collect.cpp index c5c82fb..ad01367 100644 --- a/src/netbsd/btop_collect.cpp +++ b/src/netbsd/btop_collect.cpp @@ -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 #include #include -//#include #include #include #include #include -//#include -//#include #include #include #include @@ -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";