3578 lines
101 KiB
Diff
3578 lines
101 KiB
Diff
This patch file contains code from @avafinger's htop_2.2.2 repository.
|
|
|
|
It is the result of diff between:
|
|
https://github.com/avafinger/htop_2.2.2/commit/dc21e5f6
|
|
and:
|
|
https://github.com/hishamhm/htop/tree/2.2.0
|
|
|
|
---
|
|
diff --git a/Armbian_Meter.c b/Armbian_Meter.c
|
|
new file mode 100644
|
|
index 0000000..183032b
|
|
--- /dev/null
|
|
+++ b/Armbian_Meter.c
|
|
@@ -0,0 +1,55 @@
|
|
+/*
|
|
+htop - Armbianversion_Meter.c
|
|
+(C) 2018 @lex
|
|
+*/
|
|
+
|
|
+#include "Armbian_Meter.h"
|
|
+#include "Platform.h"
|
|
+#include "CRT.h"
|
|
+
|
|
+#include "interfaces.h"
|
|
+
|
|
+/*{
|
|
+#include "Meter.h"
|
|
+}*/
|
|
+
|
|
+
|
|
+int Armbianversion_Meter_attributes[] = {
|
|
+ ARMBIAN_VERSION
|
|
+};
|
|
+
|
|
+static void Armbianversion_Meter_setValues(Meter* this, char* buffer, int len) {
|
|
+ int ret;
|
|
+ static char version[256];
|
|
+ static unsigned int use_cached = 0;
|
|
+
|
|
+ if ((use_cached++ % 10)) {
|
|
+ xSnprintf(buffer, len, "%s", version);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ ret = ReadKeyValue( "/etc/armbian-release", "VERSION=", version);
|
|
+
|
|
+ if (ret) {
|
|
+ xSnprintf(buffer, len, "%s", version);
|
|
+ } else {
|
|
+ xSnprintf(buffer, len, "%s", "unknown");
|
|
+ }
|
|
+}
|
|
+
|
|
+MeterClass Armbianversion_Meter_class = {
|
|
+ .super = {
|
|
+ .extends = Class(Meter),
|
|
+ .delete = Meter_delete
|
|
+ },
|
|
+ .updateValues = Armbianversion_Meter_setValues,
|
|
+ .defaultMode = TEXT_METERMODE,
|
|
+ .maxItems = 8,
|
|
+ .total = 100.0,
|
|
+ .attributes = Armbianversion_Meter_attributes,
|
|
+ .name = "Armbianversion",
|
|
+ .uiName = "Armbian version",
|
|
+ .caption = "Armbian : ",
|
|
+};
|
|
+
|
|
+
|
|
diff --git a/Armbian_Meter.h b/Armbian_Meter.h
|
|
new file mode 100644
|
|
index 0000000..146a1ee
|
|
--- /dev/null
|
|
+++ b/Armbian_Meter.h
|
|
@@ -0,0 +1,17 @@
|
|
+/* Do not edit this file. It was automatically generated. */
|
|
+
|
|
+#ifndef HEADER_Armbian_Meter
|
|
+#define HEADER_Armbian_Meter
|
|
+/*
|
|
+htop - Armbianversion_Meter.h
|
|
+(C) 2018 @lex
|
|
+*/
|
|
+
|
|
+#include "Meter.h"
|
|
+
|
|
+extern int Armbianversion_Meter_attributes[];
|
|
+
|
|
+extern MeterClass Armbianversion_Meter_class;
|
|
+
|
|
+
|
|
+#endif
|
|
diff --git a/AvailableMetersPanel.c b/AvailableMetersPanel.c
|
|
index ddb5536..01ee3cd 100644
|
|
--- a/AvailableMetersPanel.c
|
|
+++ b/AvailableMetersPanel.c
|
|
@@ -9,6 +9,8 @@ in the source distribution for its full text.
|
|
#include "MetersPanel.h"
|
|
|
|
#include "CPUMeter.h"
|
|
+#include "CpuFreqMeter.h"
|
|
+#include "CpuTempMeter.h"
|
|
#include "Header.h"
|
|
#include "ListItem.h"
|
|
#include "Platform.h"
|
|
@@ -100,6 +102,8 @@ PanelClass AvailableMetersPanel_class = {
|
|
};
|
|
|
|
AvailableMetersPanel* AvailableMetersPanel_new(Settings* settings, Header* header, Panel* leftMeters, Panel* rightMeters, ScreenManager* scr, ProcessList* pl) {
|
|
+ int i;
|
|
+
|
|
AvailableMetersPanel* this = AllocThis(AvailableMetersPanel);
|
|
Panel* super = (Panel*) this;
|
|
FunctionBar* fuBar = FunctionBar_newEnterEsc("Add ", "Done ");
|
|
@@ -114,7 +118,7 @@ AvailableMetersPanel* AvailableMetersPanel_new(Settings* settings, Header* heade
|
|
Panel_setHeader(super, "Available meters");
|
|
// Platform_meterTypes[0] should be always (&CPUMeter_class), which we will
|
|
// handle separately in the code below.
|
|
- for (int i = 1; Platform_meterTypes[i]; i++) {
|
|
+ for (i = 1; Platform_meterTypes[i]; i++) {
|
|
MeterClass* type = Platform_meterTypes[i];
|
|
assert(type != &CPUMeter_class);
|
|
const char* label = type->description ? type->description : type->uiName;
|
|
@@ -125,7 +129,7 @@ AvailableMetersPanel* AvailableMetersPanel_new(Settings* settings, Header* heade
|
|
int cpus = pl->cpuCount;
|
|
if (cpus > 1) {
|
|
Panel_add(super, (Object*) ListItem_new("CPU average", 0));
|
|
- for (int i = 1; i <= cpus; i++) {
|
|
+ for (i = 1; i <= cpus; i++) {
|
|
char buffer[50];
|
|
xSnprintf(buffer, 50, "%s %d", type->uiName, i);
|
|
Panel_add(super, (Object*) ListItem_new(buffer, i));
|
|
diff --git a/BlockDevice_ioStatsMeter.c b/BlockDevice_ioStatsMeter.c
|
|
new file mode 100644
|
|
index 0000000..9dccbde
|
|
--- /dev/null
|
|
+++ b/BlockDevice_ioStatsMeter.c
|
|
@@ -0,0 +1,711 @@
|
|
+/*
|
|
+htop - BlockDevice_ioStatsMeter.c
|
|
+(C) 2020 @lex
|
|
+*/
|
|
+
|
|
+#include "BlockDevice_ioStatsMeter.h"
|
|
+#include "Platform.h"
|
|
+#include "CRT.h"
|
|
+
|
|
+#include "interfaces.h"
|
|
+
|
|
+/*{
|
|
+#include "Meter.h"
|
|
+}*/
|
|
+
|
|
+
|
|
+int BlockDevice_ioStatsMeter_attributes[] = {
|
|
+ ETH1_INTERFACE
|
|
+};
|
|
+
|
|
+static void BlockDevice_sda_ioStatsMeter_setValues(Meter* this, char* buffer, int len) {
|
|
+ int ret;
|
|
+ float readspeed;
|
|
+ float writespeed;
|
|
+ double refreshdelay;
|
|
+ char block_device[80];
|
|
+ static double old = 0.;
|
|
+ static double now = 0.;
|
|
+ static int flash = 0;
|
|
+ static unsigned long sec_size = 0;
|
|
+ FILE *fp;
|
|
+
|
|
+ if (sec_size == 0) {
|
|
+ xSnprintf(block_device, sizeof(block_device), "/sys/block/%s/queue/hw_sector_size", "sda");
|
|
+ if ((fp = fopen(block_device, "r")) == NULL) {
|
|
+ xSnprintf(buffer, len, "%s", "unavailable");
|
|
+ return;
|
|
+ }
|
|
+ if (fgets(block_device, 79, fp) != NULL) {
|
|
+ sscanf(block_device, "%lu", &sec_size);
|
|
+ }
|
|
+ fclose(fp);
|
|
+ if (sec_size == 0)
|
|
+ sec_size = 1;
|
|
+ }
|
|
+
|
|
+ now = get_wall_time();
|
|
+ refreshdelay = now - old;
|
|
+ if (old == 0.)
|
|
+ refreshdelay = 1.;
|
|
+ old = now;
|
|
+
|
|
+ ret = Platform_getIO_stats("sda", 0, 0);
|
|
+ if (ret) {
|
|
+ if (Platform_BlockDevice_sda_stats.read_sectors_comp > Platform_BlockDevice_sda_stats.read_sectors)
|
|
+ Platform_BlockDevice_sda_stats.read_sectors_comp = 0;
|
|
+ if (Platform_BlockDevice_sda_stats.write_sectors_comp > Platform_BlockDevice_sda_stats.write_sectors)
|
|
+ Platform_BlockDevice_sda_stats.write_sectors_comp = 0;
|
|
+
|
|
+ /* we assume here the refresdelay is 1 sec which sometimes is 1.5, so we have a peak */
|
|
+ readspeed = (Platform_BlockDevice_sda_stats.read_sectors - Platform_BlockDevice_sda_stats.read_sectors_comp) / refreshdelay;
|
|
+ writespeed = (Platform_BlockDevice_sda_stats.write_sectors - Platform_BlockDevice_sda_stats.write_sectors_comp) / refreshdelay;
|
|
+
|
|
+ writespeed = writespeed * sec_size / 1000;
|
|
+ readspeed = readspeed * sec_size / 1000;
|
|
+ if (writespeed >= 1000 || readspeed >= 1000) {
|
|
+ writespeed /= 1000;
|
|
+ readspeed /= 1000;
|
|
+ if (writespeed >= 1000 || readspeed >= 1000) {
|
|
+ writespeed /= 1000;
|
|
+ readspeed /= 1000;
|
|
+ xSnprintf(buffer, len, "%.2f GB/s - %.2f GB/s (R/W)", (float) readspeed, (float) writespeed);
|
|
+ } else {
|
|
+ xSnprintf(buffer, len, "%.2f MB/s - %.2f MB/s (R/W)", (float) readspeed, (float) writespeed);
|
|
+ }
|
|
+ } else {
|
|
+ xSnprintf(buffer, len, "%.2f KB/s - %.2f KB/s (R/W)", (float) readspeed, (float) writespeed);
|
|
+ }
|
|
+
|
|
+ Platform_BlockDevice_sda_stats.read_sectors_comp = Platform_BlockDevice_sda_stats.read_sectors;
|
|
+ Platform_BlockDevice_sda_stats.write_sectors_comp = Platform_BlockDevice_sda_stats.write_sectors;
|
|
+
|
|
+ } else {
|
|
+ if (!(flash % 2))
|
|
+ xSnprintf(buffer, len, "%s", "unavailable");
|
|
+ else
|
|
+ xSnprintf(buffer, len, "%s", "");
|
|
+ flash++;
|
|
+ }
|
|
+}
|
|
+
|
|
+MeterClass BlockDevice_sda_ioStatsMeter_class = {
|
|
+ .super = {
|
|
+ .extends = Class(Meter),
|
|
+ .delete = Meter_delete
|
|
+ },
|
|
+ .updateValues = BlockDevice_sda_ioStatsMeter_setValues,
|
|
+ .defaultMode = TEXT_METERMODE,
|
|
+ .maxItems = 8,
|
|
+ .total = 100.0,
|
|
+ .attributes = BlockDevice_ioStatsMeter_attributes,
|
|
+ .name = "sdastat",
|
|
+ .uiName = "sda speed stat",
|
|
+ .caption = "sda stat: ",
|
|
+};
|
|
+
|
|
+static void BlockDevice_sdb_ioStatsMeter_setValues(Meter* this, char* buffer, int len) {
|
|
+ int ret;
|
|
+ float readspeed;
|
|
+ float writespeed;
|
|
+ double refreshdelay;
|
|
+ char block_device[80];
|
|
+ static double old = 0.;
|
|
+ static double now = 0.;
|
|
+ static int flash = 0;
|
|
+ static unsigned long sec_size = 0;
|
|
+ FILE *fp;
|
|
+
|
|
+ if (sec_size == 0) {
|
|
+ xSnprintf(block_device, sizeof(block_device), "/sys/block/%s/queue/hw_sector_size", "sdb");
|
|
+ if ((fp = fopen(block_device, "r")) == NULL) {
|
|
+ xSnprintf(buffer, len, "%s", "unavailable");
|
|
+ return;
|
|
+ }
|
|
+ if (fgets(block_device, 79, fp) != NULL) {
|
|
+ sscanf(block_device, "%lu", &sec_size);
|
|
+ }
|
|
+ fclose(fp);
|
|
+ if (sec_size == 0)
|
|
+ sec_size = 1;
|
|
+ }
|
|
+
|
|
+ now = get_wall_time();
|
|
+ refreshdelay = now - old;
|
|
+ if (old == 0.)
|
|
+ refreshdelay = 1.;
|
|
+ old = now;
|
|
+
|
|
+ ret = Platform_getIO_stats("sdb", 1, 0);
|
|
+ if (ret) {
|
|
+ if (Platform_BlockDevice_sdb_stats.read_sectors_comp > Platform_BlockDevice_sdb_stats.read_sectors)
|
|
+ Platform_BlockDevice_sdb_stats.read_sectors_comp = 0;
|
|
+ if (Platform_BlockDevice_sdb_stats.write_sectors_comp > Platform_BlockDevice_sdb_stats.write_sectors)
|
|
+ Platform_BlockDevice_sdb_stats.write_sectors_comp = 0;
|
|
+
|
|
+ /* we assume here the refresdelay is 1 sec which sometimes is 1.5, so we have a peak */
|
|
+ readspeed = (Platform_BlockDevice_sdb_stats.read_sectors - Platform_BlockDevice_sdb_stats.read_sectors_comp) / refreshdelay;
|
|
+ writespeed = (Platform_BlockDevice_sdb_stats.write_sectors - Platform_BlockDevice_sdb_stats.write_sectors_comp) / refreshdelay;
|
|
+
|
|
+ writespeed = writespeed * sec_size / 1000;
|
|
+ readspeed = readspeed * sec_size / 1000;
|
|
+ if (writespeed >= 1000 || readspeed >= 1000) {
|
|
+ writespeed /= 1000;
|
|
+ readspeed /= 1000;
|
|
+ if (writespeed >= 1000 || readspeed >= 1000) {
|
|
+ writespeed /= 1000;
|
|
+ readspeed /= 1000;
|
|
+ xSnprintf(buffer, len, "%.2f GB/s - %.2f GB/s (R/W)", (float) readspeed, (float) writespeed);
|
|
+ } else {
|
|
+ xSnprintf(buffer, len, "%.2f MB/s - %.2f MB/s (R/W)", (float) readspeed, (float) writespeed);
|
|
+ }
|
|
+ } else {
|
|
+ xSnprintf(buffer, len, "%.2f KB/s - %.2f KB/s (R/W)", (float) readspeed, (float) writespeed);
|
|
+ }
|
|
+
|
|
+ Platform_BlockDevice_sdb_stats.read_sectors_comp = Platform_BlockDevice_sdb_stats.read_sectors;
|
|
+ Platform_BlockDevice_sdb_stats.write_sectors_comp = Platform_BlockDevice_sdb_stats.write_sectors;
|
|
+
|
|
+ } else {
|
|
+ if (!(flash % 2))
|
|
+ xSnprintf(buffer, len, "%s", "unavailable");
|
|
+ else
|
|
+ xSnprintf(buffer, len, "%s", "");
|
|
+ flash++;
|
|
+ }
|
|
+}
|
|
+
|
|
+MeterClass BlockDevice_sdb_ioStatsMeter_class = {
|
|
+ .super = {
|
|
+ .extends = Class(Meter),
|
|
+ .delete = Meter_delete
|
|
+ },
|
|
+ .updateValues = BlockDevice_sdb_ioStatsMeter_setValues,
|
|
+ .defaultMode = TEXT_METERMODE,
|
|
+ .maxItems = 8,
|
|
+ .total = 100.0,
|
|
+ .attributes = BlockDevice_ioStatsMeter_attributes,
|
|
+ .name = "sdbstat",
|
|
+ .uiName = "sdb speed stat",
|
|
+ .caption = "sdb stat: ",
|
|
+};
|
|
+
|
|
+static void BlockDevice_sdc_ioStatsMeter_setValues(Meter* this, char* buffer, int len) {
|
|
+ int ret;
|
|
+ float readspeed;
|
|
+ float writespeed;
|
|
+ double refreshdelay;
|
|
+ char block_device[80];
|
|
+ static double old = 0.;
|
|
+ static double now = 0.;
|
|
+ static int flash = 0;
|
|
+ static unsigned long sec_size = 0;
|
|
+ FILE *fp;
|
|
+
|
|
+ if (sec_size == 0) {
|
|
+ xSnprintf(block_device, sizeof(block_device), "/sys/block/%s/queue/hw_sector_size", "sdc");
|
|
+ if ((fp = fopen(block_device, "r")) == NULL) {
|
|
+ xSnprintf(buffer, len, "%s", "unavailable");
|
|
+ return;
|
|
+ }
|
|
+ if (fgets(block_device, 79, fp) != NULL) {
|
|
+ sscanf(block_device, "%lu", &sec_size);
|
|
+ }
|
|
+ fclose(fp);
|
|
+ if (sec_size == 0)
|
|
+ sec_size = 1;
|
|
+ }
|
|
+
|
|
+ now = get_wall_time();
|
|
+ refreshdelay = now - old;
|
|
+ if (old == 0.)
|
|
+ refreshdelay = 1.;
|
|
+ old = now;
|
|
+
|
|
+ ret = Platform_getIO_stats("sdc", 2, 0);
|
|
+ if (ret) {
|
|
+ if (Platform_BlockDevice_sdc_stats.read_sectors_comp > Platform_BlockDevice_sdc_stats.read_sectors)
|
|
+ Platform_BlockDevice_sdc_stats.read_sectors_comp = 0;
|
|
+ if (Platform_BlockDevice_sdc_stats.write_sectors_comp > Platform_BlockDevice_sdc_stats.write_sectors)
|
|
+ Platform_BlockDevice_sdc_stats.write_sectors_comp = 0;
|
|
+
|
|
+ /* we assume here the refresdelay is 1 sec which sometimes is 1.5, so we have a peak */
|
|
+ readspeed = (Platform_BlockDevice_sdc_stats.read_sectors - Platform_BlockDevice_sdc_stats.read_sectors_comp) / refreshdelay;
|
|
+ writespeed = (Platform_BlockDevice_sdc_stats.write_sectors - Platform_BlockDevice_sdc_stats.write_sectors_comp) / refreshdelay;
|
|
+
|
|
+ writespeed = writespeed * sec_size / 1000;
|
|
+ readspeed = readspeed * sec_size / 1000;
|
|
+ if (writespeed >= 1000 || readspeed >= 1000) {
|
|
+ writespeed /= 1000;
|
|
+ readspeed /= 1000;
|
|
+ if (writespeed >= 1000 || readspeed >= 1000) {
|
|
+ writespeed /= 1000;
|
|
+ readspeed /= 1000;
|
|
+ xSnprintf(buffer, len, "%.2f GB/s - %.2f GB/s (R/W)", (float) readspeed, (float) writespeed);
|
|
+ } else {
|
|
+ xSnprintf(buffer, len, "%.2f MB/s - %.2f MB/s (R/W)", (float) readspeed, (float) writespeed);
|
|
+ }
|
|
+ } else {
|
|
+ xSnprintf(buffer, len, "%.2f KB/s - %.2f KB/s (R/W)", (float) readspeed, (float) writespeed);
|
|
+ }
|
|
+
|
|
+ Platform_BlockDevice_sdc_stats.read_sectors_comp = Platform_BlockDevice_sdc_stats.read_sectors;
|
|
+ Platform_BlockDevice_sdc_stats.write_sectors_comp = Platform_BlockDevice_sdc_stats.write_sectors;
|
|
+
|
|
+ } else {
|
|
+ if (!(flash % 2))
|
|
+ xSnprintf(buffer, len, "%s", "unavailable");
|
|
+ else
|
|
+ xSnprintf(buffer, len, "%s", "");
|
|
+ flash++;
|
|
+ }
|
|
+}
|
|
+
|
|
+MeterClass BlockDevice_sdc_ioStatsMeter_class = {
|
|
+ .super = {
|
|
+ .extends = Class(Meter),
|
|
+ .delete = Meter_delete
|
|
+ },
|
|
+ .updateValues = BlockDevice_sdc_ioStatsMeter_setValues,
|
|
+ .defaultMode = TEXT_METERMODE,
|
|
+ .maxItems = 8,
|
|
+ .total = 100.0,
|
|
+ .attributes = BlockDevice_ioStatsMeter_attributes,
|
|
+ .name = "sdcstat",
|
|
+ .uiName = "sdc speed stat",
|
|
+ .caption = "sdc stat: ",
|
|
+};
|
|
+
|
|
+static void BlockDevice_sdd_ioStatsMeter_setValues(Meter* this, char* buffer, int len) {
|
|
+ int ret;
|
|
+ float readspeed;
|
|
+ float writespeed;
|
|
+ double refreshdelay;
|
|
+ char block_device[80];
|
|
+ static double old = 0.;
|
|
+ static double now = 0.;
|
|
+ static int flash = 0;
|
|
+ static unsigned long sec_size = 0;
|
|
+ FILE *fp;
|
|
+
|
|
+ if (sec_size == 0) {
|
|
+ xSnprintf(block_device, sizeof(block_device), "/sys/block/%s/queue/hw_sector_size", "sdd");
|
|
+ if ((fp = fopen(block_device, "r")) == NULL) {
|
|
+ xSnprintf(buffer, len, "%s", "unavailable");
|
|
+ return;
|
|
+ }
|
|
+ if (fgets(block_device, 79, fp) != NULL) {
|
|
+ sscanf(block_device, "%lu", &sec_size);
|
|
+ }
|
|
+ fclose(fp);
|
|
+ if (sec_size == 0)
|
|
+ sec_size = 1;
|
|
+ }
|
|
+
|
|
+ now = get_wall_time();
|
|
+ refreshdelay = now - old;
|
|
+ if (old == 0.)
|
|
+ refreshdelay = 1.;
|
|
+ old = now;
|
|
+
|
|
+ ret = Platform_getIO_stats("sdd", 3, 0);
|
|
+ if (ret) {
|
|
+ if (Platform_BlockDevice_sdd_stats.read_sectors_comp > Platform_BlockDevice_sdd_stats.read_sectors)
|
|
+ Platform_BlockDevice_sdd_stats.read_sectors_comp = 0;
|
|
+ if (Platform_BlockDevice_sdd_stats.write_sectors_comp > Platform_BlockDevice_sdd_stats.write_sectors)
|
|
+ Platform_BlockDevice_sdd_stats.write_sectors_comp = 0;
|
|
+
|
|
+ /* we assume here the refresdelay is 1 sec which sometimes is 1.5, so we have a peak */
|
|
+ readspeed = (Platform_BlockDevice_sdd_stats.read_sectors - Platform_BlockDevice_sdd_stats.read_sectors_comp) / refreshdelay;
|
|
+ writespeed = (Platform_BlockDevice_sdd_stats.write_sectors - Platform_BlockDevice_sdd_stats.write_sectors_comp) / refreshdelay;
|
|
+
|
|
+ writespeed = writespeed * sec_size / 1000;
|
|
+ readspeed = readspeed * sec_size / 1000;
|
|
+ if (writespeed >= 1000 || readspeed >= 1000) {
|
|
+ writespeed /= 1000;
|
|
+ readspeed /= 1000;
|
|
+ if (writespeed >= 1000 || readspeed >= 1000) {
|
|
+ writespeed /= 1000;
|
|
+ readspeed /= 1000;
|
|
+ xSnprintf(buffer, len, "%.2f GB/s - %.2f GB/s (R/W)", (float) readspeed, (float) writespeed);
|
|
+ } else {
|
|
+ xSnprintf(buffer, len, "%.2f MB/s - %.2f MB/s (R/W)", (float) readspeed, (float) writespeed);
|
|
+ }
|
|
+ } else {
|
|
+ xSnprintf(buffer, len, "%.2f KB/s - %.2f KB/s (R/W)", (float) readspeed, (float) writespeed);
|
|
+ }
|
|
+
|
|
+ Platform_BlockDevice_sdd_stats.read_sectors_comp = Platform_BlockDevice_sdd_stats.read_sectors;
|
|
+ Platform_BlockDevice_sdd_stats.write_sectors_comp = Platform_BlockDevice_sdd_stats.write_sectors;
|
|
+
|
|
+ } else {
|
|
+ if (!(flash % 2))
|
|
+ xSnprintf(buffer, len, "%s", "unavailable");
|
|
+ else
|
|
+ xSnprintf(buffer, len, "%s", "");
|
|
+ flash++;
|
|
+ }
|
|
+}
|
|
+
|
|
+MeterClass BlockDevice_sdd_ioStatsMeter_class = {
|
|
+ .super = {
|
|
+ .extends = Class(Meter),
|
|
+ .delete = Meter_delete
|
|
+ },
|
|
+ .updateValues = BlockDevice_sdd_ioStatsMeter_setValues,
|
|
+ .defaultMode = TEXT_METERMODE,
|
|
+ .maxItems = 8,
|
|
+ .total = 100.0,
|
|
+ .attributes = BlockDevice_ioStatsMeter_attributes,
|
|
+ .name = "sddstat",
|
|
+ .uiName = "sdd speed stat",
|
|
+ .caption = "sdd stat: ",
|
|
+};
|
|
+
|
|
+static void BlockDevice_mmcblk0_ioStatsMeter_setValues(Meter* this, char* buffer, int len) {
|
|
+ int ret;
|
|
+ float readspeed;
|
|
+ float writespeed;
|
|
+ double refreshdelay;
|
|
+ char block_device[80];
|
|
+ static double old = 0.;
|
|
+ static double now = 0.;
|
|
+ static int flash = 0;
|
|
+ static unsigned long sec_size = 0;
|
|
+ FILE *fp;
|
|
+
|
|
+ if (sec_size == 0) {
|
|
+ xSnprintf(block_device, sizeof(block_device), "/sys/block/%s/queue/hw_sector_size", "mmcblk0");
|
|
+ if ((fp = fopen(block_device, "r")) == NULL) {
|
|
+ xSnprintf(buffer, len, "%s", "unavailable");
|
|
+ return;
|
|
+ }
|
|
+ if (fgets(block_device, 79, fp) != NULL) {
|
|
+ sscanf(block_device, "%lu", &sec_size);
|
|
+ }
|
|
+ fclose(fp);
|
|
+ if (sec_size == 0)
|
|
+ sec_size = 1;
|
|
+ }
|
|
+
|
|
+ now = get_wall_time();
|
|
+ refreshdelay = now - old;
|
|
+ if (old == 0.)
|
|
+ refreshdelay = 1.;
|
|
+ old = now;
|
|
+
|
|
+ ret = Platform_getIO_stats("mmcblk0", 4, 0);
|
|
+ if (ret) {
|
|
+ if (Platform_BlockDevice_mmcblk0_stats.read_sectors_comp > Platform_BlockDevice_mmcblk0_stats.read_sectors)
|
|
+ Platform_BlockDevice_mmcblk0_stats.read_sectors_comp = 0;
|
|
+ if (Platform_BlockDevice_mmcblk0_stats.write_sectors_comp > Platform_BlockDevice_mmcblk0_stats.write_sectors)
|
|
+ Platform_BlockDevice_mmcblk0_stats.write_sectors_comp = 0;
|
|
+
|
|
+ /* we assume here the refresdelay is 1 sec which sometimes is 1.5, so we have a peak */
|
|
+ readspeed = (Platform_BlockDevice_mmcblk0_stats.read_sectors - Platform_BlockDevice_mmcblk0_stats.read_sectors_comp) / refreshdelay;
|
|
+ writespeed = (Platform_BlockDevice_mmcblk0_stats.write_sectors - Platform_BlockDevice_mmcblk0_stats.write_sectors_comp) / refreshdelay;
|
|
+
|
|
+ writespeed = writespeed * sec_size / 1000;
|
|
+ readspeed = readspeed * sec_size / 1000;
|
|
+ if (writespeed >= 1000 || readspeed >= 1000) {
|
|
+ writespeed /= 1000;
|
|
+ readspeed /= 1000;
|
|
+ if (writespeed >= 1000 || readspeed >= 1000) {
|
|
+ writespeed /= 1000;
|
|
+ readspeed /= 1000;
|
|
+ xSnprintf(buffer, len, "%.2f GB/s - %.2f GB/s (R/W)", (float) readspeed, (float) writespeed);
|
|
+ } else {
|
|
+ xSnprintf(buffer, len, "%.2f MB/s - %.2f MB/s (R/W)", (float) readspeed, (float) writespeed);
|
|
+ }
|
|
+ } else {
|
|
+ xSnprintf(buffer, len, "%.2f KB/s - %.2f KB/s (R/W)", (float) readspeed, (float) writespeed);
|
|
+ }
|
|
+
|
|
+ Platform_BlockDevice_mmcblk0_stats.read_sectors_comp = Platform_BlockDevice_mmcblk0_stats.read_sectors;
|
|
+ Platform_BlockDevice_mmcblk0_stats.write_sectors_comp = Platform_BlockDevice_mmcblk0_stats.write_sectors;
|
|
+
|
|
+ } else {
|
|
+ if (!(flash % 2))
|
|
+ xSnprintf(buffer, len, "%s", "unavailable");
|
|
+ else
|
|
+ xSnprintf(buffer, len, "%s", "");
|
|
+ flash++;
|
|
+ }
|
|
+}
|
|
+
|
|
+MeterClass BlockDevice_mmcblk0_ioStatsMeter_class = {
|
|
+ .super = {
|
|
+ .extends = Class(Meter),
|
|
+ .delete = Meter_delete
|
|
+ },
|
|
+ .updateValues = BlockDevice_mmcblk0_ioStatsMeter_setValues,
|
|
+ .defaultMode = TEXT_METERMODE,
|
|
+ .maxItems = 8,
|
|
+ .total = 100.0,
|
|
+ .attributes = BlockDevice_ioStatsMeter_attributes,
|
|
+ .name = "mmcblk0stat",
|
|
+ .uiName = "mmcblk0 speed stat",
|
|
+ .caption = "mmcblk0 stat: ",
|
|
+};
|
|
+
|
|
+static void BlockDevice_mmcblk1_ioStatsMeter_setValues(Meter* this, char* buffer, int len) {
|
|
+ int ret;
|
|
+ float readspeed;
|
|
+ float writespeed;
|
|
+ double refreshdelay;
|
|
+ char block_device[80];
|
|
+ static double old = 0.;
|
|
+ static double now = 0.;
|
|
+ static int flash = 0;
|
|
+ static unsigned long sec_size = 0;
|
|
+ FILE *fp;
|
|
+
|
|
+ if (sec_size == 0) {
|
|
+ xSnprintf(block_device, sizeof(block_device), "/sys/block/%s/queue/hw_sector_size", "mmcblk1");
|
|
+ if ((fp = fopen(block_device, "r")) == NULL) {
|
|
+ xSnprintf(buffer, len, "%s", "unavailable");
|
|
+ return;
|
|
+ }
|
|
+ if (fgets(block_device, 79, fp) != NULL) {
|
|
+ sscanf(block_device, "%lu", &sec_size);
|
|
+ }
|
|
+ fclose(fp);
|
|
+ if (sec_size == 0)
|
|
+ sec_size = 1;
|
|
+ }
|
|
+
|
|
+ now = get_wall_time();
|
|
+ refreshdelay = now - old;
|
|
+ if (old == 0.)
|
|
+ refreshdelay = 1.;
|
|
+ old = now;
|
|
+
|
|
+ ret = Platform_getIO_stats("mmcblk1", 5, 0);
|
|
+ if (ret) {
|
|
+ if (Platform_BlockDevice_mmcblk1_stats.read_sectors_comp > Platform_BlockDevice_mmcblk1_stats.read_sectors)
|
|
+ Platform_BlockDevice_mmcblk1_stats.read_sectors_comp = 0;
|
|
+ if (Platform_BlockDevice_mmcblk1_stats.write_sectors_comp > Platform_BlockDevice_mmcblk1_stats.write_sectors)
|
|
+ Platform_BlockDevice_mmcblk1_stats.write_sectors_comp = 0;
|
|
+
|
|
+ /* we assume here the refresdelay is 1 sec which sometimes is 1.5, so we have a peak */
|
|
+ readspeed = (Platform_BlockDevice_mmcblk1_stats.read_sectors - Platform_BlockDevice_mmcblk1_stats.read_sectors_comp) / refreshdelay;
|
|
+ writespeed = (Platform_BlockDevice_mmcblk1_stats.write_sectors - Platform_BlockDevice_mmcblk1_stats.write_sectors_comp) / refreshdelay;
|
|
+
|
|
+ writespeed = writespeed * sec_size / 1000;
|
|
+ readspeed = readspeed * sec_size / 1000;
|
|
+ if (writespeed >= 1000 || readspeed >= 1000) {
|
|
+ writespeed /= 1000;
|
|
+ readspeed /= 1000;
|
|
+ if (writespeed >= 1000 || readspeed >= 1000) {
|
|
+ writespeed /= 1000;
|
|
+ readspeed /= 1000;
|
|
+ xSnprintf(buffer, len, "%.2f GB/s - %.2f GB/s (R/W)", (float) readspeed, (float) writespeed);
|
|
+ } else {
|
|
+ xSnprintf(buffer, len, "%.2f MB/s - %.2f MB/s (R/W)", (float) readspeed, (float) writespeed);
|
|
+ }
|
|
+ } else {
|
|
+ xSnprintf(buffer, len, "%.2f KB/s - %.2f KB/s (R/W)", (float) readspeed, (float) writespeed);
|
|
+ }
|
|
+
|
|
+ Platform_BlockDevice_mmcblk1_stats.read_sectors_comp = Platform_BlockDevice_mmcblk1_stats.read_sectors;
|
|
+ Platform_BlockDevice_mmcblk1_stats.write_sectors_comp = Platform_BlockDevice_mmcblk1_stats.write_sectors;
|
|
+
|
|
+ } else {
|
|
+ if (!(flash % 2))
|
|
+ xSnprintf(buffer, len, "%s", "unavailable");
|
|
+ else
|
|
+ xSnprintf(buffer, len, "%s", "");
|
|
+ flash++;
|
|
+ }
|
|
+}
|
|
+
|
|
+MeterClass BlockDevice_mmcblk1_ioStatsMeter_class = {
|
|
+ .super = {
|
|
+ .extends = Class(Meter),
|
|
+ .delete = Meter_delete
|
|
+ },
|
|
+ .updateValues = BlockDevice_mmcblk1_ioStatsMeter_setValues,
|
|
+ .defaultMode = TEXT_METERMODE,
|
|
+ .maxItems = 8,
|
|
+ .total = 100.0,
|
|
+ .attributes = BlockDevice_ioStatsMeter_attributes,
|
|
+ .name = "mmcblk1stat",
|
|
+ .uiName = "mmcblk1 speed stat",
|
|
+ .caption = "mmcblk1 stat: ",
|
|
+};
|
|
+
|
|
+static void BlockDevice_mmcblk2_ioStatsMeter_setValues(Meter* this, char* buffer, int len) {
|
|
+ int ret;
|
|
+ float readspeed;
|
|
+ float writespeed;
|
|
+ double refreshdelay;
|
|
+ char block_device[80];
|
|
+ static double old = 0.;
|
|
+ static double now = 0.;
|
|
+ static int flash = 0;
|
|
+ static unsigned long sec_size = 0;
|
|
+ FILE *fp;
|
|
+
|
|
+ if (sec_size == 0) {
|
|
+ xSnprintf(block_device, sizeof(block_device), "/sys/block/%s/queue/hw_sector_size", "mmcblk2");
|
|
+ if ((fp = fopen(block_device, "r")) == NULL) {
|
|
+ xSnprintf(buffer, len, "%s", "unavailable");
|
|
+ return;
|
|
+ }
|
|
+ if (fgets(block_device, 79, fp) != NULL) {
|
|
+ sscanf(block_device, "%lu", &sec_size);
|
|
+ }
|
|
+ fclose(fp);
|
|
+ if (sec_size == 0)
|
|
+ sec_size = 1;
|
|
+ }
|
|
+
|
|
+ now = get_wall_time();
|
|
+ refreshdelay = now - old;
|
|
+ if (old == 0.)
|
|
+ refreshdelay = 1.;
|
|
+ old = now;
|
|
+
|
|
+ ret = Platform_getIO_stats("mmcblk2", 6, 0);
|
|
+ if (ret) {
|
|
+ if (Platform_BlockDevice_mmcblk2_stats.read_sectors_comp > Platform_BlockDevice_mmcblk2_stats.read_sectors)
|
|
+ Platform_BlockDevice_mmcblk2_stats.read_sectors_comp = 0;
|
|
+ if (Platform_BlockDevice_mmcblk2_stats.write_sectors_comp > Platform_BlockDevice_mmcblk2_stats.write_sectors)
|
|
+ Platform_BlockDevice_mmcblk2_stats.write_sectors_comp = 0;
|
|
+
|
|
+ /* we assume here the refresdelay is 1 sec which sometimes is 1.5, so we have a peak */
|
|
+ readspeed = (Platform_BlockDevice_mmcblk2_stats.read_sectors - Platform_BlockDevice_mmcblk2_stats.read_sectors_comp) / refreshdelay;
|
|
+ writespeed = (Platform_BlockDevice_mmcblk2_stats.write_sectors - Platform_BlockDevice_mmcblk2_stats.write_sectors_comp) / refreshdelay;
|
|
+
|
|
+ writespeed = writespeed * sec_size / 1000;
|
|
+ readspeed = readspeed * sec_size / 1000;
|
|
+ if (writespeed >= 1000 || readspeed >= 1000) {
|
|
+ writespeed /= 1000;
|
|
+ readspeed /= 1000;
|
|
+ if (writespeed >= 1000 || readspeed >= 1000) {
|
|
+ writespeed /= 1000;
|
|
+ readspeed /= 1000;
|
|
+ xSnprintf(buffer, len, "%.2f GB/s - %.2f GB/s (R/W)", (float) readspeed, (float) writespeed);
|
|
+ } else {
|
|
+ xSnprintf(buffer, len, "%.2f MB/s - %.2f MB/s (R/W)", (float) readspeed, (float) writespeed);
|
|
+ }
|
|
+ } else {
|
|
+ xSnprintf(buffer, len, "%.2f KB/s - %.2f KB/s (R/W)", (float) readspeed, (float) writespeed);
|
|
+ }
|
|
+
|
|
+ Platform_BlockDevice_mmcblk2_stats.read_sectors_comp = Platform_BlockDevice_mmcblk2_stats.read_sectors;
|
|
+ Platform_BlockDevice_mmcblk2_stats.write_sectors_comp = Platform_BlockDevice_mmcblk2_stats.write_sectors;
|
|
+
|
|
+ } else {
|
|
+ if (!(flash % 2))
|
|
+ xSnprintf(buffer, len, "%s", "unavailable");
|
|
+ else
|
|
+ xSnprintf(buffer, len, "%s", "");
|
|
+ flash++;
|
|
+ }
|
|
+}
|
|
+
|
|
+MeterClass BlockDevice_mmcblk2_ioStatsMeter_class = {
|
|
+ .super = {
|
|
+ .extends = Class(Meter),
|
|
+ .delete = Meter_delete
|
|
+ },
|
|
+ .updateValues = BlockDevice_mmcblk2_ioStatsMeter_setValues,
|
|
+ .defaultMode = TEXT_METERMODE,
|
|
+ .maxItems = 8,
|
|
+ .total = 100.0,
|
|
+ .attributes = BlockDevice_ioStatsMeter_attributes,
|
|
+ .name = "mmcblk2stat",
|
|
+ .uiName = "mmcblk2 speed stat",
|
|
+ .caption = "mmcblk2 stat: ",
|
|
+};
|
|
+
|
|
+static void BlockDevice_mmcblk3_ioStatsMeter_setValues(Meter* this, char* buffer, int len) {
|
|
+ int ret;
|
|
+ float readspeed;
|
|
+ float writespeed;
|
|
+ double refreshdelay;
|
|
+ char block_device[80];
|
|
+ static double old = 0.;
|
|
+ static double now = 0.;
|
|
+ static int flash = 0;
|
|
+ static unsigned long sec_size = 0;
|
|
+ FILE *fp;
|
|
+
|
|
+ if (sec_size == 0) {
|
|
+ xSnprintf(block_device, sizeof(block_device), "/sys/block/%s/queue/hw_sector_size", "mmcblk3");
|
|
+ if ((fp = fopen(block_device, "r")) == NULL) {
|
|
+ xSnprintf(buffer, len, "%s", "unavailable");
|
|
+ return;
|
|
+ }
|
|
+ if (fgets(block_device, 79, fp) != NULL) {
|
|
+ sscanf(block_device, "%lu", &sec_size);
|
|
+ }
|
|
+ fclose(fp);
|
|
+ if (sec_size == 0)
|
|
+ sec_size = 1;
|
|
+ }
|
|
+
|
|
+ now = get_wall_time();
|
|
+ refreshdelay = now - old;
|
|
+ if (old == 0.)
|
|
+ refreshdelay = 1.;
|
|
+ old = now;
|
|
+
|
|
+ ret = Platform_getIO_stats("mmcblk3", 7, 0);
|
|
+ if (ret) {
|
|
+ if (Platform_BlockDevice_mmcblk3_stats.read_sectors_comp > Platform_BlockDevice_mmcblk3_stats.read_sectors)
|
|
+ Platform_BlockDevice_mmcblk3_stats.read_sectors_comp = 0;
|
|
+ if (Platform_BlockDevice_mmcblk3_stats.write_sectors_comp > Platform_BlockDevice_mmcblk3_stats.write_sectors)
|
|
+ Platform_BlockDevice_mmcblk3_stats.write_sectors_comp = 0;
|
|
+
|
|
+ /* we assume here the refresdelay is 1 sec which sometimes is 1.5, so we have a peak */
|
|
+ readspeed = (Platform_BlockDevice_mmcblk3_stats.read_sectors - Platform_BlockDevice_mmcblk3_stats.read_sectors_comp) / refreshdelay;
|
|
+ writespeed = (Platform_BlockDevice_mmcblk3_stats.write_sectors - Platform_BlockDevice_mmcblk3_stats.write_sectors_comp) / refreshdelay;
|
|
+
|
|
+ writespeed = writespeed * sec_size / 1000;
|
|
+ readspeed = readspeed * sec_size / 1000;
|
|
+ if (writespeed >= 1000 || readspeed >= 1000) {
|
|
+ writespeed /= 1000;
|
|
+ readspeed /= 1000;
|
|
+ if (writespeed >= 1000 || readspeed >= 1000) {
|
|
+ writespeed /= 1000;
|
|
+ readspeed /= 1000;
|
|
+ xSnprintf(buffer, len, "%.2f GB/s - %.2f GB/s (R/W)", (float) readspeed, (float) writespeed);
|
|
+ } else {
|
|
+ xSnprintf(buffer, len, "%.2f MB/s - %.2f MB/s (R/W)", (float) readspeed, (float) writespeed);
|
|
+ }
|
|
+ } else {
|
|
+ xSnprintf(buffer, len, "%.2f KB/s - %.2f KB/s (R/W)", (float) readspeed, (float) writespeed);
|
|
+ }
|
|
+
|
|
+ Platform_BlockDevice_mmcblk3_stats.read_sectors_comp = Platform_BlockDevice_mmcblk3_stats.read_sectors;
|
|
+ Platform_BlockDevice_mmcblk3_stats.write_sectors_comp = Platform_BlockDevice_mmcblk3_stats.write_sectors;
|
|
+
|
|
+ } else {
|
|
+ if (!(flash % 2))
|
|
+ xSnprintf(buffer, len, "%s", "unavailable");
|
|
+ else
|
|
+ xSnprintf(buffer, len, "%s", "");
|
|
+ flash++;
|
|
+ }
|
|
+}
|
|
+
|
|
+MeterClass BlockDevice_mmcblk3_ioStatsMeter_class = {
|
|
+ .super = {
|
|
+ .extends = Class(Meter),
|
|
+ .delete = Meter_delete
|
|
+ },
|
|
+ .updateValues = BlockDevice_mmcblk3_ioStatsMeter_setValues,
|
|
+ .defaultMode = TEXT_METERMODE,
|
|
+ .maxItems = 8,
|
|
+ .total = 100.0,
|
|
+ .attributes = BlockDevice_ioStatsMeter_attributes,
|
|
+ .name = "mmcblk3stat",
|
|
+ .uiName = "mmcblk3 speed stat",
|
|
+ .caption = "mmcblk3 stat: ",
|
|
+};
|
|
+
|
|
+
|
|
+
|
|
+
|
|
diff --git a/BlockDevice_ioStatsMeter.h b/BlockDevice_ioStatsMeter.h
|
|
new file mode 100644
|
|
index 0000000..ce707c8
|
|
--- /dev/null
|
|
+++ b/BlockDevice_ioStatsMeter.h
|
|
@@ -0,0 +1,31 @@
|
|
+/* Do not edit this file. It was automatically generated. */
|
|
+
|
|
+#ifndef HEADER_BlockDevice_ioStatsMeter
|
|
+#define HEADER_BlockDevice_ioStatsMeter
|
|
+/*
|
|
+htop - BlockDevice_ioStatsMeter.h
|
|
+(C) 2020 @lex
|
|
+*/
|
|
+
|
|
+#include "Meter.h"
|
|
+
|
|
+extern int BlockDevice_ioStatsMeter_attributes[];
|
|
+
|
|
+extern MeterClass BlockDevice_sda_ioStatsMeter_class;
|
|
+
|
|
+extern MeterClass BlockDevice_sdb_ioStatsMeter_class;
|
|
+
|
|
+extern MeterClass BlockDevice_sdc_ioStatsMeter_class;
|
|
+
|
|
+extern MeterClass BlockDevice_sdd_ioStatsMeter_class;
|
|
+
|
|
+extern MeterClass BlockDevice_mmcblk0_ioStatsMeter_class;
|
|
+
|
|
+extern MeterClass BlockDevice_mmcblk1_ioStatsMeter_class;
|
|
+
|
|
+extern MeterClass BlockDevice_mmcblk2_ioStatsMeter_class;
|
|
+
|
|
+extern MeterClass BlockDevice_mmcblk3_ioStatsMeter_class;
|
|
+
|
|
+
|
|
+#endif
|
|
diff --git a/CPUMeter.c b/CPUMeter.c
|
|
index de5490d..0825dba 100644
|
|
--- a/CPUMeter.c
|
|
+++ b/CPUMeter.c
|
|
@@ -6,6 +6,7 @@ in the source distribution for its full text.
|
|
*/
|
|
|
|
#include "CPUMeter.h"
|
|
+#include "CpuFreqMeter.h"
|
|
|
|
#include "CRT.h"
|
|
#include "Settings.h"
|
|
diff --git a/CRT.c b/CRT.c
|
|
index ca9a10d..1fefaff 100644
|
|
--- a/CRT.c
|
|
+++ b/CRT.c
|
|
@@ -128,6 +128,20 @@ typedef enum ColorElements_ {
|
|
CPU_SOFTIRQ,
|
|
CPU_STEAL,
|
|
CPU_GUEST,
|
|
+ CPU_TEMP,
|
|
+ CPU_FREQ,
|
|
+ CPU_VCORE,
|
|
+ GPU_TEMP,
|
|
+ ETH0_INTERFACE,
|
|
+ ETH1_INTERFACE,
|
|
+ WLAN0_INTERFACE,
|
|
+ WLAN1_INTERFACE,
|
|
+ KERNEL_VERSION,
|
|
+ DISTRO_VERSION,
|
|
+ OS_VERSION,
|
|
+ ARMBIAN_VERSION,
|
|
+ ETH0_STATS,
|
|
+ ETH1_STATS,
|
|
LAST_COLORELEMENT
|
|
} ColorElements;
|
|
|
|
@@ -232,6 +246,18 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
|
|
[CPU_SOFTIRQ] = ColorPair(Magenta,Black),
|
|
[CPU_STEAL] = ColorPair(Cyan,Black),
|
|
[CPU_GUEST] = ColorPair(Cyan,Black),
|
|
+ [CPU_FREQ] = A_BOLD | ColorPair(Yellow,Black),
|
|
+ [CPU_TEMP] = A_BOLD | ColorPair(Red,Black),
|
|
+ [CPU_VCORE] = A_BOLD | ColorPair(Yellow,Black),
|
|
+ [GPU_TEMP] = ColorPair(Cyan,Black),
|
|
+ [ETH0_INTERFACE] = A_BOLD | ColorPair(Cyan,Black),
|
|
+ [ETH1_INTERFACE] = A_BOLD | ColorPair(Cyan,Black),
|
|
+ [WLAN0_INTERFACE] = A_BOLD | ColorPair(Cyan,Black),
|
|
+ [WLAN1_INTERFACE] = A_BOLD | ColorPair(Cyan,Black),
|
|
+ [KERNEL_VERSION] = A_BOLD | ColorPair(Cyan,Black),
|
|
+ [DISTRO_VERSION] = A_BOLD | ColorPair(Cyan,Black),
|
|
+ [OS_VERSION] = A_BOLD | ColorPair(Cyan,Black),
|
|
+ [ARMBIAN_VERSION] = A_BOLD | ColorPair(Cyan,Black),
|
|
},
|
|
[COLORSCHEME_MONOCHROME] = {
|
|
[RESET_COLOR] = A_NORMAL,
|
|
@@ -291,6 +317,18 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
|
|
[CPU_SOFTIRQ] = A_BOLD,
|
|
[CPU_STEAL] = A_REVERSE,
|
|
[CPU_GUEST] = A_REVERSE,
|
|
+ [CPU_FREQ] = A_BOLD,
|
|
+ [CPU_TEMP] = A_BOLD,
|
|
+ [CPU_VCORE] = A_BOLD,
|
|
+ [GPU_TEMP] = A_BOLD,
|
|
+ [ETH0_INTERFACE] = A_BOLD,
|
|
+ [ETH1_INTERFACE] = A_BOLD,
|
|
+ [WLAN0_INTERFACE] = A_BOLD,
|
|
+ [WLAN1_INTERFACE] = A_BOLD,
|
|
+ [KERNEL_VERSION] = A_BOLD,
|
|
+ [DISTRO_VERSION] = A_BOLD,
|
|
+ [OS_VERSION] = A_BOLD,
|
|
+ [ARMBIAN_VERSION] = A_BOLD,
|
|
},
|
|
[COLORSCHEME_BLACKONWHITE] = {
|
|
[RESET_COLOR] = ColorPair(Black,White),
|
|
@@ -350,6 +388,18 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
|
|
[CPU_SOFTIRQ] = ColorPair(Blue,White),
|
|
[CPU_STEAL] = ColorPair(Cyan,White),
|
|
[CPU_GUEST] = ColorPair(Cyan,White),
|
|
+ [CPU_FREQ] = A_BOLD | ColorPair(Yellow,White),
|
|
+ [CPU_TEMP] = A_BOLD | ColorPair(Yellow,White),
|
|
+ [CPU_VCORE] = A_BOLD | ColorPair(Yellow,White),
|
|
+ [GPU_TEMP] = A_BOLD | ColorPair(Yellow,White),
|
|
+ [ETH0_INTERFACE] = A_BOLD | ColorPair(Yellow,White),
|
|
+ [ETH1_INTERFACE] = A_BOLD | ColorPair(Yellow,White),
|
|
+ [WLAN0_INTERFACE] = A_BOLD | ColorPair(Yellow,White),
|
|
+ [WLAN1_INTERFACE] = A_BOLD | ColorPair(Yellow,White),
|
|
+ [KERNEL_VERSION] = A_BOLD | ColorPair(Yellow,White),
|
|
+ [DISTRO_VERSION] = A_BOLD | ColorPair(Yellow,White),
|
|
+ [OS_VERSION] = A_BOLD | ColorPair(Yellow,White),
|
|
+ [ARMBIAN_VERSION] = A_BOLD | ColorPair(Yellow,White),
|
|
},
|
|
[COLORSCHEME_LIGHTTERMINAL] = {
|
|
[RESET_COLOR] = ColorPair(Black,Black),
|
|
@@ -409,6 +459,18 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
|
|
[CPU_SOFTIRQ] = ColorPair(Blue,Black),
|
|
[CPU_STEAL] = ColorPair(Black,Black),
|
|
[CPU_GUEST] = ColorPair(Black,Black),
|
|
+ [CPU_FREQ] = A_BOLD | ColorPair(Yellow,Black),
|
|
+ [CPU_TEMP] = A_BOLD | ColorPair(Yellow,Black),
|
|
+ [CPU_VCORE] = A_BOLD | ColorPair(Yellow,Black),
|
|
+ [GPU_TEMP] = A_BOLD | ColorPair(Yellow,Black),
|
|
+ [ETH0_INTERFACE] = A_BOLD | ColorPair(Yellow,Black),
|
|
+ [ETH1_INTERFACE] = A_BOLD | ColorPair(Yellow,Black),
|
|
+ [WLAN0_INTERFACE] = A_BOLD | ColorPair(Yellow,Black),
|
|
+ [WLAN1_INTERFACE] = A_BOLD | ColorPair(Yellow,Black),
|
|
+ [KERNEL_VERSION] = A_BOLD | ColorPair(Yellow,Black),
|
|
+ [DISTRO_VERSION] = A_BOLD | ColorPair(Yellow,Black),
|
|
+ [OS_VERSION] = A_BOLD | ColorPair(Yellow,Black),
|
|
+ [ARMBIAN_VERSION] = A_BOLD | ColorPair(Yellow,Black),
|
|
},
|
|
[COLORSCHEME_MIDNIGHT] = {
|
|
[RESET_COLOR] = ColorPair(White,Blue),
|
|
@@ -468,6 +530,18 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
|
|
[CPU_SOFTIRQ] = ColorPair(Black,Blue),
|
|
[CPU_STEAL] = ColorPair(White,Blue),
|
|
[CPU_GUEST] = ColorPair(White,Blue),
|
|
+ [CPU_FREQ] = A_BOLD | ColorPair(Red,Black),
|
|
+ [CPU_TEMP] = A_BOLD | ColorPair(Red,Black),
|
|
+ [CPU_VCORE] = A_BOLD | ColorPair(Yellow,Black),
|
|
+ [GPU_TEMP] = A_BOLD | ColorPair(Yellow,Black),
|
|
+ [ETH0_INTERFACE] = A_BOLD | ColorPair(Cyan,Blue),
|
|
+ [ETH1_INTERFACE] = A_BOLD | ColorPair(Cyan,Blue),
|
|
+ [WLAN0_INTERFACE] = A_BOLD | ColorPair(Cyan,Blue),
|
|
+ [WLAN1_INTERFACE] = A_BOLD | ColorPair(Cyan,Blue),
|
|
+ [KERNEL_VERSION] = A_BOLD | ColorPair(Cyan,Black),
|
|
+ [DISTRO_VERSION] = A_BOLD | ColorPair(Cyan,Black),
|
|
+ [OS_VERSION] = A_BOLD | ColorPair(Cyan,Black),
|
|
+ [ARMBIAN_VERSION] = A_BOLD | ColorPair(Cyan,Black),
|
|
},
|
|
[COLORSCHEME_BLACKNIGHT] = {
|
|
[RESET_COLOR] = ColorPair(Cyan,Black),
|
|
@@ -527,6 +601,18 @@ int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
|
|
[CPU_SOFTIRQ] = ColorPair(Blue,Black),
|
|
[CPU_STEAL] = ColorPair(Cyan,Black),
|
|
[CPU_GUEST] = ColorPair(Cyan,Black),
|
|
+ [CPU_FREQ] = A_BOLD | ColorPair(Red,Black),
|
|
+ [CPU_TEMP] = A_BOLD | ColorPair(Red,Black),
|
|
+ [CPU_VCORE] = A_BOLD | ColorPair(Yellow,Black),
|
|
+ [GPU_TEMP] = A_BOLD | ColorPair(Yellow,Black),
|
|
+ [ETH0_INTERFACE] = A_BOLD | ColorPair(Blue,Black),
|
|
+ [ETH1_INTERFACE] = A_BOLD | ColorPair(Blue,Black),
|
|
+ [WLAN0_INTERFACE] = A_BOLD | ColorPair(Blue,Black),
|
|
+ [WLAN1_INTERFACE] = A_BOLD | ColorPair(Blue,Black),
|
|
+ [KERNEL_VERSION] = A_BOLD | ColorPair(Blue,Black),
|
|
+ [DISTRO_VERSION] = A_BOLD | ColorPair(Blue,Black),
|
|
+ [OS_VERSION] = A_BOLD | ColorPair(Blue,Black),
|
|
+ [ARMBIAN_VERSION] = A_BOLD | ColorPair(Blue,Black),
|
|
},
|
|
[COLORSCHEME_BROKENGRAY] = { 0 } // dynamically generated.
|
|
};
|
|
@@ -596,6 +682,15 @@ void CRT_restorePrivileges() {
|
|
// TODO: pass an instance of Settings instead.
|
|
|
|
void CRT_init(int delay, int colorScheme) {
|
|
+#ifdef DEBUG
|
|
+ setenv("TERM", "xterm", 1);
|
|
+ CRT_termType = getenv("TERM");
|
|
+ if (String_eq(CRT_termType, "linux"))
|
|
+ CRT_scrollHAmount = 20;
|
|
+ else
|
|
+ CRT_scrollHAmount = 5;
|
|
+ setenv("TERM", "xterm", 1);
|
|
+#endif
|
|
initscr();
|
|
noecho();
|
|
CRT_delay = delay;
|
|
diff --git a/CRT.h b/CRT.h
|
|
index 933fe06..29ba16b 100644
|
|
--- a/CRT.h
|
|
+++ b/CRT.h
|
|
@@ -116,6 +116,20 @@ typedef enum ColorElements_ {
|
|
CPU_SOFTIRQ,
|
|
CPU_STEAL,
|
|
CPU_GUEST,
|
|
+ CPU_TEMP,
|
|
+ CPU_FREQ,
|
|
+ CPU_VCORE,
|
|
+ GPU_TEMP,
|
|
+ ETH0_INTERFACE,
|
|
+ ETH1_INTERFACE,
|
|
+ WLAN0_INTERFACE,
|
|
+ WLAN1_INTERFACE,
|
|
+ KERNEL_VERSION,
|
|
+ DISTRO_VERSION,
|
|
+ OS_VERSION,
|
|
+ ARMBIAN_VERSION,
|
|
+ ETH0_STATS,
|
|
+ ETH1_STATS,
|
|
LAST_COLORELEMENT
|
|
} ColorElements;
|
|
|
|
diff --git a/CpuFreqMeter.c b/CpuFreqMeter.c
|
|
new file mode 100644
|
|
index 0000000..6508180
|
|
--- /dev/null
|
|
+++ b/CpuFreqMeter.c
|
|
@@ -0,0 +1,109 @@
|
|
+/*
|
|
+htop - CpuFreqMeter.c
|
|
+(C) 2020 Alexander Finger
|
|
+*/
|
|
+
|
|
+#include "CpuFreqMeter.h"
|
|
+#include "Platform.h"
|
|
+#include "CRT.h"
|
|
+
|
|
+/*{
|
|
+#include "Meter.h"
|
|
+}*/
|
|
+
|
|
+
|
|
+int CpuFreqMeter_attributes[] = {
|
|
+ CPU_FREQ
|
|
+};
|
|
+
|
|
+static void CpuFreqMeter_setValues(Meter* this, char* buffer, int len) {
|
|
+ int ghz,mhz,roundup;
|
|
+ int cpu, Freq;
|
|
+ int bigLITTLE;
|
|
+ char buf_b[32];
|
|
+ char buf_l[32];
|
|
+ int ln = sizeof(buf_l);
|
|
+ static int pulse = 0;
|
|
+
|
|
+ memset(buf_l, 0, sizeof(buf_l));
|
|
+ memset(buf_b, 0, sizeof(buf_b));
|
|
+
|
|
+ bigLITTLE = Platform_getCpuBigLITTLE();
|
|
+ if (bigLITTLE) {
|
|
+ cpu = bigLITTLE;
|
|
+ if (cpu < 0)
|
|
+ cpu = 0;
|
|
+ Freq = Platform_getCpuFreq(this, cpu);
|
|
+ if (Freq > 1000) {
|
|
+ Freq /= 1000;
|
|
+ }
|
|
+ if (Freq > 1000) {
|
|
+ ghz = Freq / 1000;
|
|
+ mhz = Freq % 1000;
|
|
+ roundup = ((mhz % 10) > 5);
|
|
+ mhz /= 10;
|
|
+ mhz += roundup;
|
|
+ xSnprintf(buf_b, ln, "%d.%02d GHz", ghz, mhz);
|
|
+ } else {
|
|
+ xSnprintf(buf_b, ln, "%4d MHz", Freq);
|
|
+ }
|
|
+
|
|
+ cpu--;
|
|
+ if (cpu < 0)
|
|
+ cpu = 0;
|
|
+ Freq = Platform_getCpuFreq(this, cpu);
|
|
+ if (Freq > 1000) {
|
|
+ Freq /= 1000;
|
|
+ }
|
|
+ if (Freq > 1000) {
|
|
+ ghz = Freq / 1000;
|
|
+ mhz = Freq % 1000;
|
|
+ roundup = ((mhz % 10) > 5);
|
|
+ mhz /= 10;
|
|
+ mhz += roundup;
|
|
+ xSnprintf(buf_l, ln, "%d.%02d GHz", ghz, mhz);
|
|
+ } else {
|
|
+ xSnprintf(buf_l, ln, "%4d MHz", Freq);
|
|
+ }
|
|
+
|
|
+ if (pulse)
|
|
+ xSnprintf(buffer, len, "%s %s (big.LITTLE)", buf_b, buf_l, pulse);
|
|
+ else
|
|
+ xSnprintf(buffer, len, "%s %s ", buf_b, buf_l, pulse);
|
|
+ pulse = !pulse;
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ cpu = 0;
|
|
+ Freq = Platform_getCpuFreq(this, cpu);
|
|
+ if (Freq > 1000) {
|
|
+ Freq /= 1000;
|
|
+ }
|
|
+ if (Freq > 1000) {
|
|
+ ghz = Freq / 1000;
|
|
+ mhz = Freq % 1000;
|
|
+ roundup = ((mhz % 10) > 5);
|
|
+ mhz /= 10;
|
|
+ mhz += roundup;
|
|
+ xSnprintf(buffer, len, "%d.%02d GHz", ghz, mhz);
|
|
+ } else {
|
|
+ xSnprintf(buffer, len, "%4d MHz", Freq);
|
|
+ }
|
|
+ pulse = !pulse;
|
|
+}
|
|
+
|
|
+MeterClass CpuFreqMeter_class = {
|
|
+ .super = {
|
|
+ .extends = Class(Meter),
|
|
+ .delete = Meter_delete
|
|
+ },
|
|
+ .updateValues = CpuFreqMeter_setValues,
|
|
+ .defaultMode = TEXT_METERMODE,
|
|
+ .maxItems = 1,
|
|
+ .total = 100.0,
|
|
+ .attributes = CpuFreqMeter_attributes,
|
|
+ .name = "CpuFreq",
|
|
+ .uiName = "CpuFreq",
|
|
+ .caption = "Cpu Freq: ",
|
|
+};
|
|
+
|
|
diff --git a/CpuFreqMeter.h b/CpuFreqMeter.h
|
|
new file mode 100644
|
|
index 0000000..151a58c
|
|
--- /dev/null
|
|
+++ b/CpuFreqMeter.h
|
|
@@ -0,0 +1,17 @@
|
|
+/* Do not edit this file. It was automatically generated. */
|
|
+
|
|
+#ifndef HEADER_CpuFreqMeter
|
|
+#define HEADER_CpuFreqMeter
|
|
+/*
|
|
+htop - CpuFreqMeter.h
|
|
+(C) 2020 Alexander Finger
|
|
+*/
|
|
+
|
|
+#include "Meter.h"
|
|
+
|
|
+extern int CpuFreqMeter_attributes[];
|
|
+
|
|
+extern MeterClass CpuFreqMeter_class;
|
|
+
|
|
+
|
|
+#endif
|
|
diff --git a/CpuTempMeter.c b/CpuTempMeter.c
|
|
new file mode 100644
|
|
index 0000000..4052256
|
|
--- /dev/null
|
|
+++ b/CpuTempMeter.c
|
|
@@ -0,0 +1,39 @@
|
|
+/*
|
|
+htop - CpuTempMeter.c
|
|
+(C) 2020 @lex
|
|
+*/
|
|
+
|
|
+#include "CpuTempMeter.h"
|
|
+#include "Platform.h"
|
|
+#include "CRT.h"
|
|
+
|
|
+/*{
|
|
+#include "Meter.h"
|
|
+}*/
|
|
+
|
|
+int CpuTempMeter_attributes[] = {
|
|
+ CPU_TEMP
|
|
+};
|
|
+
|
|
+static void CpuTempMeter_setValues(Meter* this, char* buffer, int len) {
|
|
+ int Temp = Platform_getCpuTemp(this);
|
|
+ if (Temp > 1000) {
|
|
+ Temp /= 1000;
|
|
+ }
|
|
+ xSnprintf(buffer, len, "%4d C", Temp);
|
|
+}
|
|
+
|
|
+MeterClass CpuTempMeter_class = {
|
|
+ .super = {
|
|
+ .extends = Class(Meter),
|
|
+ .delete = Meter_delete
|
|
+ },
|
|
+ .updateValues = CpuTempMeter_setValues,
|
|
+ .defaultMode = TEXT_METERMODE,
|
|
+ .maxItems = 1,
|
|
+ .total = 100.0,
|
|
+ .attributes = CpuTempMeter_attributes,
|
|
+ .name = "CpuTemp",
|
|
+ .uiName = "CpuTemp",
|
|
+ .caption = "Cpu Temp: "
|
|
+};
|
|
diff --git a/CpuTempMeter.h b/CpuTempMeter.h
|
|
new file mode 100644
|
|
index 0000000..3538ac3
|
|
--- /dev/null
|
|
+++ b/CpuTempMeter.h
|
|
@@ -0,0 +1,16 @@
|
|
+/* Do not edit this file. It was automatically generated. */
|
|
+
|
|
+#ifndef HEADER_CpuTempMeter
|
|
+#define HEADER_CpuTempMeter
|
|
+/*
|
|
+htop - CpuTempMeter.h
|
|
+(C) 2020 @lex
|
|
+*/
|
|
+
|
|
+#include "Meter.h"
|
|
+
|
|
+extern int CpuTempMeter_attributes[];
|
|
+
|
|
+extern MeterClass CpuTempMeter_class;
|
|
+
|
|
+#endif
|
|
diff --git a/CpuVcoreMeter.c b/CpuVcoreMeter.c
|
|
new file mode 100644
|
|
index 0000000..03adb6d
|
|
--- /dev/null
|
|
+++ b/CpuVcoreMeter.c
|
|
@@ -0,0 +1,84 @@
|
|
+/*
|
|
+htop - CpuVcoreMeter.c
|
|
+(C) 2020 Alexander Finger
|
|
+*/
|
|
+
|
|
+#include "CpuVcoreMeter.h"
|
|
+#include "Platform.h"
|
|
+#include "CRT.h"
|
|
+
|
|
+/*{
|
|
+#include "Meter.h"
|
|
+}*/
|
|
+
|
|
+
|
|
+int CpuVcoreMeter_attributes[] = {
|
|
+ CPU_VCORE
|
|
+};
|
|
+
|
|
+static void CpuVcoreMeter_setValues(Meter* this, char* buffer, int len) {
|
|
+ int v1,v2;
|
|
+ int Vcore, Vcore_l, Vcore_b;
|
|
+ char buf1[80], buf2[80];
|
|
+ int h;
|
|
+
|
|
+ if (Platform_getCpuBigLITTLE()) {
|
|
+ h = len / 2;
|
|
+ if (h > 79)
|
|
+ h = 79;
|
|
+ Vcore_b = Platform_getCpuVcore_b(this);
|
|
+ if (Vcore_b > 1000) {
|
|
+ Vcore_b /= 1000;
|
|
+ }
|
|
+ if (Vcore_b >= 1000) {
|
|
+ Vcore_b /= 10;
|
|
+ v1 = Vcore_b / 100;
|
|
+ v2 = Vcore_b % 100;
|
|
+ xSnprintf(buf1, h, "%d.%02d V ", v1, v2);
|
|
+ } else {
|
|
+ xSnprintf(buf1, h, "%4d mV", Vcore_b);
|
|
+ }
|
|
+ Vcore_l = Platform_getCpuVcore_l(this);
|
|
+ if (Vcore_l > 1000) {
|
|
+ Vcore_l /= 1000;
|
|
+ }
|
|
+ if (Vcore_l >= 1000) {
|
|
+ Vcore_l /= 10;
|
|
+ v1 = Vcore_l / 100;
|
|
+ v2 = Vcore_l % 100;
|
|
+ xSnprintf(buf2, h, "%d.%02d V ", v1, v2);
|
|
+ } else {
|
|
+ xSnprintf(buf2, h, "%4d mV", Vcore_l);
|
|
+ }
|
|
+ xSnprintf(buffer, len, "%s %s (big.LITTLE)", buf1, buf2);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ Vcore = Platform_getCpuVcore(this);
|
|
+ if (Vcore > 1000) {
|
|
+ Vcore /= 1000;
|
|
+ }
|
|
+ if (Vcore >= 1000) {
|
|
+ Vcore /= 10;
|
|
+ v1 = Vcore / 100;
|
|
+ v2 = Vcore % 100;
|
|
+ xSnprintf(buffer, len, "%d.%02d V", v1, v2);
|
|
+ } else {
|
|
+ xSnprintf(buffer, len, "%4d mV", Vcore);
|
|
+ }
|
|
+}
|
|
+
|
|
+MeterClass CpuVcoreMeter_class = {
|
|
+ .super = {
|
|
+ .extends = Class(Meter),
|
|
+ .delete = Meter_delete
|
|
+ },
|
|
+ .updateValues = CpuVcoreMeter_setValues,
|
|
+ .defaultMode = TEXT_METERMODE,
|
|
+ .maxItems = 1,
|
|
+ .total = 100.0,
|
|
+ .attributes = CpuVcoreMeter_attributes,
|
|
+ .name = "CpuVcore",
|
|
+ .uiName = "CpuVcore",
|
|
+ .caption = "Cpu Vcor: "
|
|
+};
|
|
diff --git a/CpuVcoreMeter.h b/CpuVcoreMeter.h
|
|
new file mode 100644
|
|
index 0000000..603e8e2
|
|
--- /dev/null
|
|
+++ b/CpuVcoreMeter.h
|
|
@@ -0,0 +1,16 @@
|
|
+/* Do not edit this file. It was automatically generated. */
|
|
+
|
|
+#ifndef HEADER_CpuVcoreMeter
|
|
+#define HEADER_CpuVcoreMeter
|
|
+/*
|
|
+htop - CpuVcoreMeter.h
|
|
+(C) 2020 Alexander Finger
|
|
+*/
|
|
+
|
|
+#include "Meter.h"
|
|
+
|
|
+extern int CpuVcoreMeter_attributes[];
|
|
+
|
|
+extern MeterClass CpuVcoreMeter_class;
|
|
+
|
|
+#endif
|
|
diff --git a/Eth0_Meter.c b/Eth0_Meter.c
|
|
new file mode 100644
|
|
index 0000000..90e512a
|
|
--- /dev/null
|
|
+++ b/Eth0_Meter.c
|
|
@@ -0,0 +1,60 @@
|
|
+/*
|
|
+htop - Eth0_Meter.c
|
|
+(C) 2018 @lex
|
|
+*/
|
|
+
|
|
+#include "Eth0_Meter.h"
|
|
+#include "Platform.h"
|
|
+#include "CRT.h"
|
|
+
|
|
+#include "interfaces.h"
|
|
+
|
|
+/*{
|
|
+#include "Meter.h"
|
|
+}*/
|
|
+
|
|
+
|
|
+int Eth0_Meter_attributes[] = {
|
|
+ ETH0_INTERFACE
|
|
+};
|
|
+
|
|
+static void Eth0_Meter_setValues(Meter* this, char* buffer, int len) {
|
|
+ int ret;
|
|
+ static char szIP[48];
|
|
+ static unsigned int use_cached = 0;
|
|
+ Settings* settings = this->pl->settings;
|
|
+
|
|
+ if ((use_cached++ % 2)) {
|
|
+ xSnprintf(buffer, len, "%s", szIP);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (settings->eth0_alias[0] != 0) {
|
|
+ ret = findIP_interface(settings->eth0_alias, szIP, sizeof(szIP));
|
|
+ } else {
|
|
+ ret = findIP_interface("eth0", szIP, sizeof(szIP));
|
|
+ }
|
|
+
|
|
+ if (ret) {
|
|
+ xSnprintf(buffer, len, "%s", szIP);
|
|
+ } else {
|
|
+ xSnprintf(buffer, len, "%s", "down");
|
|
+ }
|
|
+}
|
|
+
|
|
+MeterClass Eth0_Meter_class = {
|
|
+ .super = {
|
|
+ .extends = Class(Meter),
|
|
+ .delete = Meter_delete
|
|
+ },
|
|
+ .updateValues = Eth0_Meter_setValues,
|
|
+ .defaultMode = TEXT_METERMODE,
|
|
+ .maxItems = 8,
|
|
+ .total = 100.0,
|
|
+ .attributes = Eth0_Meter_attributes,
|
|
+ .name = "Eth0",
|
|
+ .uiName = "Eth0 IP",
|
|
+ .caption = "Eth0 IP: ",
|
|
+};
|
|
+
|
|
+
|
|
diff --git a/Eth0_Meter.h b/Eth0_Meter.h
|
|
new file mode 100644
|
|
index 0000000..5443abc
|
|
--- /dev/null
|
|
+++ b/Eth0_Meter.h
|
|
@@ -0,0 +1,17 @@
|
|
+/* Do not edit this file. It was automatically generated. */
|
|
+
|
|
+#ifndef HEADER_Eth0_Meter
|
|
+#define HEADER_Eth0_Meter
|
|
+/*
|
|
+htop - Eth0_Meter.h
|
|
+(C) 2018 @lex
|
|
+*/
|
|
+
|
|
+#include "Meter.h"
|
|
+
|
|
+extern int Eth0_Meter_attributes[];
|
|
+
|
|
+extern MeterClass Eth0_Meter_class;
|
|
+
|
|
+
|
|
+#endif
|
|
diff --git a/Eth0_StatsMeter.c b/Eth0_StatsMeter.c
|
|
new file mode 100644
|
|
index 0000000..974c656
|
|
--- /dev/null
|
|
+++ b/Eth0_StatsMeter.c
|
|
@@ -0,0 +1,83 @@
|
|
+/*
|
|
+htop - Eth0_StatsMeter.c
|
|
+(C) 2020 @lex
|
|
+*/
|
|
+
|
|
+#include "Eth0_StatsMeter.h"
|
|
+#include "Platform.h"
|
|
+#include "CRT.h"
|
|
+
|
|
+#include "interfaces.h"
|
|
+
|
|
+/*{
|
|
+#include "Meter.h"
|
|
+}*/
|
|
+
|
|
+
|
|
+int Eth0_StatsMeter_attributes[] = {
|
|
+ ETH0_INTERFACE
|
|
+};
|
|
+
|
|
+/* borrowed from slurm */
|
|
+static void Eth0_StatsMeter_setValues(Meter* this, char* buffer, int len) {
|
|
+ int ret;
|
|
+ float rxspeed;
|
|
+ float txspeed;
|
|
+ Settings* settings = this->pl->settings;
|
|
+ double refreshdelay;
|
|
+ static double old = 0.;
|
|
+ static double now = 0.;
|
|
+ static int flash = 0;
|
|
+
|
|
+ now = get_wall_time();
|
|
+ refreshdelay = now - old;
|
|
+ if (old == 0.)
|
|
+ refreshdelay = 1.;
|
|
+ old = now;
|
|
+
|
|
+ if (settings->eth0_alias[0] != 0) {
|
|
+ ret = Platform_getEth_stats(settings->eth0_alias, 0, 0);
|
|
+ } else {
|
|
+ ret = Platform_getEth_stats("eth0", 0, 0);
|
|
+ }
|
|
+
|
|
+ if (ret) {
|
|
+ if (Platform_Eth0_stats.rx_bytes_comp > Platform_Eth0_stats.rx_bytes)
|
|
+ Platform_Eth0_stats.rx_bytes_comp = 0;
|
|
+ if (Platform_Eth0_stats.tx_bytes_comp > Platform_Eth0_stats.tx_bytes)
|
|
+ Platform_Eth0_stats.tx_bytes_comp = 0;
|
|
+
|
|
+ /* we assume here the refresdelay is 1 sec which sometimes is 1.5, so we have a peak */
|
|
+ rxspeed = (Platform_Eth0_stats.rx_bytes - Platform_Eth0_stats.rx_bytes_comp) / refreshdelay;
|
|
+ txspeed = (Platform_Eth0_stats.tx_bytes - Platform_Eth0_stats.tx_bytes_comp) / refreshdelay;
|
|
+
|
|
+ xSnprintf(buffer, len, "%.2f KB/s - %.2f KB/s (TX/RX)", (float) txspeed / 1024, (float) rxspeed / 1024);
|
|
+
|
|
+ Platform_Eth0_stats.rx_bytes_comp = Platform_Eth0_stats.rx_bytes;
|
|
+ Platform_Eth0_stats.tx_bytes_comp = Platform_Eth0_stats.tx_bytes;
|
|
+
|
|
+ } else {
|
|
+ if (!(flash % 2))
|
|
+ xSnprintf(buffer, len, "%s", "unavail");
|
|
+ else
|
|
+ xSnprintf(buffer, len, "%s", "");
|
|
+ flash++;
|
|
+ }
|
|
+}
|
|
+
|
|
+MeterClass Eth0_StatsMeter_class = {
|
|
+ .super = {
|
|
+ .extends = Class(Meter),
|
|
+ .delete = Meter_delete
|
|
+ },
|
|
+ .updateValues = Eth0_StatsMeter_setValues,
|
|
+ .defaultMode = TEXT_METERMODE,
|
|
+ .maxItems = 8,
|
|
+ .total = 100.0,
|
|
+ .attributes = Eth0_StatsMeter_attributes,
|
|
+ .name = "Eth0stat",
|
|
+ .uiName = "Eth0 stat",
|
|
+ .caption = "Eth0 stat: ",
|
|
+};
|
|
+
|
|
+
|
|
diff --git a/Eth0_StatsMeter.h b/Eth0_StatsMeter.h
|
|
new file mode 100644
|
|
index 0000000..e44a5cc
|
|
--- /dev/null
|
|
+++ b/Eth0_StatsMeter.h
|
|
@@ -0,0 +1,18 @@
|
|
+/* Do not edit this file. It was automatically generated. */
|
|
+
|
|
+#ifndef HEADER_Eth0_StatsMeter
|
|
+#define HEADER_Eth0_StatsMeter
|
|
+/*
|
|
+htop - Eth0_StatsMeter.h
|
|
+(C) 2020 @lex
|
|
+*/
|
|
+
|
|
+#include "Meter.h"
|
|
+
|
|
+extern int Eth0_StatsMeter_attributes[];
|
|
+
|
|
+/* borrowed from slurm */
|
|
+extern MeterClass Eth0_StatsMeter_class;
|
|
+
|
|
+
|
|
+#endif
|
|
diff --git a/Eth1_Meter.c b/Eth1_Meter.c
|
|
new file mode 100644
|
|
index 0000000..41cfa05
|
|
--- /dev/null
|
|
+++ b/Eth1_Meter.c
|
|
@@ -0,0 +1,60 @@
|
|
+/*
|
|
+htop - Eth1_Meter.c
|
|
+(C) 2018 @lex
|
|
+*/
|
|
+
|
|
+#include "Eth1_Meter.h"
|
|
+#include "Platform.h"
|
|
+#include "CRT.h"
|
|
+
|
|
+#include "interfaces.h"
|
|
+
|
|
+/*{
|
|
+#include "Meter.h"
|
|
+}*/
|
|
+
|
|
+
|
|
+int Eth1_Meter_attributes[] = {
|
|
+ ETH1_INTERFACE
|
|
+};
|
|
+
|
|
+static void Eth1_Meter_setValues(Meter* this, char* buffer, int len) {
|
|
+ int ret;
|
|
+ static char szIP[48];
|
|
+ static unsigned int use_cached = 0;
|
|
+ Settings* settings = this->pl->settings;
|
|
+
|
|
+ if ((use_cached++ % 2)) {
|
|
+ xSnprintf(buffer, len, "%s", szIP);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (settings->eth1_alias[0] != 0) {
|
|
+ ret = findIP_interface(settings->eth1_alias, szIP, sizeof(szIP));
|
|
+ } else {
|
|
+ ret = findIP_interface("eth1", szIP, sizeof(szIP));
|
|
+ }
|
|
+
|
|
+ if (ret) {
|
|
+ xSnprintf(buffer, len, "%s", szIP);
|
|
+ } else {
|
|
+ xSnprintf(buffer, len, "%s", "down");
|
|
+ }
|
|
+}
|
|
+
|
|
+MeterClass Eth1_Meter_class = {
|
|
+ .super = {
|
|
+ .extends = Class(Meter),
|
|
+ .delete = Meter_delete
|
|
+ },
|
|
+ .updateValues = Eth1_Meter_setValues,
|
|
+ .defaultMode = TEXT_METERMODE,
|
|
+ .maxItems = 8,
|
|
+ .total = 100.0,
|
|
+ .attributes = Eth1_Meter_attributes,
|
|
+ .name = "Eth1",
|
|
+ .uiName = "Eth1 IP",
|
|
+ .caption = "Eth1 IP: ",
|
|
+};
|
|
+
|
|
+
|
|
diff --git a/Eth1_Meter.h b/Eth1_Meter.h
|
|
new file mode 100644
|
|
index 0000000..7f7f4fc
|
|
--- /dev/null
|
|
+++ b/Eth1_Meter.h
|
|
@@ -0,0 +1,17 @@
|
|
+/* Do not edit this file. It was automatically generated. */
|
|
+
|
|
+#ifndef HEADER_Eth1_Meter
|
|
+#define HEADER_Eth1_Meter
|
|
+/*
|
|
+htop - Eth1_Meter.h
|
|
+(C) 2018 @lex
|
|
+*/
|
|
+
|
|
+#include "Meter.h"
|
|
+
|
|
+extern int Eth1_Meter_attributes[];
|
|
+
|
|
+extern MeterClass Eth1_Meter_class;
|
|
+
|
|
+
|
|
+#endif
|
|
diff --git a/Eth1_StatsMeter.c b/Eth1_StatsMeter.c
|
|
new file mode 100644
|
|
index 0000000..85e6dc9
|
|
--- /dev/null
|
|
+++ b/Eth1_StatsMeter.c
|
|
@@ -0,0 +1,83 @@
|
|
+/*
|
|
+htop - Eth1_StatsMeter.c
|
|
+(C) 2020 @lex
|
|
+*/
|
|
+
|
|
+#include "Eth1_StatsMeter.h"
|
|
+#include "Platform.h"
|
|
+#include "CRT.h"
|
|
+
|
|
+#include "interfaces.h"
|
|
+
|
|
+/*{
|
|
+#include "Meter.h"
|
|
+}*/
|
|
+
|
|
+
|
|
+int Eth1_StatsMeter_attributes[] = {
|
|
+ ETH1_INTERFACE
|
|
+};
|
|
+
|
|
+/* borrowed from slurm */
|
|
+static void Eth1_StatsMeter_setValues(Meter* this, char* buffer, int len) {
|
|
+ int ret;
|
|
+ float rxspeed;
|
|
+ float txspeed;
|
|
+ Settings* settings = this->pl->settings;
|
|
+ double refreshdelay;
|
|
+ static double old = 0.;
|
|
+ static double now = 0.;
|
|
+ static int flash = 0;
|
|
+
|
|
+ now = get_wall_time();
|
|
+ refreshdelay = now - old;
|
|
+ if (old == 0.)
|
|
+ refreshdelay = 1.;
|
|
+ old = now;
|
|
+
|
|
+ if (settings->eth1_alias[0] != 0) {
|
|
+ ret = Platform_getEth_stats(settings->eth1_alias, 1, 0);
|
|
+ } else {
|
|
+ ret = Platform_getEth_stats("eth1", 1, 0);
|
|
+ }
|
|
+
|
|
+ if (ret) {
|
|
+ if (Platform_Eth1_stats.rx_bytes_comp > Platform_Eth1_stats.rx_bytes)
|
|
+ Platform_Eth1_stats.rx_bytes_comp = 0;
|
|
+ if (Platform_Eth1_stats.tx_bytes_comp > Platform_Eth1_stats.tx_bytes)
|
|
+ Platform_Eth1_stats.tx_bytes_comp = 0;
|
|
+
|
|
+ /* we assume here the refresdelay is 1 sec which sometimes is 1.5, so we have a peak */
|
|
+ rxspeed = (Platform_Eth1_stats.rx_bytes - Platform_Eth1_stats.rx_bytes_comp) / refreshdelay;
|
|
+ txspeed = (Platform_Eth1_stats.tx_bytes - Platform_Eth1_stats.tx_bytes_comp) / refreshdelay;
|
|
+
|
|
+ xSnprintf(buffer, len, "%.2f KB/s - %.2f KB/s (TX/RX)", (float) txspeed / 1024, (float) rxspeed / 1024);
|
|
+
|
|
+ Platform_Eth1_stats.rx_bytes_comp = Platform_Eth1_stats.rx_bytes;
|
|
+ Platform_Eth1_stats.tx_bytes_comp = Platform_Eth1_stats.tx_bytes;
|
|
+
|
|
+ } else {
|
|
+ if (!(flash % 2))
|
|
+ xSnprintf(buffer, len, "%s", "unavail");
|
|
+ else
|
|
+ xSnprintf(buffer, len, "%s", "");
|
|
+ flash++;
|
|
+ }
|
|
+}
|
|
+
|
|
+MeterClass Eth1_StatsMeter_class = {
|
|
+ .super = {
|
|
+ .extends = Class(Meter),
|
|
+ .delete = Meter_delete
|
|
+ },
|
|
+ .updateValues = Eth1_StatsMeter_setValues,
|
|
+ .defaultMode = TEXT_METERMODE,
|
|
+ .maxItems = 8,
|
|
+ .total = 100.0,
|
|
+ .attributes = Eth1_StatsMeter_attributes,
|
|
+ .name = "Eth1stat",
|
|
+ .uiName = "Eth1 stat",
|
|
+ .caption = "Eth1 stat: ",
|
|
+};
|
|
+
|
|
+
|
|
diff --git a/Eth1_StatsMeter.h b/Eth1_StatsMeter.h
|
|
new file mode 100644
|
|
index 0000000..c173b15
|
|
--- /dev/null
|
|
+++ b/Eth1_StatsMeter.h
|
|
@@ -0,0 +1,18 @@
|
|
+/* Do not edit this file. It was automatically generated. */
|
|
+
|
|
+#ifndef HEADER_Eth1_StatsMeter
|
|
+#define HEADER_Eth1_StatsMeter
|
|
+/*
|
|
+htop - Eth1_StatsMeter.h
|
|
+(C) 2020 @lex
|
|
+*/
|
|
+
|
|
+#include "Meter.h"
|
|
+
|
|
+extern int Eth1_StatsMeter_attributes[];
|
|
+
|
|
+/* borrowed from slurm */
|
|
+extern MeterClass Eth1_StatsMeter_class;
|
|
+
|
|
+
|
|
+#endif
|
|
diff --git a/GpuTempMeter.c b/GpuTempMeter.c
|
|
new file mode 100644
|
|
index 0000000..92394b3
|
|
--- /dev/null
|
|
+++ b/GpuTempMeter.c
|
|
@@ -0,0 +1,39 @@
|
|
+/*
|
|
+htop - GpuTempMeter.c
|
|
+(C) 2018 @lex
|
|
+*/
|
|
+
|
|
+#include "GpuTempMeter.h"
|
|
+#include "Platform.h"
|
|
+#include "CRT.h"
|
|
+
|
|
+/*{
|
|
+#include "Meter.h"
|
|
+}*/
|
|
+
|
|
+int GpuTempMeter_attributes[] = {
|
|
+ GPU_TEMP
|
|
+};
|
|
+
|
|
+static void GpuTempMeter_setValues(Meter* this, char* buffer, int len) {
|
|
+ int Temp = Platform_getGpuTemp(this);
|
|
+ if (Temp > 1000) {
|
|
+ Temp /= 1000;
|
|
+ }
|
|
+ xSnprintf(buffer, len, "%4d C", Temp);
|
|
+}
|
|
+
|
|
+MeterClass GpuTempMeter_class = {
|
|
+ .super = {
|
|
+ .extends = Class(Meter),
|
|
+ .delete = Meter_delete
|
|
+ },
|
|
+ .updateValues = GpuTempMeter_setValues,
|
|
+ .defaultMode = TEXT_METERMODE,
|
|
+ .maxItems = 1,
|
|
+ .total = 100.0,
|
|
+ .attributes = GpuTempMeter_attributes,
|
|
+ .name = "GpuTemp",
|
|
+ .uiName = "GpuTemp",
|
|
+ .caption = "Gpu Temp: "
|
|
+};
|
|
diff --git a/GpuTempMeter.h b/GpuTempMeter.h
|
|
new file mode 100644
|
|
index 0000000..40dab90
|
|
--- /dev/null
|
|
+++ b/GpuTempMeter.h
|
|
@@ -0,0 +1,16 @@
|
|
+/* Do not edit this file. It was automatically generated. */
|
|
+
|
|
+#ifndef HEADER_GpuTempMeter
|
|
+#define HEADER_GpuTempMeter
|
|
+/*
|
|
+htop - GpuTempMeter.h
|
|
+(C) 2018 @lex
|
|
+*/
|
|
+
|
|
+#include "Meter.h"
|
|
+
|
|
+extern int GpuTempMeter_attributes[];
|
|
+
|
|
+extern MeterClass GpuTempMeter_class;
|
|
+
|
|
+#endif
|
|
diff --git a/Kernel_Meter.c b/Kernel_Meter.c
|
|
new file mode 100644
|
|
index 0000000..45c675f
|
|
--- /dev/null
|
|
+++ b/Kernel_Meter.c
|
|
@@ -0,0 +1,55 @@
|
|
+/*
|
|
+htop - Kernelversion_Meter.c
|
|
+(C) 2018 @lex
|
|
+*/
|
|
+
|
|
+#include "Kernel_Meter.h"
|
|
+#include "Platform.h"
|
|
+#include "CRT.h"
|
|
+
|
|
+#include "interfaces.h"
|
|
+
|
|
+/*{
|
|
+#include "Meter.h"
|
|
+}*/
|
|
+
|
|
+
|
|
+int Kernelversion_Meter_attributes[] = {
|
|
+ KERNEL_VERSION
|
|
+};
|
|
+
|
|
+static void Kernelversion_Meter_setValues(Meter* this, char* buffer, int len) {
|
|
+ int ret;
|
|
+ static char version[256];
|
|
+ static int use_cached = 0;
|
|
+
|
|
+ if ((use_cached++ % 10)) {
|
|
+ xSnprintf(buffer, len, "%s", version);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ ret = ReadTokenValue( "/proc/version", "Linux version", version);
|
|
+
|
|
+ if (ret) {
|
|
+ xSnprintf(buffer, len, "%s", version);
|
|
+ } else {
|
|
+ xSnprintf(buffer, len, "%s", "down");
|
|
+ }
|
|
+}
|
|
+
|
|
+MeterClass Kernelversion_Meter_class = {
|
|
+ .super = {
|
|
+ .extends = Class(Meter),
|
|
+ .delete = Meter_delete
|
|
+ },
|
|
+ .updateValues = Kernelversion_Meter_setValues,
|
|
+ .defaultMode = TEXT_METERMODE,
|
|
+ .maxItems = 8,
|
|
+ .total = 100.0,
|
|
+ .attributes = Kernelversion_Meter_attributes,
|
|
+ .name = "Kernelversion",
|
|
+ .uiName = "Kernel version",
|
|
+ .caption = "Kernel: ",
|
|
+};
|
|
+
|
|
+
|
|
diff --git a/Kernel_Meter.h b/Kernel_Meter.h
|
|
new file mode 100644
|
|
index 0000000..98f9a1f
|
|
--- /dev/null
|
|
+++ b/Kernel_Meter.h
|
|
@@ -0,0 +1,17 @@
|
|
+/* Do not edit this file. It was automatically generated. */
|
|
+
|
|
+#ifndef HEADER_Kernel_Meter
|
|
+#define HEADER_Kernel_Meter
|
|
+/*
|
|
+htop - Kernelversion_Meter.h
|
|
+(C) 2018 @lex
|
|
+*/
|
|
+
|
|
+#include "Meter.h"
|
|
+
|
|
+extern int Kernelversion_Meter_attributes[];
|
|
+
|
|
+extern MeterClass Kernelversion_Meter_class;
|
|
+
|
|
+
|
|
+#endif
|
|
diff --git a/Makefile.am b/Makefile.am
|
|
index cd5209c..6557c6a 100644
|
|
--- a/Makefile.am
|
|
+++ b/Makefile.am
|
|
@@ -21,7 +21,9 @@ ClockMeter.c ColorsPanel.c ColumnsPanel.c CPUMeter.c CRT.c MainPanel.c \
|
|
DisplayOptionsPanel.c FunctionBar.c Hashtable.c Header.c htop.c ListItem.c \
|
|
LoadAverageMeter.c MemoryMeter.c Meter.c MetersPanel.c Object.c Panel.c \
|
|
BatteryMeter.c Process.c ProcessList.c RichString.c ScreenManager.c Settings.c \
|
|
-SignalsPanel.c StringUtils.c SwapMeter.c TasksMeter.c UptimeMeter.c \
|
|
+SignalsPanel.c StringUtils.c SwapMeter.c TasksMeter.c UptimeMeter.c CpuFreqMeter.c CpuTempMeter.c GpuTempMeter.c CpuVcoreMeter.c \
|
|
+interfaces.c OS_Meter.c Eth0_Meter.c Eth1_Meter.c Wlan0_Meter.c Wlan1_Meter.c Kernel_Meter.c Armbian_Meter.c \
|
|
+Wlan0_StatsMeter.c Eth0_StatsMeter.c Eth1_StatsMeter.c BlockDevice_ioStatsMeter.c \
|
|
TraceScreen.c UsersTable.c Vector.c AvailableColumnsPanel.c AffinityPanel.c \
|
|
HostnameMeter.c OpenFilesScreen.c Affinity.c IncSet.c Action.c EnvScreen.c \
|
|
InfoScreen.c XAlloc.c
|
|
@@ -32,7 +34,9 @@ CPUMeter.h CRT.h MainPanel.h DisplayOptionsPanel.h FunctionBar.h \
|
|
Hashtable.h Header.h htop.h ListItem.h LoadAverageMeter.h MemoryMeter.h \
|
|
BatteryMeter.h Meter.h MetersPanel.h Object.h Panel.h ProcessList.h RichString.h \
|
|
ScreenManager.h Settings.h SignalsPanel.h StringUtils.h SwapMeter.h \
|
|
-TasksMeter.h UptimeMeter.h TraceScreen.h UsersTable.h Vector.h Process.h \
|
|
+TasksMeter.h UptimeMeter.h CpuFreqMeter.h CpuTempMeter.h GpuTempMeter.h CpuVcoreMeter.h TraceScreen.h UsersTable.h Vector.h Process.h \
|
|
+interfaces.h OS_Meter.h Eth0_Meter.h Eth1_Meter.h Wlan0_Meter.h Wlan1_Meter.h Kernel_Meter.h Armbian_Meter.h \
|
|
+Wlan0_StatsMeter.h Eth0_StatsMeter.h Eth1_StatsMeter.h BlockDevice_ioStatsMeter.h \
|
|
AffinityPanel.h HostnameMeter.h OpenFilesScreen.h Affinity.h IncSet.h Action.h \
|
|
EnvScreen.h InfoScreen.h XAlloc.h
|
|
|
|
diff --git a/OS_Meter.c b/OS_Meter.c
|
|
new file mode 100644
|
|
index 0000000..588c234
|
|
--- /dev/null
|
|
+++ b/OS_Meter.c
|
|
@@ -0,0 +1,55 @@
|
|
+/*
|
|
+htop - OSversion_Meter.c
|
|
+(C) 2018 @lex
|
|
+*/
|
|
+
|
|
+#include "OS_Meter.h"
|
|
+#include "Platform.h"
|
|
+#include "CRT.h"
|
|
+
|
|
+#include "interfaces.h"
|
|
+
|
|
+/*{
|
|
+#include "Meter.h"
|
|
+}*/
|
|
+
|
|
+
|
|
+int OSversion_Meter_attributes[] = {
|
|
+ OS_VERSION
|
|
+};
|
|
+
|
|
+static void OSversion_Meter_setValues(Meter* this, char* buffer, int len) {
|
|
+ int ret;
|
|
+ static char version[256];
|
|
+ static int use_cached = 0;
|
|
+
|
|
+ if ((use_cached++ % 10)) {
|
|
+ xSnprintf(buffer, len, "%s", version);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ ret = ReadKeyValue( "/etc/os-release", "PRETTY_NAME=", version);
|
|
+
|
|
+ if (ret) {
|
|
+ xSnprintf(buffer, len, "%s", version);
|
|
+ } else {
|
|
+ xSnprintf(buffer, len, "%s", "down");
|
|
+ }
|
|
+}
|
|
+
|
|
+MeterClass OSversion_Meter_class = {
|
|
+ .super = {
|
|
+ .extends = Class(Meter),
|
|
+ .delete = Meter_delete
|
|
+ },
|
|
+ .updateValues = OSversion_Meter_setValues,
|
|
+ .defaultMode = TEXT_METERMODE,
|
|
+ .maxItems = 8,
|
|
+ .total = 100.0,
|
|
+ .attributes = OSversion_Meter_attributes,
|
|
+ .name = "OSversion",
|
|
+ .uiName = "OS version",
|
|
+ .caption = "OS vers: ",
|
|
+};
|
|
+
|
|
+
|
|
diff --git a/OS_Meter.h b/OS_Meter.h
|
|
new file mode 100644
|
|
index 0000000..c5cccb2
|
|
--- /dev/null
|
|
+++ b/OS_Meter.h
|
|
@@ -0,0 +1,17 @@
|
|
+/* Do not edit this file. It was automatically generated. */
|
|
+
|
|
+#ifndef HEADER_OS_Meter
|
|
+#define HEADER_OS_Meter
|
|
+/*
|
|
+htop - OSversion_Meter.h
|
|
+(C) 2018 @lex
|
|
+*/
|
|
+
|
|
+#include "Meter.h"
|
|
+
|
|
+extern int OSversion_Meter_attributes[];
|
|
+
|
|
+extern MeterClass OSversion_Meter_class;
|
|
+
|
|
+
|
|
+#endif
|
|
diff --git a/Process.c b/Process.c
|
|
index 471f529..9ac5fa6 100644
|
|
--- a/Process.c
|
|
+++ b/Process.c
|
|
@@ -1,6 +1,7 @@
|
|
/*
|
|
htop - Process.c
|
|
(C) 2004-2015 Hisham H. Muhammad
|
|
+(C) 2020 Alexander Finger
|
|
Released under the GNU GPL, see the COPYING file
|
|
in the source distribution for its full text.
|
|
*/
|
|
diff --git a/Process.h b/Process.h
|
|
index f702ca0..fbd9ef5 100644
|
|
--- a/Process.h
|
|
+++ b/Process.h
|
|
@@ -5,6 +5,7 @@
|
|
/*
|
|
htop - Process.h
|
|
(C) 2004-2015 Hisham H. Muhammad
|
|
+(C) 2020 Alexander Finger
|
|
Released under the GNU GPL, see the COPYING file
|
|
in the source distribution for its full text.
|
|
*/
|
|
diff --git a/ProcessList.c b/ProcessList.c
|
|
index 7482b03..4ef1e83 100644
|
|
--- a/ProcessList.c
|
|
+++ b/ProcessList.c
|
|
@@ -69,6 +69,7 @@ typedef struct ProcessList_ {
|
|
unsigned long long int freeSwap;
|
|
|
|
int cpuCount;
|
|
+ int cpuBigLITTLE;
|
|
|
|
} ProcessList;
|
|
|
|
diff --git a/ProcessList.h b/ProcessList.h
|
|
index 572d484..aa0e6c0 100644
|
|
--- a/ProcessList.h
|
|
+++ b/ProcessList.h
|
|
@@ -63,6 +63,7 @@ typedef struct ProcessList_ {
|
|
unsigned long long int freeSwap;
|
|
|
|
int cpuCount;
|
|
+ int cpuBigLITTLE;
|
|
|
|
} ProcessList;
|
|
|
|
diff --git a/ScreenManager.c b/ScreenManager.c
|
|
index 05e1c02..3ae6670 100644
|
|
--- a/ScreenManager.c
|
|
+++ b/ScreenManager.c
|
|
@@ -130,6 +130,7 @@ static void checkRecalculation(ScreenManager* this, double* oldTime, int* sortTi
|
|
if (newTime < *oldTime) *rescan = true; // clock was adjusted?
|
|
if (*rescan) {
|
|
*oldTime = newTime;
|
|
+ Header_draw(this->header);
|
|
ProcessList_scan(pl);
|
|
if (*sortTimeout == 0 || this->settings->treeView) {
|
|
ProcessList_sort(pl);
|
|
@@ -139,7 +140,7 @@ static void checkRecalculation(ScreenManager* this, double* oldTime, int* sortTi
|
|
}
|
|
if (*redraw) {
|
|
ProcessList_rebuildPanel(pl);
|
|
- Header_draw(this->header);
|
|
+ // Header_draw(this->header);
|
|
}
|
|
*rescan = false;
|
|
}
|
|
diff --git a/Settings.c b/Settings.c
|
|
index db2fa06..912ad7d 100644
|
|
--- a/Settings.c
|
|
+++ b/Settings.c
|
|
@@ -59,6 +59,28 @@ typedef struct Settings_ {
|
|
bool accountGuestInCPUMeter;
|
|
bool headerMargin;
|
|
|
|
+ char CpuFreq_handler[256];
|
|
+ char CpuTemp_handler[256];
|
|
+ char CpuVCore_l_handler[256];
|
|
+ char CpuVCore_b_handler[256];
|
|
+
|
|
+ char GpuVCore_handler[256];
|
|
+ char GpuTemp_handler[256];
|
|
+
|
|
+ char BoardName[128];
|
|
+ char KernelVersionFull[256];
|
|
+ char KernelVersionShort[64];
|
|
+
|
|
+ char IP_wlan0[32];
|
|
+ char IP_wlan1[32];
|
|
+ char IP_eth0[32];
|
|
+ char IP_eth1[32];
|
|
+
|
|
+ char eth0_alias[32];
|
|
+ char eth1_alias[32];
|
|
+ char wlan0_alias[32];
|
|
+ char wlan1_alias[32];
|
|
+
|
|
bool changed;
|
|
} Settings;
|
|
|
|
@@ -141,6 +163,12 @@ static void Settings_defaultMeters(Settings* this) {
|
|
this->columns[1].modes[r++] = TEXT_METERMODE;
|
|
this->columns[1].names[r] = xStrdup("Uptime");
|
|
this->columns[1].modes[r++] = TEXT_METERMODE;
|
|
+
|
|
+ this->columns[1].names[r] = xStrdup("CpuTemp");
|
|
+ this->columns[1].modes[r++] = TEXT_METERMODE;
|
|
+ this->columns[1].names[r] = xStrdup("CpuFreq");
|
|
+ this->columns[1].modes[r++] = TEXT_METERMODE;
|
|
+
|
|
}
|
|
|
|
static void readFields(ProcessField* fields, int* flags, const char* line) {
|
|
@@ -244,7 +272,41 @@ static bool Settings_read(Settings* this, const char* fileName) {
|
|
} else if (String_eq(option[0], "right_meter_modes")) {
|
|
Settings_readMeterModes(this, option[1], 1);
|
|
didReadMeters = true;
|
|
- }
|
|
+ } else if (String_eq(option[0], "BoardName")) {
|
|
+ strcpy(this->BoardName,option[1]);
|
|
+ didReadMeters = true;
|
|
+ } else if (String_eq(option[0], "CpuFreq_handler")) {
|
|
+ strcpy(this->CpuFreq_handler,option[1]);
|
|
+ didReadMeters = true;
|
|
+ } else if (String_eq(option[0], "CpuTemp_handler")) {
|
|
+ strcpy(this->CpuTemp_handler,option[1]);
|
|
+ didReadMeters = true;
|
|
+ } else if (String_eq(option[0], "CpuVCore_l_handler")) {
|
|
+ strcpy(this->CpuVCore_l_handler,option[1]);
|
|
+ didReadMeters = true;
|
|
+ } else if (String_eq(option[0], "CpuVCore_b_handler")) {
|
|
+ strcpy(this->CpuVCore_b_handler,option[1]);
|
|
+ didReadMeters = true;
|
|
+ } else if (String_eq(option[0], "GpuVCore_handler")) {
|
|
+ strcpy(this->GpuVCore_handler,option[1]);
|
|
+ didReadMeters = true;
|
|
+ } else if (String_eq(option[0], "GpuTemp_handler")) {
|
|
+ strcpy(this->GpuTemp_handler,option[1]);
|
|
+ didReadMeters = true;
|
|
+ } else if (String_eq(option[0], "eth0_alias")) {
|
|
+ strcpy(this->eth0_alias,option[1]);
|
|
+ didReadMeters = true;
|
|
+ } else if (String_eq(option[0], "eth1_alias")) {
|
|
+ strcpy(this->eth1_alias,option[1]);
|
|
+ didReadMeters = true;
|
|
+ } else if (String_eq(option[0], "wlan0_alias")) {
|
|
+ strcpy(this->wlan0_alias,option[1]);
|
|
+ didReadMeters = true;
|
|
+ } else if (String_eq(option[0], "wlan1_alias")) {
|
|
+ strcpy(this->wlan1_alias,option[1]);
|
|
+ didReadMeters = true;
|
|
+ }
|
|
+
|
|
String_freeArray(option);
|
|
}
|
|
fclose(fd);
|
|
@@ -320,6 +382,23 @@ bool Settings_write(Settings* this) {
|
|
fprintf(fd, "left_meter_modes="); writeMeterModes(this, fd, 0);
|
|
fprintf(fd, "right_meters="); writeMeters(this, fd, 1);
|
|
fprintf(fd, "right_meter_modes="); writeMeterModes(this, fd, 1);
|
|
+
|
|
+ fprintf(fd, "# SBC hardware and Kernel specific path.\n");
|
|
+ fprintf(fd, "# Editable manually.\n");
|
|
+ fprintf(fd, "BoardName=%s\n", this->BoardName);
|
|
+ fprintf(fd, "CpuFreq_handler=%s\n", this->CpuFreq_handler);
|
|
+ fprintf(fd, "CpuTemp_handler=%s\n", this->CpuTemp_handler);
|
|
+ fprintf(fd, "CpuVCore_l_handler=%s\n", this->CpuVCore_l_handler);
|
|
+ fprintf(fd, "CpuVCore_b_handler=%s\n", this->CpuVCore_b_handler);
|
|
+ fprintf(fd, "GpuVCore_handler=%s\n", this->GpuVCore_handler);
|
|
+ fprintf(fd, "GpuTemp_handler=%s\n", this->GpuTemp_handler);
|
|
+
|
|
+ fprintf(fd, "# Wlan / Eth alias\n");
|
|
+ fprintf(fd, "eth0_alias=%s\n",this->eth0_alias);
|
|
+ fprintf(fd, "eth1_alias=%s\n",this->eth1_alias);
|
|
+ fprintf(fd, "wlan0_alias=%s\n",this->wlan0_alias);
|
|
+ fprintf(fd, "wlan1_alias=%s\n",this->wlan1_alias);
|
|
+
|
|
fclose(fd);
|
|
return true;
|
|
}
|
|
diff --git a/Settings.h b/Settings.h
|
|
index d9dc068..4fcd885 100644
|
|
--- a/Settings.h
|
|
+++ b/Settings.h
|
|
@@ -50,6 +50,28 @@ typedef struct Settings_ {
|
|
bool accountGuestInCPUMeter;
|
|
bool headerMargin;
|
|
|
|
+ char CpuFreq_handler[256];
|
|
+ char CpuTemp_handler[256];
|
|
+ char CpuVCore_l_handler[256];
|
|
+ char CpuVCore_b_handler[256];
|
|
+
|
|
+ char GpuVCore_handler[256];
|
|
+ char GpuTemp_handler[256];
|
|
+
|
|
+ char BoardName[128];
|
|
+ char KernelVersionFull[256];
|
|
+ char KernelVersionShort[64];
|
|
+
|
|
+ char IP_wlan0[32];
|
|
+ char IP_wlan1[32];
|
|
+ char IP_eth0[32];
|
|
+ char IP_eth1[32];
|
|
+
|
|
+ char eth0_alias[32];
|
|
+ char eth1_alias[32];
|
|
+ char wlan0_alias[32];
|
|
+ char wlan1_alias[32];
|
|
+
|
|
bool changed;
|
|
} Settings;
|
|
|
|
diff --git a/Wlan0_Meter.c b/Wlan0_Meter.c
|
|
new file mode 100644
|
|
index 0000000..bf75623
|
|
--- /dev/null
|
|
+++ b/Wlan0_Meter.c
|
|
@@ -0,0 +1,58 @@
|
|
+/*
|
|
+htop - Wlan0_Meter.c
|
|
+(C) 2020 @lex
|
|
+*/
|
|
+
|
|
+#include "Wlan0_Meter.h"
|
|
+#include "Platform.h"
|
|
+#include "CRT.h"
|
|
+
|
|
+/*{
|
|
+#include "Meter.h"
|
|
+}*/
|
|
+
|
|
+
|
|
+int Wlan0_Meter_attributes[] = {
|
|
+ WLAN0_INTERFACE
|
|
+};
|
|
+
|
|
+static void Wlan0_Meter_setValues(Meter* this, char* buffer, int len) {
|
|
+ int ret;
|
|
+ static char szIP[48];
|
|
+ static unsigned int use_cached = 0;
|
|
+ Settings* settings = this->pl->settings;
|
|
+
|
|
+ if ((use_cached++ % 2)) {
|
|
+ xSnprintf(buffer, len, "%s", szIP);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (settings->wlan0_alias[0] != 0) {
|
|
+ ret = findIP_interface(settings->wlan0_alias, szIP, sizeof(szIP));
|
|
+ } else {
|
|
+ ret = findIP_interface("wlan0", szIP, sizeof(szIP));
|
|
+ }
|
|
+
|
|
+ if (ret) {
|
|
+ xSnprintf(buffer, len, "%s", szIP);
|
|
+ } else {
|
|
+ xSnprintf(buffer, len, "%s", "down");
|
|
+ }
|
|
+}
|
|
+
|
|
+MeterClass Wlan0_Meter_class = {
|
|
+ .super = {
|
|
+ .extends = Class(Meter),
|
|
+ .delete = Meter_delete
|
|
+ },
|
|
+ .updateValues = Wlan0_Meter_setValues,
|
|
+ .defaultMode = TEXT_METERMODE,
|
|
+ .maxItems = 8,
|
|
+ .total = 100.0,
|
|
+ .attributes = Wlan0_Meter_attributes,
|
|
+ .name = "Wlan0",
|
|
+ .uiName = "Wlan0 IP",
|
|
+ .caption = "Wlan0 IP: ",
|
|
+};
|
|
+
|
|
+
|
|
diff --git a/Wlan0_Meter.h b/Wlan0_Meter.h
|
|
new file mode 100644
|
|
index 0000000..59761ff
|
|
--- /dev/null
|
|
+++ b/Wlan0_Meter.h
|
|
@@ -0,0 +1,17 @@
|
|
+/* Do not edit this file. It was automatically generated. */
|
|
+
|
|
+#ifndef HEADER_Wlan0_Meter
|
|
+#define HEADER_Wlan0_Meter
|
|
+/*
|
|
+htop - Wlan0_Meter.h
|
|
+(C) 2020 @lex
|
|
+*/
|
|
+
|
|
+#include "Meter.h"
|
|
+
|
|
+extern int Wlan0_Meter_attributes[];
|
|
+
|
|
+extern MeterClass Wlan0_Meter_class;
|
|
+
|
|
+
|
|
+#endif
|
|
diff --git a/Wlan0_StatsMeter.c b/Wlan0_StatsMeter.c
|
|
new file mode 100644
|
|
index 0000000..f920f9c
|
|
--- /dev/null
|
|
+++ b/Wlan0_StatsMeter.c
|
|
@@ -0,0 +1,83 @@
|
|
+/*
|
|
+htop - Wlan0_StatsMeter.c
|
|
+(C) 2020 @lex
|
|
+*/
|
|
+
|
|
+#include "Wlan0_StatsMeter.h"
|
|
+#include "Platform.h"
|
|
+#include "CRT.h"
|
|
+
|
|
+#include "interfaces.h"
|
|
+
|
|
+/*{
|
|
+#include "Meter.h"
|
|
+}*/
|
|
+
|
|
+
|
|
+int Wlan0_StatsMeter_attributes[] = {
|
|
+ ETH0_INTERFACE
|
|
+};
|
|
+
|
|
+/* borrowed from slurm */
|
|
+static void Wlan0_StatsMeter_setValues(Meter* this, char* buffer, int len) {
|
|
+ int ret;
|
|
+ float rxspeed;
|
|
+ float txspeed;
|
|
+ Settings* settings = this->pl->settings;
|
|
+ double refreshdelay;
|
|
+ static double old = 0.;
|
|
+ static double now = 0.;
|
|
+ static int flash = 0;
|
|
+
|
|
+ now = get_wall_time();
|
|
+ refreshdelay = now - old;
|
|
+ if (old == 0.)
|
|
+ refreshdelay = 1.;
|
|
+ old = now;
|
|
+
|
|
+ if (settings->wlan0_alias[0] != 0) {
|
|
+ ret = Platform_getEth_stats(settings->wlan0_alias, 2, 0);
|
|
+ } else {
|
|
+ ret = Platform_getEth_stats("wlan0", 0, 0);
|
|
+ }
|
|
+
|
|
+ if (ret) {
|
|
+ if (Platform_Wlan0_stats.rx_bytes_comp > Platform_Wlan0_stats.rx_bytes)
|
|
+ Platform_Wlan0_stats.rx_bytes_comp = 0;
|
|
+ if (Platform_Wlan0_stats.tx_bytes_comp > Platform_Wlan0_stats.tx_bytes)
|
|
+ Platform_Wlan0_stats.tx_bytes_comp = 0;
|
|
+
|
|
+ /* we assume here the refresdelay is 1 sec which sometimes is 1.5, so we have a peak */
|
|
+ rxspeed = (Platform_Wlan0_stats.rx_bytes - Platform_Wlan0_stats.rx_bytes_comp) / refreshdelay;
|
|
+ txspeed = (Platform_Wlan0_stats.tx_bytes - Platform_Wlan0_stats.tx_bytes_comp) / refreshdelay;
|
|
+
|
|
+ xSnprintf(buffer, len, "%.2f KB/s - %.2f KB/s (TX/RX)", (float) txspeed / 1024, (float) rxspeed / 1024);
|
|
+
|
|
+ Platform_Wlan0_stats.rx_bytes_comp = Platform_Wlan0_stats.rx_bytes;
|
|
+ Platform_Wlan0_stats.tx_bytes_comp = Platform_Wlan0_stats.tx_bytes;
|
|
+
|
|
+ } else {
|
|
+ if (!(flash % 2))
|
|
+ xSnprintf(buffer, len, "%s", "unavail");
|
|
+ else
|
|
+ xSnprintf(buffer, len, "%s", "");
|
|
+ flash++;
|
|
+ }
|
|
+}
|
|
+
|
|
+MeterClass Wlan0_StatsMeter_class = {
|
|
+ .super = {
|
|
+ .extends = Class(Meter),
|
|
+ .delete = Meter_delete
|
|
+ },
|
|
+ .updateValues = Wlan0_StatsMeter_setValues,
|
|
+ .defaultMode = TEXT_METERMODE,
|
|
+ .maxItems = 8,
|
|
+ .total = 100.0,
|
|
+ .attributes = Wlan0_StatsMeter_attributes,
|
|
+ .name = "Wlan0stat",
|
|
+ .uiName = "Wlan0 stat",
|
|
+ .caption = "Wlan0 stat: ",
|
|
+};
|
|
+
|
|
+
|
|
diff --git a/Wlan0_StatsMeter.h b/Wlan0_StatsMeter.h
|
|
new file mode 100644
|
|
index 0000000..2880f9d
|
|
--- /dev/null
|
|
+++ b/Wlan0_StatsMeter.h
|
|
@@ -0,0 +1,18 @@
|
|
+/* Do not edit this file. It was automatically generated. */
|
|
+
|
|
+#ifndef HEADER_Wlan0_StatsMeter
|
|
+#define HEADER_Wlan0_StatsMeter
|
|
+/*
|
|
+htop - Wlan0_StatsMeter.h
|
|
+(C) 2020 @lex
|
|
+*/
|
|
+
|
|
+#include "Meter.h"
|
|
+
|
|
+extern int Wlan0_StatsMeter_attributes[];
|
|
+
|
|
+/* borrowed from slurm */
|
|
+extern MeterClass Wlan0_StatsMeter_class;
|
|
+
|
|
+
|
|
+#endif
|
|
diff --git a/Wlan1_Meter.c b/Wlan1_Meter.c
|
|
new file mode 100644
|
|
index 0000000..c5acd69
|
|
--- /dev/null
|
|
+++ b/Wlan1_Meter.c
|
|
@@ -0,0 +1,60 @@
|
|
+/*
|
|
+htop - Eth0_Meter.c
|
|
+(C) 2018 @lex
|
|
+*/
|
|
+
|
|
+#include "Wlan1_Meter.h"
|
|
+#include "Platform.h"
|
|
+#include "CRT.h"
|
|
+
|
|
+#include "interfaces.h"
|
|
+
|
|
+/*{
|
|
+#include "Meter.h"
|
|
+}*/
|
|
+
|
|
+
|
|
+int Wlan1_Meter_attributes[] = {
|
|
+ WLAN1_INTERFACE
|
|
+};
|
|
+
|
|
+static void Wlan1_Meter_setValues(Meter* this, char* buffer, int len) {
|
|
+ int ret;
|
|
+ static char szIP[48];
|
|
+ static unsigned int use_cached = 0;
|
|
+ Settings* settings = this->pl->settings;
|
|
+
|
|
+ if ((use_cached++ % 2)) {
|
|
+ xSnprintf(buffer, len, "%s", szIP);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (settings->wlan1_alias[0] != 0) {
|
|
+ ret = findIP_interface(settings->wlan1_alias, szIP, sizeof(szIP));
|
|
+ } else {
|
|
+ ret = findIP_interface("wlan1", szIP, sizeof(szIP));
|
|
+ }
|
|
+
|
|
+ if (ret) {
|
|
+ xSnprintf(buffer, len, "%s", szIP);
|
|
+ } else {
|
|
+ xSnprintf(buffer, len, "%s", "down");
|
|
+ }
|
|
+}
|
|
+
|
|
+MeterClass Wlan1_Meter_class = {
|
|
+ .super = {
|
|
+ .extends = Class(Meter),
|
|
+ .delete = Meter_delete
|
|
+ },
|
|
+ .updateValues = Wlan1_Meter_setValues,
|
|
+ .defaultMode = TEXT_METERMODE,
|
|
+ .maxItems = 8,
|
|
+ .total = 100.0,
|
|
+ .attributes = Wlan1_Meter_attributes,
|
|
+ .name = "Wlan1",
|
|
+ .uiName = "Wlan1 IP",
|
|
+ .caption = "Wlan1 IP: ",
|
|
+};
|
|
+
|
|
+
|
|
diff --git a/Wlan1_Meter.h b/Wlan1_Meter.h
|
|
new file mode 100644
|
|
index 0000000..4bba228
|
|
--- /dev/null
|
|
+++ b/Wlan1_Meter.h
|
|
@@ -0,0 +1,17 @@
|
|
+/* Do not edit this file. It was automatically generated. */
|
|
+
|
|
+#ifndef HEADER_Wlan1_Meter
|
|
+#define HEADER_Wlan1_Meter
|
|
+/*
|
|
+htop - Eth0_Meter.h
|
|
+(C) 2018 @lex
|
|
+*/
|
|
+
|
|
+#include "Meter.h"
|
|
+
|
|
+extern int Wlan1_Meter_attributes[];
|
|
+
|
|
+extern MeterClass Wlan1_Meter_class;
|
|
+
|
|
+
|
|
+#endif
|
|
diff --git a/htop.c b/htop.c
|
|
index 6db81dd..0044eb8 100644
|
|
--- a/htop.c
|
|
+++ b/htop.c
|
|
@@ -1,6 +1,7 @@
|
|
/*
|
|
htop - htop.c
|
|
(C) 2004-2011 Hisham H. Muhammad
|
|
+(C) 2020 Alexander Finger
|
|
Released under the GNU GPL, see the COPYING file
|
|
in the source distribution for its full text.
|
|
*/
|
|
@@ -170,7 +171,6 @@ static void millisleep(unsigned long millisec) {
|
|
}
|
|
|
|
int main(int argc, char** argv) {
|
|
-
|
|
char *lc_ctype = getenv("LC_CTYPE");
|
|
if(lc_ctype != NULL)
|
|
setlocale(LC_CTYPE, lc_ctype);
|
|
@@ -193,6 +193,8 @@ int main(int argc, char** argv) {
|
|
UsersTable* ut = UsersTable_new();
|
|
ProcessList* pl = ProcessList_new(ut, flags.pidWhiteList, flags.userId);
|
|
|
|
+ Platform_findCpuBigLITTLE(pl->cpuCount, &pl->cpuBigLITTLE);
|
|
+
|
|
Settings* settings = Settings_new(pl->cpuCount);
|
|
pl->settings = settings;
|
|
|
|
@@ -243,7 +245,16 @@ int main(int argc, char** argv) {
|
|
mvhline(LINES-1, 0, ' ', COLS);
|
|
attroff(CRT_colors[RESET_COLOR]);
|
|
refresh();
|
|
-
|
|
+
|
|
+ Platform_getEth_stats("", -1, 1);
|
|
+ Platform_getIO_stats("", 0, 1);
|
|
+ Platform_getIO_stats("", 1, 1);
|
|
+ Platform_getIO_stats("", 2, 1);
|
|
+ Platform_getIO_stats("", 3, 1);
|
|
+ Platform_getIO_stats("", 4, 1);
|
|
+ Platform_getIO_stats("", 5, 1);
|
|
+ Platform_getIO_stats("", 6, 1);
|
|
+ Platform_getIO_stats("", 7, 1);
|
|
CRT_done();
|
|
if (settings->changed)
|
|
Settings_write(settings);
|
|
diff --git a/htop.h b/htop.h
|
|
index 7faa6c6..05d5fd4 100644
|
|
--- a/htop.h
|
|
+++ b/htop.h
|
|
@@ -5,6 +5,7 @@
|
|
/*
|
|
htop - htop.h
|
|
(C) 2004-2011 Hisham H. Muhammad
|
|
+(C) 2020 Alexander Finger
|
|
Released under the GNU GPL, see the COPYING file
|
|
in the source distribution for its full text.
|
|
*/
|
|
diff --git a/interfaces.c b/interfaces.c
|
|
new file mode 100644
|
|
index 0000000..aa41d2a
|
|
--- /dev/null
|
|
+++ b/interfaces.c
|
|
@@ -0,0 +1,206 @@
|
|
+#include <errno.h>
|
|
+#include <string.h>
|
|
+#include <stdio.h>
|
|
+#include <stdlib.h>
|
|
+#include <ctype.h>
|
|
+#include <unistd.h>
|
|
+#include <linux/i2c-dev.h>
|
|
+#include <sys/ioctl.h>
|
|
+#include <sys/types.h>
|
|
+#include <sys/stat.h>
|
|
+#include <fcntl.h>
|
|
+#include <time.h>
|
|
+#include <unistd.h>
|
|
+#include <sys/types.h>
|
|
+#include <ifaddrs.h>
|
|
+#include <arpa/inet.h>
|
|
+#include <sys/socket.h>
|
|
+#include <netdb.h>
|
|
+#include <linux/if_link.h>
|
|
+#include <linux/if.h>
|
|
+#include <signal.h>
|
|
+
|
|
+#include "interfaces.h"
|
|
+#include "Settings.h"
|
|
+
|
|
+#define BLEN 256
|
|
+/*
|
|
+ /etc/armbian-release
|
|
+ VERSION=20.02.1
|
|
+
|
|
+ /etc/debian_version
|
|
+ buster/sid
|
|
+
|
|
+ cat /etc/lsb-release
|
|
+ DISTRIB_DESCRIPTION="Ubuntu 18.04.5 LTS"
|
|
+
|
|
+ cat /etc/os-release
|
|
+ PRETTY_NAME="Ubuntu 18.04.5 LTS"
|
|
+ VERSION="18.04.5 LTS (Bionic Beaver)"
|
|
+ ID=ubuntu
|
|
+
|
|
+ cat /proc/version
|
|
+ Linux version 5.3.0-52-generic (buildd@lgw01-amd64-037) (gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)) #46~18.04.1-Ubuntu SMP Thu Apr 30 16:13:51 UTC 2020
|
|
+*/
|
|
+
|
|
+
|
|
+int ReadKeyValue( char *fname, char *key, char *value) {
|
|
+ FILE* fp;
|
|
+ char buffer[BLEN];
|
|
+ int fd = 0;
|
|
+ int len = strlen(key);
|
|
+ char *str;
|
|
+ char *str_end;
|
|
+
|
|
+ fp = fopen(fname, "r");
|
|
+ if (fp == NULL)
|
|
+ return fd;
|
|
+
|
|
+ while (fgets(buffer, BLEN, fp) != NULL) {
|
|
+ str = strstr(buffer, key);
|
|
+ if (str != NULL) {
|
|
+ fd = 1;
|
|
+ str += len;
|
|
+ if (*str == '\"') {
|
|
+ str++;
|
|
+ len = strlen(str);
|
|
+ str_end = str + len;
|
|
+ while (*str_end != '\"') {
|
|
+ *str_end = 0;
|
|
+ str_end--;
|
|
+ if (str_end == str)
|
|
+ break;
|
|
+ }
|
|
+ *str_end = 0;
|
|
+ strcpy(value, str);
|
|
+ fd = 1;
|
|
+ } else {
|
|
+ strcpy(value, str);
|
|
+ fd = 1;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ fclose(fp);
|
|
+ return fd;
|
|
+}
|
|
+
|
|
+int ReadTokenValue( char *fname, char *key, char *value) {
|
|
+ FILE* fp;
|
|
+ char buffer[BLEN];
|
|
+ int fd = 0;
|
|
+ int len = strlen(key);
|
|
+ char *str;
|
|
+ char *str_end;
|
|
+
|
|
+ fp = fopen(fname, "r");
|
|
+ if (fp == NULL)
|
|
+ return fd;
|
|
+
|
|
+ while (fgets(buffer, BLEN, fp) != NULL) {
|
|
+ str = strstr(buffer, key);
|
|
+ if (str != NULL) {
|
|
+ fd = 1;
|
|
+ str += len;
|
|
+ str++;
|
|
+ str_end = str;
|
|
+ while (*str_end != ' ' && *str_end != 0) {
|
|
+ str_end++;
|
|
+ }
|
|
+ *str_end = 0;
|
|
+ strcpy(value, str);
|
|
+ fd = 1;
|
|
+ }
|
|
+ }
|
|
+ fclose(fp);
|
|
+ return fd;
|
|
+}
|
|
+
|
|
+char *ltrim(char *str) {
|
|
+ while(isspace(*str))
|
|
+ str++;
|
|
+ return str;
|
|
+}
|
|
+
|
|
+char *rtrim(char *str) {
|
|
+ char* end = str + strlen(str);
|
|
+ while (isspace(*--end))
|
|
+ ;
|
|
+ *(end + 1) = '\0';
|
|
+ return str;
|
|
+}
|
|
+
|
|
+char *trim(char *str) {
|
|
+ return rtrim(ltrim(str));
|
|
+}
|
|
+
|
|
+int FindDataValueFromKey( char *fname, char *key, char *value) {
|
|
+ FILE* fp;
|
|
+ char buffer[BLEN];
|
|
+ int fd = 0;
|
|
+ char *str;
|
|
+ char *str_end;
|
|
+ char *str_start;
|
|
+
|
|
+ fp = fopen(fname, "r");
|
|
+ if (fp == NULL)
|
|
+ return fd;
|
|
+
|
|
+ while (fgets(buffer, BLEN, fp) != NULL) {
|
|
+ str_start = buffer;
|
|
+ str_end = strchr(buffer, ':');
|
|
+ if (str_end != NULL) {
|
|
+ *str_end = 0;
|
|
+ str_start = trim(str_start);
|
|
+ if (strcasecmp(str_start, key) == 0) {
|
|
+ str = str_end + 1;
|
|
+ str = trim(str);
|
|
+ strcpy(value, str);
|
|
+ printf("key: %s, value: %s\n", str_start, str);
|
|
+ fd = 1;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ fclose(fp);
|
|
+ return fd;
|
|
+}
|
|
+
|
|
+
|
|
+int findIP_interface(char *dev, char *szIP, int bufsz) {
|
|
+ struct ifaddrs *ifaddr, *ifa;
|
|
+ int family, s, n;
|
|
+ char host[NI_MAXHOST];
|
|
+ int found_if = 0;
|
|
+ int len = strlen(dev);
|
|
+
|
|
+ /* get interface information */
|
|
+ if (getifaddrs(&ifaddr) != -1) {
|
|
+ for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) {
|
|
+ if (ifa->ifa_addr == NULL)
|
|
+ continue;
|
|
+
|
|
+ family = ifa->ifa_addr->sa_family;
|
|
+ if ((strncmp (dev, ifa->ifa_name, len ) == 0) && (family == AF_INET || family == AF_INET6)) {
|
|
+ s = getnameinfo(ifa->ifa_addr,
|
|
+ (ifa->ifa_addr->sa_family == AF_INET) ? sizeof(struct sockaddr_in) :
|
|
+ sizeof(struct sockaddr_in6),
|
|
+ host, NI_MAXHOST,
|
|
+ NULL, 0, NI_NUMERICHOST);
|
|
+ if (s != 0) {
|
|
+ break;
|
|
+ }
|
|
+ if ((ifa->ifa_flags & IFF_UP) == 0)
|
|
+ continue;
|
|
+ if ((ifa->ifa_flags & IFF_RUNNING) == 0)
|
|
+ continue;
|
|
+ found_if = 1;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ if (found_if) {
|
|
+ snprintf ( szIP, bufsz, "%s", host );
|
|
+ }
|
|
+ freeifaddrs(ifaddr);
|
|
+ }
|
|
+ return found_if;
|
|
+}
|
|
diff --git a/interfaces.h b/interfaces.h
|
|
new file mode 100644
|
|
index 0000000..adb4e5b
|
|
--- /dev/null
|
|
+++ b/interfaces.h
|
|
@@ -0,0 +1,40 @@
|
|
+/* Do not edit this file. It was automatically generated. */
|
|
+
|
|
+#ifndef HEADER_interfaces
|
|
+#define HEADER_interfaces
|
|
+
|
|
+#define BLEN 256
|
|
+/*
|
|
+ /etc/armbian-release
|
|
+ VERSION=20.02.1
|
|
+
|
|
+ /etc/debian_version
|
|
+ buster/sid
|
|
+
|
|
+ cat /etc/lsb-release
|
|
+ DISTRIB_DESCRIPTION="Ubuntu 18.04.5 LTS"
|
|
+
|
|
+ cat /etc/os-release
|
|
+ PRETTY_NAME="Ubuntu 18.04.5 LTS"
|
|
+ VERSION="18.04.5 LTS (Bionic Beaver)"
|
|
+ ID=ubuntu
|
|
+
|
|
+ cat /proc/version
|
|
+ Linux version 5.3.0-52-generic (buildd@lgw01-amd64-037) (gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)) #46~18.04.1-Ubuntu SMP Thu Apr 30 16:13:51 UTC 2020
|
|
+*/
|
|
+
|
|
+int ReadKeyValue( char *fname, char *key, char *value);
|
|
+
|
|
+int ReadTokenValue( char *fname, char *key, char *value);
|
|
+
|
|
+char *ltrim(char *str);
|
|
+
|
|
+char *rtrim(char *str);
|
|
+
|
|
+char *trim(char *str);
|
|
+
|
|
+int FindDataValueFromKey( char *fname, char *key, char *value);
|
|
+
|
|
+int findIP_interface(char *dev, char *szIP, int bufsz);
|
|
+
|
|
+#endif
|
|
diff --git a/linux/Platform.c b/linux/Platform.c
|
|
index ab90ca7..e87089c 100644
|
|
--- a/linux/Platform.c
|
|
+++ b/linux/Platform.c
|
|
@@ -1,6 +1,7 @@
|
|
/*
|
|
htop - linux/Platform.c
|
|
(C) 2014 Hisham H. Muhammad
|
|
+(C) 2020 Alexander Finger
|
|
Released under the GNU GPL, see the COPYING file
|
|
in the source distribution for its full text.
|
|
*/
|
|
@@ -14,6 +15,21 @@ in the source distribution for its full text.
|
|
|
|
#include "Meter.h"
|
|
#include "CPUMeter.h"
|
|
+#include "CpuFreqMeter.h"
|
|
+#include "CpuTempMeter.h"
|
|
+#include "GpuTempMeter.h"
|
|
+#include "CpuVcoreMeter.h"
|
|
+#include "Eth0_StatsMeter.h"
|
|
+#include "Eth1_StatsMeter.h"
|
|
+#include "Wlan0_StatsMeter.h"
|
|
+#include "BlockDevice_ioStatsMeter.h"
|
|
+#include "Eth0_Meter.h"
|
|
+#include "Eth1_Meter.h"
|
|
+#include "Wlan0_Meter.h"
|
|
+#include "Wlan1_Meter.h"
|
|
+#include "Armbian_Meter.h"
|
|
+#include "OS_Meter.h"
|
|
+#include "Kernel_Meter.h"
|
|
#include "MemoryMeter.h"
|
|
#include "SwapMeter.h"
|
|
#include "TasksMeter.h"
|
|
@@ -22,12 +38,23 @@ in the source distribution for its full text.
|
|
#include "ClockMeter.h"
|
|
#include "HostnameMeter.h"
|
|
#include "LinuxProcess.h"
|
|
+#include "Settings.h"
|
|
+#include "interfaces.h"
|
|
+
|
|
+#ifdef WIN32
|
|
+#include <windows.h>
|
|
+#elif _POSIX_C_SOURCE >= 199309L
|
|
+#include <time.h> /* for nanosleep */
|
|
+#else
|
|
+#include <unistd.h> /* for usleep */
|
|
+#endif
|
|
|
|
#include <math.h>
|
|
#include <assert.h>
|
|
#include <limits.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
+#include <sys/time.h>
|
|
|
|
/*{
|
|
#include "Action.h"
|
|
@@ -35,6 +62,50 @@ in the source distribution for its full text.
|
|
#include "BatteryMeter.h"
|
|
#include "LinuxProcess.h"
|
|
#include "SignalsPanel.h"
|
|
+#ifdef WIN32
|
|
+#include <windows.h>
|
|
+#elif _POSIX_C_SOURCE >= 199309L
|
|
+#include <time.h>
|
|
+#else
|
|
+#include <unistd.h>
|
|
+#endif
|
|
+#include <string.h>
|
|
+
|
|
+
|
|
+typedef enum vendor_id_ {
|
|
+ VENDOR_INTEL,
|
|
+ VENDOR_AMD,
|
|
+ VENDOR_CYRIX,
|
|
+ VENDOR_VIA,
|
|
+ VENDOR_TRANSMETA,
|
|
+ VENDOR_UMC,
|
|
+ VENDOR_NEXGEN,
|
|
+ VENDOR_RISE,
|
|
+ VENDOR_SIS,
|
|
+ VENDOR_NSC,
|
|
+ VENDOR_VORTEX,
|
|
+ VENDOR_RDC,
|
|
+ VENDOR_UNKNOWN
|
|
+} vendor_id;
|
|
+
|
|
+typedef struct Stats_ {
|
|
+ int rx_over;
|
|
+ int tx_over;
|
|
+ double rx_bytes;
|
|
+ double tx_bytes;
|
|
+ double rx_bytes_comp;
|
|
+ double tx_bytes_comp;
|
|
+} Stats;
|
|
+
|
|
+typedef struct ioStats_ {
|
|
+ int read_over;
|
|
+ int write_over;
|
|
+ double read_sectors;
|
|
+ double write_sectors;
|
|
+ double read_sectors_comp;
|
|
+ double write_sectors_comp;
|
|
+} ioStats;
|
|
+
|
|
}*/
|
|
|
|
#ifndef CLAMP
|
|
@@ -45,6 +116,7 @@ ProcessField Platform_defaultFields[] = { PID, USER, PRIORITY, NICE, M_SIZE, M_R
|
|
|
|
//static ProcessField defaultIoFields[] = { PID, IO_PRIORITY, USER, IO_READ_RATE, IO_WRITE_RATE, IO_RATE, COMM, 0 };
|
|
|
|
+int Platform_cpuBigLITTLE = 0;
|
|
int Platform_numberOfFields = LAST_PROCESSFIELD;
|
|
|
|
const SignalItem Platform_signals[] = {
|
|
@@ -126,9 +198,270 @@ MeterClass* Platform_meterTypes[] = {
|
|
&LeftCPUs2Meter_class,
|
|
&RightCPUs2Meter_class,
|
|
&BlankMeter_class,
|
|
+ &CpuTempMeter_class,
|
|
+ &CpuFreqMeter_class,
|
|
+ /* --- fix me --- &AllCpuFreqMeter_class, */
|
|
+ &CpuVcoreMeter_class,
|
|
+ &GpuTempMeter_class,
|
|
+ /* interfaces */
|
|
+ &Eth0_Meter_class,
|
|
+ &Eth1_Meter_class,
|
|
+ &Wlan0_Meter_class,
|
|
+ &Wlan0_StatsMeter_class,
|
|
+ &Wlan1_Meter_class,
|
|
+ &OSversion_Meter_class,
|
|
+ &Kernelversion_Meter_class,
|
|
+ &Armbianversion_Meter_class,
|
|
+ &Eth0_StatsMeter_class,
|
|
+ &Eth1_StatsMeter_class,
|
|
+ &BlockDevice_sda_ioStatsMeter_class,
|
|
+ &BlockDevice_sdb_ioStatsMeter_class,
|
|
+ &BlockDevice_sdc_ioStatsMeter_class,
|
|
+ &BlockDevice_sdd_ioStatsMeter_class,
|
|
+ &BlockDevice_mmcblk0_ioStatsMeter_class,
|
|
+ &BlockDevice_mmcblk1_ioStatsMeter_class,
|
|
+ &BlockDevice_mmcblk2_ioStatsMeter_class,
|
|
+ &BlockDevice_mmcblk3_ioStatsMeter_class,
|
|
NULL
|
|
};
|
|
|
|
+/* cross-platform sleep function */
|
|
+void sleep_ms(int milliseconds) {
|
|
+#ifdef WIN32
|
|
+ Sleep(milliseconds);
|
|
+#elif _POSIX_C_SOURCE >= 199309L
|
|
+ struct timespec ts;
|
|
+ ts.tv_sec = milliseconds / 1000;
|
|
+ ts.tv_nsec = (milliseconds % 1000) * 1000000;
|
|
+ nanosleep(&ts, NULL);
|
|
+#else
|
|
+ usleep(milliseconds * 1000);
|
|
+#endif
|
|
+}
|
|
+
|
|
+int Platform_getGpuTemp(Meter* this) {
|
|
+ int Temp = 0;
|
|
+ char szbuf[256];
|
|
+ Settings* settings = this->pl->settings;
|
|
+ char *handler;
|
|
+ char *cpu_core_policy;
|
|
+
|
|
+ handler = settings->GpuTemp_handler;
|
|
+ if (handler[0] != 0) {
|
|
+ cpu_core_policy = strchr(handler, '%');
|
|
+ if (cpu_core_policy) {
|
|
+ xSnprintf(szbuf, sizeof(szbuf), "%s", "/sys/class/thermal/thermal_zone1/temp");
|
|
+ } else {
|
|
+ xSnprintf(szbuf, sizeof(szbuf), "%s", handler);
|
|
+ }
|
|
+ } else {
|
|
+ xSnprintf(szbuf, sizeof(szbuf), "%s", "/sys/class/thermal/thermal_zone1/temp");
|
|
+ }
|
|
+
|
|
+ FILE* fd = fopen(szbuf, "r");
|
|
+ if (!fd) {
|
|
+ fd = fopen("/sys/devices/virtual/thermal/thermal_zone1/temp", "r");
|
|
+ }
|
|
+ if (fd) {
|
|
+ int n = fscanf(fd, "%d", &Temp);
|
|
+ fclose(fd);
|
|
+ if (n <= 0) return 0;
|
|
+ }
|
|
+ return Temp;
|
|
+}
|
|
+
|
|
+int Platform_getCpuTemp(Meter* this) {
|
|
+ int Temp = 0;
|
|
+ char szbuf[256];
|
|
+ Settings* settings = this->pl->settings;
|
|
+ char *handler;
|
|
+ char *cpu_core_policy;
|
|
+
|
|
+ handler = settings->CpuTemp_handler;
|
|
+ if (handler[0] != 0) {
|
|
+ cpu_core_policy = strchr(handler, '%');
|
|
+ if (cpu_core_policy) {
|
|
+ xSnprintf(szbuf, sizeof(szbuf), "%s", "/sys/class/thermal/thermal_zone0/temp");
|
|
+ } else {
|
|
+ xSnprintf(szbuf, sizeof(szbuf), "%s", handler);
|
|
+ }
|
|
+ } else {
|
|
+ // sleep_ms(30);
|
|
+ // xSnprintf(szbuf, sizeof(szbuf), "/sys/devices/system/cpu/cpufreq/policy%d/cpuinfo_cur_freq", cpu);
|
|
+ xSnprintf(szbuf, sizeof(szbuf), "%s", "/sys/class/thermal/thermal_zone0/temp");
|
|
+ }
|
|
+ FILE *fd = fopen(szbuf, "r");
|
|
+ if (!fd) {
|
|
+ fd = fopen("/sys/devices/virtual/thermal/thermal_zone0/temp", "r");
|
|
+ }
|
|
+ if (fd) {
|
|
+ int n = fscanf(fd, "%d", &Temp);
|
|
+ fclose(fd);
|
|
+ if (n <= 0) return 0;
|
|
+ }
|
|
+ return Temp;
|
|
+}
|
|
+
|
|
+int Platform_getCpuFreq(Meter* this, int cpu) {
|
|
+ int Freq = 0;
|
|
+ FILE* fd;
|
|
+ char szbuf[256];
|
|
+ Settings* settings = this->pl->settings;
|
|
+ char *handler;
|
|
+ char *cpu_core_policy;
|
|
+
|
|
+ handler = settings->CpuFreq_handler;
|
|
+ if (handler[0] != 0) {
|
|
+ cpu_core_policy = strchr(handler, '%');
|
|
+ if (cpu_core_policy) {
|
|
+ xSnprintf(szbuf, sizeof(szbuf), handler, cpu);
|
|
+ } else {
|
|
+ xSnprintf(szbuf, sizeof(szbuf), "%s", handler);
|
|
+ }
|
|
+ } else {
|
|
+ // sleep_ms(30);
|
|
+ // xSnprintf(szbuf, sizeof(szbuf), "/sys/devices/system/cpu/cpufreq/policy%d/cpuinfo_cur_freq", cpu);
|
|
+ xSnprintf(szbuf, sizeof(szbuf), "%s", "/sys/devices/system/cpu/cpufreq/policy0/cpuinfo_cur_freq");
|
|
+ }
|
|
+ fd = fopen(szbuf, "r");
|
|
+ if (fd) {
|
|
+ int n;
|
|
+ n = fscanf(fd, "%d", &Freq);
|
|
+ fclose(fd);
|
|
+ if (n <= 0) return 0;
|
|
+ }
|
|
+ return Freq;
|
|
+}
|
|
+
|
|
+int Platform_getCpuVcore(Meter* this) {
|
|
+ int Vcore = 0;
|
|
+ FILE* fd;
|
|
+ char szbuf[256];
|
|
+ Settings* settings = this->pl->settings;
|
|
+ char *handler;
|
|
+ char *cpu_core_policy;
|
|
+ handler = settings->CpuVCore_l_handler;
|
|
+ if (handler[0] != 0) {
|
|
+ cpu_core_policy = strchr(handler, '%');
|
|
+ if (cpu_core_policy) {
|
|
+ xSnprintf(szbuf, sizeof(szbuf), "%s", "/sys/devices/platform/ff3c0000.i2c/i2c-0/0-001b/regulator/regulator.13/microvolts");
|
|
+ } else {
|
|
+ xSnprintf(szbuf, sizeof(szbuf), "%s", handler);
|
|
+ }
|
|
+ } else {
|
|
+ xSnprintf(szbuf, sizeof(szbuf), "%s", "/sys/devices/platform/ff3c0000.i2c/i2c-0/0-001b/regulator/regulator.13/microvolts");
|
|
+ }
|
|
+
|
|
+ // sleep_ms(10);
|
|
+ fd = fopen(szbuf, "r");
|
|
+ if (fd) {
|
|
+ int n;
|
|
+ n = fscanf(fd, "%d", &Vcore);
|
|
+ fclose(fd);
|
|
+ if (n <= 0) return 0;
|
|
+ }
|
|
+ return Vcore;
|
|
+}
|
|
+
|
|
+int Platform_getCpuVcore_l(Meter* this) {
|
|
+ int Vcore = 0;
|
|
+ FILE* fd;
|
|
+ char szbuf[256];
|
|
+ Settings* settings = this->pl->settings;
|
|
+ char *handler;
|
|
+ char *cpu_core_policy;
|
|
+ handler = settings->CpuVCore_l_handler;
|
|
+ if (handler[0] != 0) {
|
|
+ cpu_core_policy = strchr(handler, '%');
|
|
+ if (cpu_core_policy) {
|
|
+ strcpy(szbuf, "/sys/devices/platform/ff3c0000.i2c/i2c-0/0-001b/regulator/regulator.13/microvolts");
|
|
+ } else {
|
|
+ strcpy(szbuf, handler);
|
|
+ }
|
|
+ } else {
|
|
+ strcpy(szbuf, "/sys/devices/platform/ff3c0000.i2c/i2c-0/0-001b/regulator/regulator.13/microvolts");
|
|
+ }
|
|
+
|
|
+ // sleep_ms(10);
|
|
+ fd = fopen(szbuf, "r");
|
|
+ if (fd) {
|
|
+ int n;
|
|
+ n = fscanf(fd, "%d", &Vcore);
|
|
+ fclose(fd);
|
|
+ if (n <= 0) return 0;
|
|
+ }
|
|
+ return Vcore;
|
|
+}
|
|
+
|
|
+int Platform_getCpuVcore_b(Meter* this) {
|
|
+ int Vcore = 0;
|
|
+ FILE* fd;
|
|
+ char szbuf[256];
|
|
+ Settings* settings = this->pl->settings;
|
|
+ char *handler;
|
|
+ char *cpu_core_policy;
|
|
+ handler = settings->CpuVCore_b_handler;
|
|
+ if (handler[0] != 0) {
|
|
+ cpu_core_policy = strchr(handler, '%');
|
|
+ if (cpu_core_policy) {
|
|
+ strcpy(szbuf, "/sys/devices/platform/ff3c0000.i2c/i2c-0/0-0040/regulator/regulator.10/microvolts");
|
|
+ } else {
|
|
+ strcpy(szbuf, handler);
|
|
+ }
|
|
+ } else {
|
|
+ strcpy(szbuf, "/sys/devices/platform/ff3c0000.i2c/i2c-0/0-0040/regulator/regulator.10/microvolts");
|
|
+ }
|
|
+ // sleep_ms(10);
|
|
+ fd = fopen(szbuf, "r");
|
|
+ if (fd) {
|
|
+ int n;
|
|
+ n = fscanf(fd, "%d", &Vcore);
|
|
+ fclose(fd);
|
|
+ if (n <= 0) return 0;
|
|
+ }
|
|
+ return Vcore;
|
|
+}
|
|
+
|
|
+
|
|
+int Platform_getCpuBigLITTLE() {
|
|
+ return Platform_cpuBigLITTLE;
|
|
+}
|
|
+
|
|
+int Platform_findCpuBigLITTLE(int cpucount, int *cpuBigLITTLE) {
|
|
+ char buf[256];
|
|
+ int n, prev, next;
|
|
+ FILE* fd;
|
|
+
|
|
+ *cpuBigLITTLE = 0;
|
|
+ prev = next = -1;
|
|
+ int cpu = 0;
|
|
+ while (cpu < cpucount) {
|
|
+ xSnprintf(buf, sizeof(buf), "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_max_freq", cpu);
|
|
+ fd = fopen(buf, "r");
|
|
+ if (fd) {
|
|
+ n = fscanf(fd, "%d", &next);
|
|
+ fclose(fd);
|
|
+ if (n <= 0)
|
|
+ break;
|
|
+ if (prev == -1) {
|
|
+ prev = next;
|
|
+ } else {
|
|
+ if (prev != next) {
|
|
+ if (prev < next) {
|
|
+ Platform_cpuBigLITTLE = cpu;
|
|
+ } else {
|
|
+ Platform_cpuBigLITTLE = cpu * -1; /* fix me */
|
|
+ }
|
|
+ *cpuBigLITTLE = Platform_cpuBigLITTLE;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ cpu++;
|
|
+ }
|
|
+ return cpu;
|
|
+}
|
|
+
|
|
int Platform_getUptime() {
|
|
double uptime = 0;
|
|
FILE* fd = fopen(PROCDIR "/uptime", "r");
|
|
@@ -237,3 +570,177 @@ char* Platform_getProcessEnv(pid_t pid) {
|
|
}
|
|
return env;
|
|
}
|
|
+
|
|
+Stats Platform_Eth0_stats;
|
|
+Stats Platform_Eth1_stats;
|
|
+Stats Platform_Wlan0_stats;
|
|
+
|
|
+int Platform_getEth_stats(char *devname, int id, int close_fp) {
|
|
+ char buffer[BLEN];
|
|
+ char *str;
|
|
+ char *str_end;
|
|
+ char *str_start;
|
|
+ unsigned long dump;
|
|
+ int ifound;
|
|
+ unsigned long rx_o, tx_o;
|
|
+ Stats *Platform_Eth_stats;
|
|
+ static FILE *fp_proc_net_dev = NULL;
|
|
+
|
|
+ if (close_fp) {
|
|
+ if (fp_proc_net_dev)
|
|
+ fclose(fp_proc_net_dev);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ if (fp_proc_net_dev == NULL) {
|
|
+ if ((fp_proc_net_dev = fopen("/proc/net/dev", "r")) == NULL) {
|
|
+ return 0;
|
|
+ }
|
|
+ }
|
|
+ if (id == 0) {
|
|
+ Platform_Eth_stats = &Platform_Eth0_stats;
|
|
+ } else {
|
|
+ if (id == 1) {
|
|
+ Platform_Eth_stats = &Platform_Eth1_stats;
|
|
+ } else {
|
|
+ Platform_Eth_stats = &Platform_Wlan0_stats;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* save rx/tx values */
|
|
+ rx_o = Platform_Eth_stats->rx_bytes;
|
|
+ tx_o = Platform_Eth_stats->tx_bytes;
|
|
+
|
|
+ /* do not parse the first two lines as they only contain static garbage */
|
|
+ fseek(fp_proc_net_dev, 0, SEEK_SET);
|
|
+ fgets(buffer, BLEN, fp_proc_net_dev);
|
|
+ fgets(buffer, BLEN, fp_proc_net_dev);
|
|
+
|
|
+ ifound = 0;
|
|
+ while (fgets(buffer, BLEN, fp_proc_net_dev) != NULL) {
|
|
+ str_start = buffer;
|
|
+ str_end = strchr(buffer, ':');
|
|
+ if (str_end != NULL) {
|
|
+ *str_end = 0;
|
|
+ str_start = trim(str_start);
|
|
+ if (strcasecmp(str_start, devname) == 0) {
|
|
+ str = str_end + 1;
|
|
+ str = ltrim(str);
|
|
+ sscanf(str,
|
|
+ "%lg %lu %lu %lu %lu %lu %lu %lu %lg %lu %lu %lu %lu %lu %lu %lu",
|
|
+ &Platform_Eth_stats->rx_bytes, &dump, &dump,
|
|
+ &dump, &dump, &dump, &dump, &dump, &Platform_Eth_stats->tx_bytes,
|
|
+ &dump, &dump, &dump, &dump, &dump, &dump, &dump);
|
|
+ ifound = 1;
|
|
+ continue;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ if (ifound) {
|
|
+ if (rx_o > Platform_Eth_stats->rx_bytes)
|
|
+ Platform_Eth_stats->rx_over++;
|
|
+ if (tx_o > Platform_Eth_stats->tx_bytes)
|
|
+ Platform_Eth_stats->tx_over++;
|
|
+ }
|
|
+ return ifound;
|
|
+}
|
|
+
|
|
+double get_wall_time(void) {
|
|
+ struct timeval time;
|
|
+ if (gettimeofday(&time, NULL))
|
|
+ return 0.;
|
|
+ return (double) time.tv_sec + (double) time.tv_usec * .000001;
|
|
+}
|
|
+
|
|
+ioStats Platform_BlockDevice_sda_stats;
|
|
+ioStats Platform_BlockDevice_sdb_stats;
|
|
+ioStats Platform_BlockDevice_sdc_stats;
|
|
+ioStats Platform_BlockDevice_sdd_stats;
|
|
+ioStats Platform_BlockDevice_mmcblk0_stats;
|
|
+ioStats Platform_BlockDevice_mmcblk1_stats;
|
|
+ioStats Platform_BlockDevice_mmcblk2_stats;
|
|
+ioStats Platform_BlockDevice_mmcblk3_stats;
|
|
+
|
|
+FILE *fp_block_dev_a[8] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
|
|
+
|
|
+int Platform_getIO_stats(char *devname, int idx, int close_fp) {
|
|
+ char block_device[80] = {0};
|
|
+ char buffer[BLEN] = {0};
|
|
+ unsigned long dump;
|
|
+ unsigned long read_o, write_o;
|
|
+ ioStats *Platform_io_stats;
|
|
+ FILE *fp_block_dev = NULL;
|
|
+
|
|
+ if (idx > 7)
|
|
+ idx = 0;
|
|
+
|
|
+ fp_block_dev = fp_block_dev_a[idx];
|
|
+
|
|
+ if (close_fp) {
|
|
+ if (fp_block_dev)
|
|
+ fclose(fp_block_dev);
|
|
+ return 0;
|
|
+ }
|
|
+ if (devname && *devname == 0)
|
|
+ return 0;
|
|
+
|
|
+ if (fp_block_dev == NULL) {
|
|
+ xSnprintf(block_device, sizeof(block_device), "/sys/block/%s/stat", devname);
|
|
+ if ((fp_block_dev = fopen(block_device, "r")) == NULL) {
|
|
+ return 0;
|
|
+ }
|
|
+ fp_block_dev_a[idx] = fp_block_dev;
|
|
+ }
|
|
+
|
|
+ switch(idx) {
|
|
+ case 0:
|
|
+ Platform_io_stats = &Platform_BlockDevice_sda_stats;
|
|
+ break;
|
|
+ case 1:
|
|
+ Platform_io_stats = &Platform_BlockDevice_sdb_stats;
|
|
+ break;
|
|
+ case 2:
|
|
+ Platform_io_stats = &Platform_BlockDevice_sdc_stats;
|
|
+ break;
|
|
+ case 3:
|
|
+ Platform_io_stats = &Platform_BlockDevice_sdd_stats;
|
|
+ break;
|
|
+ case 4:
|
|
+ Platform_io_stats = &Platform_BlockDevice_mmcblk0_stats;
|
|
+ break;
|
|
+ case 5:
|
|
+ Platform_io_stats = &Platform_BlockDevice_mmcblk1_stats;
|
|
+ break;
|
|
+ case 6:
|
|
+ Platform_io_stats = &Platform_BlockDevice_mmcblk2_stats;
|
|
+ break;
|
|
+ case 7:
|
|
+ Platform_io_stats = &Platform_BlockDevice_mmcblk3_stats;
|
|
+ break;
|
|
+ default:
|
|
+ Platform_io_stats = &Platform_BlockDevice_sda_stats;
|
|
+ break;
|
|
+ }
|
|
+ /* save read/write values */
|
|
+ read_o = Platform_io_stats->read_sectors;
|
|
+ write_o = Platform_io_stats->write_sectors;
|
|
+ fseek(fp_block_dev, 0, SEEK_SET);
|
|
+ if (fgets(buffer, BLEN - 1, fp_block_dev) != NULL) {
|
|
+ sscanf(buffer,
|
|
+ "%lu %lu %lg %lu %lu %lu %lg %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu",
|
|
+ &dump, &dump, &Platform_io_stats->read_sectors, &dump, &dump,
|
|
+ &dump, &Platform_io_stats->write_sectors, &dump, &dump, &dump, &dump,
|
|
+ &dump, &dump, &dump, &dump, &dump, &dump);
|
|
+ } else {
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ while (fgets(buffer, BLEN - 1, fp_block_dev) != NULL)
|
|
+ ;
|
|
+
|
|
+ if (read_o > Platform_io_stats->read_sectors)
|
|
+ Platform_io_stats->read_over++;
|
|
+ if (write_o > Platform_io_stats->write_sectors)
|
|
+ Platform_io_stats->write_over++;
|
|
+ return 1;
|
|
+}
|
|
diff --git a/linux/Platform.h b/linux/Platform.h
|
|
index b0456e5..54dbf80 100644
|
|
--- a/linux/Platform.h
|
|
+++ b/linux/Platform.h
|
|
@@ -5,15 +5,65 @@
|
|
/*
|
|
htop - linux/Platform.h
|
|
(C) 2014 Hisham H. Muhammad
|
|
+(C) 2020 Alexander Finger
|
|
Released under the GNU GPL, see the COPYING file
|
|
in the source distribution for its full text.
|
|
*/
|
|
|
|
+#ifdef WIN32
|
|
+#elif _POSIX_C_SOURCE >= 199309L
|
|
+#else
|
|
+#endif
|
|
+
|
|
#include "Action.h"
|
|
#include "MainPanel.h"
|
|
#include "BatteryMeter.h"
|
|
#include "LinuxProcess.h"
|
|
#include "SignalsPanel.h"
|
|
+#ifdef WIN32
|
|
+#include <windows.h>
|
|
+#elif _POSIX_C_SOURCE >= 199309L
|
|
+#include <time.h>
|
|
+#else
|
|
+#include <unistd.h>
|
|
+#endif
|
|
+#include <string.h>
|
|
+
|
|
+
|
|
+typedef enum vendor_id_ {
|
|
+ VENDOR_INTEL,
|
|
+ VENDOR_AMD,
|
|
+ VENDOR_CYRIX,
|
|
+ VENDOR_VIA,
|
|
+ VENDOR_TRANSMETA,
|
|
+ VENDOR_UMC,
|
|
+ VENDOR_NEXGEN,
|
|
+ VENDOR_RISE,
|
|
+ VENDOR_SIS,
|
|
+ VENDOR_NSC,
|
|
+ VENDOR_VORTEX,
|
|
+ VENDOR_RDC,
|
|
+ VENDOR_UNKNOWN
|
|
+} vendor_id;
|
|
+
|
|
+typedef struct Stats_ {
|
|
+ int rx_over;
|
|
+ int tx_over;
|
|
+ double rx_bytes;
|
|
+ double tx_bytes;
|
|
+ double rx_bytes_comp;
|
|
+ double tx_bytes_comp;
|
|
+} Stats;
|
|
+
|
|
+typedef struct ioStats_ {
|
|
+ int read_over;
|
|
+ int write_over;
|
|
+ double read_sectors;
|
|
+ double write_sectors;
|
|
+ double read_sectors_comp;
|
|
+ double write_sectors_comp;
|
|
+} ioStats;
|
|
+
|
|
|
|
#ifndef CLAMP
|
|
#define CLAMP(x,low,high) (((x)>(high))?(high):(((x)<(low))?(low):(x)))
|
|
@@ -21,6 +71,7 @@ in the source distribution for its full text.
|
|
|
|
extern ProcessField Platform_defaultFields[];
|
|
|
|
+extern int Platform_cpuBigLITTLE;
|
|
extern int Platform_numberOfFields;
|
|
|
|
extern const SignalItem Platform_signals[];
|
|
@@ -31,6 +82,25 @@ void Platform_setBindings(Htop_Action* keys);
|
|
|
|
extern MeterClass* Platform_meterTypes[];
|
|
|
|
+/* cross-platform sleep function */
|
|
+void sleep_ms(int milliseconds);
|
|
+
|
|
+int Platform_getGpuTemp(Meter* this);
|
|
+
|
|
+int Platform_getCpuTemp(Meter* this);
|
|
+
|
|
+int Platform_getCpuFreq(Meter* this, int cpu);
|
|
+
|
|
+int Platform_getCpuVcore(Meter* this);
|
|
+
|
|
+int Platform_getCpuVcore_l(Meter* this);
|
|
+
|
|
+int Platform_getCpuVcore_b(Meter* this);
|
|
+
|
|
+int Platform_getCpuBigLITTLE();
|
|
+
|
|
+int Platform_findCpuBigLITTLE(int cpucount, int *cpuBigLITTLE);
|
|
+
|
|
int Platform_getUptime();
|
|
|
|
void Platform_getLoadAverage(double* one, double* five, double* fifteen);
|
|
@@ -45,4 +115,25 @@ void Platform_setSwapValues(Meter* this);
|
|
|
|
char* Platform_getProcessEnv(pid_t pid);
|
|
|
|
+Stats Platform_Eth0_stats;
|
|
+Stats Platform_Eth1_stats;
|
|
+Stats Platform_Wlan0_stats;
|
|
+
|
|
+int Platform_getEth_stats(char *devname, int id, int close_fp);
|
|
+
|
|
+double get_wall_time(void);
|
|
+
|
|
+ioStats Platform_BlockDevice_sda_stats;
|
|
+ioStats Platform_BlockDevice_sdb_stats;
|
|
+ioStats Platform_BlockDevice_sdc_stats;
|
|
+ioStats Platform_BlockDevice_sdd_stats;
|
|
+ioStats Platform_BlockDevice_mmcblk0_stats;
|
|
+ioStats Platform_BlockDevice_mmcblk1_stats;
|
|
+ioStats Platform_BlockDevice_mmcblk2_stats;
|
|
+ioStats Platform_BlockDevice_mmcblk3_stats;
|
|
+
|
|
+extern FILE *fp_block_dev_a[8];
|
|
+
|
|
+int Platform_getIO_stats(char *devname, int idx, int close_fp);
|
|
+
|
|
#endif
|