From 25b777967449315dd0d13d17f5a627b1bfe2056d Mon Sep 17 00:00:00 2001 From: Shun Terabayashi Date: Sun, 18 Oct 2020 23:00:36 +0900 Subject: Initial implement for command line interface --- makefile | 29 +++++++++++- src/gui.c | 1 + src/zenmonitor-cli.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/zenmonitor-lib.c | 94 ++++++++++++++++++++++++++++++++++++++ src/zenmonitor.c | 93 ++----------------------------------- 5 files changed, 253 insertions(+), 91 deletions(-) create mode 100644 src/zenmonitor-cli.c create mode 100644 src/zenmonitor-lib.c diff --git a/makefile b/makefile index dabe5d2..93b7bf5 100755 --- a/makefile +++ b/makefile @@ -1,9 +1,28 @@ +CC := cc + ifeq ($(PREFIX),) PREFIX := /usr/local endif +BUILD_FILES_COMMON := \ + src/ss/*.c \ + src/sysfs.c \ + src/zenmonitor-lib.c + +BUILD_FILES_GUI := \ + $(BUILD_FILES_COMMON) \ + src/gui.c \ + src/zenmonitor.c + +BUILD_FILES_CLI := \ + $(BUILD_FILES_COMMON) \ + src/zenmonitor-cli.c + build: - cc -Isrc/include `pkg-config --cflags gtk+-3.0` src/*.c src/ss/*.c -o zenmonitor `pkg-config --libs gtk+-3.0` -lm -no-pie -Wall + $(CC) -Isrc/include `pkg-config --cflags gtk+-3.0` $(BUILD_FILES_GUI) -o zenmonitor `pkg-config --libs gtk+-3.0` -lm -no-pie -Wall $(CFLAGS) + +build-cli: + $(CC) -Isrc/include `pkg-config --cflags glib-2.0` $(BUILD_FILES_CLI) -o zenmonitor-cli `pkg-config --libs glib-2.0` -lm -no-pie -Wall $(CFLAGS) install: mkdir -p $(DESTDIR)$(PREFIX)/bin @@ -14,6 +33,10 @@ install: data/zenmonitor.desktop.in > \ $(DESTDIR)$(PREFIX)/share/applications/zenmonitor.desktop +install-cli: + mkdir -p $(DESTDIR)$(PREFIX)/bin + install -m 755 zenmonitor-cli $(DESTDIR)$(PREFIX)/bin + install-polkit: sed -e "s|@APP_EXEC@|${DESTDIR}${PREFIX}/bin/zenmonitor|" \ data/zenmonitor-root.desktop.in > \ @@ -29,5 +52,9 @@ uninstall: rm -f $(DESTDIR)$(PREFIX)/share/applications/zenmonitor-root.desktop rm -f $(DESTDIR)/usr/share/polkit-1/actions/org.pkexec.zenmonitor.policy +all: build build-cli + clean: rm -f zenmonitor + rm -f zenmonitor-cli + rm -f *.o diff --git a/src/gui.c b/src/gui.c index 11ef4f8..e382f96 100644 --- a/src/gui.c +++ b/src/gui.c @@ -1,5 +1,6 @@ #include #include +#include #include "gui.h" #include "zenmonitor.h" diff --git a/src/zenmonitor-cli.c b/src/zenmonitor-cli.c new file mode 100644 index 0000000..744b92a --- /dev/null +++ b/src/zenmonitor-cli.c @@ -0,0 +1,127 @@ +#include +#include +#include +#include "msr.h" +#include "os.h" +#include "zenpower.h" +#include "zenmonitor.h" + +gboolean display_coreid = 0; +gdouble delay = 0.5; +gchar *format = ""; +gchar *columns[2048]; + +static GOptionEntry options[] = +{ + { "format", 'f', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, &format, "Output format (csv, json)", "FORMAT" }, + { "delay", 'd', G_OPTION_FLAG_NONE, G_OPTION_ARG_DOUBLE, &delay, "Interval of refreshing informations", "SECONDS" }, + { "coreid", 'c', 0, G_OPTION_ARG_NONE, &display_coreid, "Display core_id instead of core index", NULL }, + { NULL } +}; + +static SensorSource sensor_sources[] = { + { + "zenpower", + zenpower_init, zenpower_get_sensors, zenpower_update, zenpower_clear_minmax, + FALSE, NULL + }, + { + "msr", + msr_init, msr_get_sensors, msr_update, msr_clear_minmax, + FALSE, NULL + }, + { + "os", + os_init, os_get_sensors, os_update, os_clear_minmax, + FALSE, NULL + }, + { + NULL + } +}; + +void init_sensors() { + GSList *sensor; + SensorSource *source; + const SensorInit *data; + guint i = 0; + + for(source = sensor_sources; source->drv; source++) + { + if(source->func_init()) + { + source->sensors = source->func_get_sensors(); + if(source->sensors != NULL) + { + source->enabled = TRUE; + sensor = source->sensors; + while(sensor) + { + data = (SensorInit*)sensor->data; + columns[i++] = data->label; + sensor = sensor->next; + } + } + } + } + columns[i] = NULL; +} + +void update_data() +{ + SensorSource *source; + GSList *node; + const SensorInit *sensorData; + + for(source = sensor_sources; source->drv; source++) + { + if(source->enabled) + { + source->func_update(); + if(source->sensors) + { + node = source->sensors; + + while(node) + { + sensorData = (SensorInit*)node->data; + printf("%s\t%f\n", sensorData->label, *sensorData->value); + node = node->next; + } + } + } + } +} + +void start_watching() +{ + guint i = 0; + while(columns[i]) + { + printf("%s\n", columns[i++]); + } + + while(1) + { + update_data(); + usleep(delay * 1000 * 1000); + } +} + +int main(int argc, char *argv[]) +{ + GError *error = NULL; + GOptionContext *context; + + context = g_option_context_new("- Zenmonitor options"); + g_option_context_add_main_entries(context, options, NULL); + if(!g_option_context_parse(context, &argc, &argv, &error)) { + g_print ("option parsing failed: %s\n", error->message); + exit (1); + } + + init_sensors(); + start_watching(); + + return EXIT_SUCCESS; +} diff --git a/src/zenmonitor-lib.c b/src/zenmonitor-lib.c new file mode 100644 index 0000000..dded8f3 --- /dev/null +++ b/src/zenmonitor-lib.c @@ -0,0 +1,94 @@ +#include + +#include "zenpower.h" +#include "msr.h" +#include "os.h" +#include "zenmonitor.h" + +#define AMD_STRING "AuthenticAMD" +#define ZEN_FAMILY 0x17 + +// AMD PPR = https://www.amd.com/system/files/TechDocs/54945_PPR_Family_17h_Models_00h-0Fh.pdf + +gboolean check_zen() { + guint32 eax = 0, ebx = 0, ecx = 0, edx = 0, ext_family; + char vendor[13]; + + __get_cpuid(0, &eax, &ebx, &ecx, &edx); + + memcpy(vendor, &ebx, 4); + memcpy(vendor+4, &edx, 4); + memcpy(vendor+8, &ecx, 4); + vendor[12] = 0; + + if (strcmp(vendor, AMD_STRING) != 0){ + return FALSE; + } + + __get_cpuid(1, &eax, &ebx, &ecx, &edx); + + ext_family = ((eax >> 8) & 0xF) + ((eax >> 20) & 0xFF); + if (ext_family != ZEN_FAMILY){ + return FALSE; + } + + return TRUE; +} + +gchar *cpu_model() { + guint32 eax = 0, ebx = 0, ecx = 0, edx = 0; + char model[48]; + + // AMD PPR: page 65-68 - CPUID_Fn80000002_EAX-CPUID_Fn80000004_EDX + __get_cpuid(0x80000002, &eax, &ebx, &ecx, &edx); + memcpy(model, &eax, 4); + memcpy(model+4, &ebx, 4); + memcpy(model+8, &ecx, 4); + memcpy(model+12, &edx, 4); + + __get_cpuid(0x80000003, &eax, &ebx, &ecx, &edx); + memcpy(model+16, &eax, 4); + memcpy(model+20, &ebx, 4); + memcpy(model+24, &ecx, 4); + memcpy(model+28, &edx, 4); + + __get_cpuid(0x80000004, &eax, &ebx, &ecx, &edx); + memcpy(model+32, &eax, 4); + memcpy(model+36, &ebx, 4); + memcpy(model+40, &ecx, 4); + memcpy(model+44, &edx, 4); + + model[48] = 0; + return g_strdup(g_strchomp(model)); +} + +guint get_core_count() { + guint eax = 0, ebx = 0, ecx = 0, edx = 0; + guint logical_cpus, threads_per_code; + + // AMD PPR: page 57 - CPUID_Fn00000001_EBX + __get_cpuid(1, &eax, &ebx, &ecx, &edx); + logical_cpus = (ebx >> 16) & 0xFF; + + // AMD PPR: page 82 - CPUID_Fn8000001E_EBX + __get_cpuid(0x8000001E, &eax, &ebx, &ecx, &edx); + threads_per_code = ((ebx >> 8) & 0xF) + 1; + + if (threads_per_code == 0) + return logical_cpus; + + return logical_cpus / threads_per_code; +} + +SensorInit *sensor_init_new() { + return g_new0(SensorInit, 1); +} + +void sensor_init_free(SensorInit *s) { + if (s) { + g_free(s->label); + g_free(s->hint); + g_free(s); + } +} + diff --git a/src/zenmonitor.c b/src/zenmonitor.c index d02c510..cb35ce2 100644 --- a/src/zenmonitor.c +++ b/src/zenmonitor.c @@ -1,87 +1,14 @@ #include -#include #include #include -#include "zenmonitor.h" + #include "zenpower.h" #include "msr.h" #include "os.h" #include "gui.h" +#include "zenmonitor.h" -#define AMD_STRING "AuthenticAMD" -#define ZEN_FAMILY 0x17 - -// AMD PPR = https://www.amd.com/system/files/TechDocs/54945_PPR_Family_17h_Models_00h-0Fh.pdf - -gboolean check_zen() { - guint32 eax = 0, ebx = 0, ecx = 0, edx = 0, ext_family; - char vendor[13]; - - __get_cpuid(0, &eax, &ebx, &ecx, &edx); - - memcpy(vendor, &ebx, 4); - memcpy(vendor+4, &edx, 4); - memcpy(vendor+8, &ecx, 4); - vendor[12] = 0; - - if (strcmp(vendor, AMD_STRING) != 0){ - return FALSE; - } - - __get_cpuid(1, &eax, &ebx, &ecx, &edx); - - ext_family = ((eax >> 8) & 0xF) + ((eax >> 20) & 0xFF); - if (ext_family != ZEN_FAMILY){ - return FALSE; - } - - return TRUE; -} - -gchar *cpu_model() { - guint32 eax = 0, ebx = 0, ecx = 0, edx = 0; - char model[48]; - - // AMD PPR: page 65-68 - CPUID_Fn80000002_EAX-CPUID_Fn80000004_EDX - __get_cpuid(0x80000002, &eax, &ebx, &ecx, &edx); - memcpy(model, &eax, 4); - memcpy(model+4, &ebx, 4); - memcpy(model+8, &ecx, 4); - memcpy(model+12, &edx, 4); - - __get_cpuid(0x80000003, &eax, &ebx, &ecx, &edx); - memcpy(model+16, &eax, 4); - memcpy(model+20, &ebx, 4); - memcpy(model+24, &ecx, 4); - memcpy(model+28, &edx, 4); - - __get_cpuid(0x80000004, &eax, &ebx, &ecx, &edx); - memcpy(model+32, &eax, 4); - memcpy(model+36, &ebx, 4); - memcpy(model+40, &ecx, 4); - memcpy(model+44, &edx, 4); - - model[48] = 0; - return g_strdup(g_strchomp(model)); -} - -guint get_core_count() { - guint eax = 0, ebx = 0, ecx = 0, edx = 0; - guint logical_cpus, threads_per_code; - - // AMD PPR: page 57 - CPUID_Fn00000001_EBX - __get_cpuid(1, &eax, &ebx, &ecx, &edx); - logical_cpus = (ebx >> 16) & 0xFF; - - // AMD PPR: page 82 - CPUID_Fn8000001E_EBX - __get_cpuid(0x8000001E, &eax, &ebx, &ecx, &edx); - threads_per_code = ((ebx >> 8) & 0xF) + 1; - - if (threads_per_code == 0) - return logical_cpus; - - return logical_cpus / threads_per_code; -} +gboolean display_coreid = 0; static SensorSource sensor_sources[] = { { @@ -104,20 +31,6 @@ static SensorSource sensor_sources[] = { } }; -SensorInit *sensor_init_new() { - return g_new0(SensorInit, 1); -} - -void sensor_init_free(SensorInit *s) { - if (s) { - g_free(s->label); - g_free(s->hint); - g_free(s); - } -} - -gboolean display_coreid = 0; - static GOptionEntry options[] = { { "coreid", 'c', 0, G_OPTION_ARG_NONE, &display_coreid, "Display core_id instead of core index", NULL }, -- cgit v1.2.3-70-g09d2