mirror of https://github.com/aristocratos/btop.git
Add power CPU consumption monitoring on linux
This commit is contained in:
parent
1b126f55e3
commit
dcd3642718
|
@ -119,6 +119,8 @@ namespace Config {
|
|||
|
||||
{"show_uptime", "#* Shows the system uptime in the CPU box."},
|
||||
|
||||
{"show_cpu_watts", "#* Shows the CPU package current power consumption in watts."},
|
||||
|
||||
{"check_temp", "#* Show cpu temperature."},
|
||||
|
||||
{"cpu_sensor", "#* Which sensor to use for cpu temperature, use options menu to select from list of available sensors."},
|
||||
|
@ -239,6 +241,7 @@ namespace Config {
|
|||
{"cpu_single_graph", false},
|
||||
{"cpu_bottom", false},
|
||||
{"show_uptime", true},
|
||||
{"show_cpu_watts", true},
|
||||
{"check_temp", true},
|
||||
{"show_coretemp", true},
|
||||
{"show_cpu_freq", true},
|
||||
|
|
|
@ -705,6 +705,17 @@ namespace Cpu {
|
|||
}
|
||||
}
|
||||
|
||||
//? Package power
|
||||
if (Config::getB("show_cpu_watts") && supports_watts && cy < b_height - 1 and b_columns > 1) {
|
||||
string cwatts_pre;
|
||||
string cwatts_post;
|
||||
if (b_column_size == 2 and show_temps) { cwatts_pre = "Package Power:"; cwatts_post = "Watts"; }
|
||||
else if (b_column_size == 2 or (b_column_size == 1 and show_temps)) { cwatts_pre = "Pkg Power:"; cwatts_post = "W"; }
|
||||
else if (b_column_size == 1 or (b_column_size == 0 and show_temps)) { cwatts_pre = "PP:"; cwatts_post = "W"; }
|
||||
string cwatts = fmt::format("{} {:.2f} {}", cwatts_pre, cpu.usage_watts, cwatts_post);
|
||||
out += Mv::to(b_y + b_height - 2, b_x + 1) + Theme::c("main_fg") + cwatts;
|
||||
}
|
||||
|
||||
//? Load average
|
||||
if (cy < b_height - 1 and cc <= b_columns) {
|
||||
string lavg_pre;
|
||||
|
|
|
@ -402,6 +402,13 @@ namespace Menu {
|
|||
"\"/uptime\" in the formatting.",
|
||||
"",
|
||||
"True or False."},
|
||||
{"show_cpu_watts",
|
||||
"Shows the CPU power consumption in watts.",
|
||||
"",
|
||||
"Note: Root permissions are required",
|
||||
"Supports only Intel x86 CPUs on Linux",
|
||||
"",
|
||||
"True or False."},
|
||||
},
|
||||
{
|
||||
{"mem_below_net",
|
||||
|
|
|
@ -89,7 +89,7 @@ namespace Shared {
|
|||
namespace Cpu {
|
||||
extern string box;
|
||||
extern int x, y, width, height, min_width, min_height;
|
||||
extern bool shown, redraw, got_sensors, cpu_temp_only, has_battery;
|
||||
extern bool shown, redraw, got_sensors, cpu_temp_only, has_battery, supports_watts;
|
||||
extern string cpuName, cpuHz;
|
||||
extern vector<string> available_fields;
|
||||
extern vector<string> available_sensors;
|
||||
|
@ -113,6 +113,7 @@ namespace Cpu {
|
|||
vector<deque<long long>> temp;
|
||||
long long temp_max = 0;
|
||||
array<double, 3> load_avg;
|
||||
float usage_watts = 0;
|
||||
};
|
||||
|
||||
//* Collect cpu stats and temperatures
|
||||
|
|
|
@ -77,7 +77,7 @@ namespace Cpu {
|
|||
vector<string> available_fields = {"total"};
|
||||
vector<string> available_sensors = {"Auto"};
|
||||
cpu_info current_cpu;
|
||||
bool got_sensors = false, cpu_temp_only = false;
|
||||
bool got_sensors = false, cpu_temp_only = false, supports_watts = false;
|
||||
|
||||
//* Populate found_sensors map
|
||||
bool get_sensors();
|
||||
|
|
|
@ -56,6 +56,18 @@ using namespace Tools;
|
|||
using namespace std::literals; // for operator""s
|
||||
//? --------------------------------------------------- FUNCTIONS -----------------------------------------------------
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
long long get_monotonicTimeUSec()
|
||||
{
|
||||
struct timespec time;
|
||||
clock_gettime(CLOCK_MONOTONIC, &time);
|
||||
return time.tv_sec * 1000000 + time.tv_nsec / 1000;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace Cpu {
|
||||
vector<long long> core_old_totals;
|
||||
vector<long long> core_old_idles;
|
||||
|
@ -65,6 +77,7 @@ namespace Cpu {
|
|||
fs::path freq_path = "/sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq";
|
||||
bool got_sensors{}; // defaults to false
|
||||
bool cpu_temp_only{}; // defaults to false
|
||||
bool supports_watts = true;
|
||||
|
||||
//* Populate found_sensors map
|
||||
bool get_sensors();
|
||||
|
@ -666,6 +679,47 @@ namespace Cpu {
|
|||
return {percent, seconds, status};
|
||||
}
|
||||
|
||||
long long get_cpuConsumptionUJoules()
|
||||
{
|
||||
long long consumption = -1;
|
||||
const auto rapl_power_usage_path = "/sys/class/powercap/intel-rapl:0/energy_uj";
|
||||
std::ifstream file(rapl_power_usage_path);
|
||||
if(file.good())
|
||||
{
|
||||
file >> consumption;
|
||||
}
|
||||
return consumption;
|
||||
}
|
||||
|
||||
float get_cpuConsumptionWatts()
|
||||
{
|
||||
static long long previous_usage = 0;
|
||||
static long long previous_timestamp = 0;
|
||||
|
||||
if (previous_usage == 0)
|
||||
{
|
||||
previous_usage = get_cpuConsumptionUJoules();
|
||||
previous_timestamp = get_monotonicTimeUSec();
|
||||
supports_watts = (previous_usage > 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!supports_watts)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto current_timestamp = get_monotonicTimeUSec();
|
||||
auto current_usage = get_cpuConsumptionUJoules();
|
||||
|
||||
auto watts = (float)(current_usage - previous_usage) / (float)(current_timestamp - previous_timestamp);
|
||||
|
||||
previous_timestamp = current_timestamp;
|
||||
previous_usage = current_usage;
|
||||
|
||||
return watts;
|
||||
}
|
||||
|
||||
auto collect(bool no_update) -> cpu_info& {
|
||||
if (Runner::stopping or (no_update and not current_cpu.cpu_percent.at("total").empty())) return current_cpu;
|
||||
auto& cpu = current_cpu;
|
||||
|
@ -803,6 +857,9 @@ namespace Cpu {
|
|||
if (Config::getB("show_battery") and has_battery)
|
||||
current_bat = get_battery();
|
||||
|
||||
if (Config::getB("show_cpu_watts") and supports_watts)
|
||||
current_cpu.usage_watts = get_cpuConsumptionWatts();
|
||||
|
||||
return cpu;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ namespace Cpu {
|
|||
vector<string> available_sensors = {"Auto"};
|
||||
cpu_info current_cpu;
|
||||
fs::path freq_path = "/sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq";
|
||||
bool got_sensors = false, cpu_temp_only = false;
|
||||
bool got_sensors = false, cpu_temp_only = false, supports_watts = false;
|
||||
int core_offset = 0;
|
||||
|
||||
//* Populate found_sensors map
|
||||
|
|
Loading…
Reference in New Issue