diff options
author | Ondrej Čerman | 2019-10-12 21:12:55 +0200 |
---|---|---|
committer | Ondrej Čerman | 2019-10-12 21:12:55 +0200 |
commit | 38aaa630df9a88d6387ebc2b95f50da7bad6b03d (patch) | |
tree | 63ea3a45e2fd5ef56987c9018a5caa9cc9aca15a /src | |
parent | f3ca3475d0500734421b738f944edbf55802abca (diff) | |
parent | e409f26106b4a60a64a122e1cb5884360c2cca34 (diff) |
Merge branch 'nove'
Diffstat (limited to 'src')
-rw-r--r-- | src/gui.c | 4 | ||||
-rw-r--r-- | src/include/os.h | 4 | ||||
-rw-r--r-- | src/include/sysfs.h | 3 | ||||
-rw-r--r-- | src/include/zenmonitor.h | 1 | ||||
-rw-r--r-- | src/ss/msr.c | 44 | ||||
-rw-r--r-- | src/ss/os.c | 91 | ||||
-rw-r--r-- | src/ss/zenpower.c | 3 | ||||
-rw-r--r-- | src/sysfs.c | 47 | ||||
-rw-r--r-- | src/zenmonitor.c | 24 |
9 files changed, 185 insertions, 36 deletions
@@ -23,7 +23,6 @@ static void init_sensors() { GtkListStore *store; SensorSource *source; const SensorInit *data; - gboolean added; guint i = 0; store = GTK_LIST_STORE(model); @@ -69,7 +68,6 @@ static void set_list_column_value(float num, const gchar *printf_format, GtkTree static gboolean update_data (gpointer data) { GtkTreeIter iter; - guint number; GSList *node; SensorSource *source; const SensorInit *sensorData; @@ -106,7 +104,6 @@ static gboolean update_data (gpointer data) { static void add_columns (GtkTreeView *treeview) { GtkCellRenderer *renderer; GtkTreeViewColumn *column; - GtkTreeModel *model = gtk_tree_view_get_model (treeview); // NAME renderer = gtk_cell_renderer_text_new (); @@ -160,7 +157,6 @@ static void about_btn_clicked(GtkButton *button, gpointer user_data) { static void clear_btn_clicked(GtkButton *button, gpointer user_data) { SensorSource *source; - const SensorInit *sensorData; for (source = sensor_sources; source->drv; source++) { if (!source->enabled) diff --git a/src/include/os.h b/src/include/os.h new file mode 100644 index 0000000..d6af111 --- /dev/null +++ b/src/include/os.h @@ -0,0 +1,4 @@ +gboolean os_init(); +void os_update(); +void os_clear_minmax(); +GSList* os_get_sensors(); diff --git a/src/include/sysfs.h b/src/include/sysfs.h new file mode 100644 index 0000000..a079c7d --- /dev/null +++ b/src/include/sysfs.h @@ -0,0 +1,3 @@ +#define SYSFS_DIR_CPUS "/sys/devices/system/cpu" + +gshort* get_cpu_dev_ids(); diff --git a/src/include/zenmonitor.h b/src/include/zenmonitor.h index c0b1f73..21cc9fc 100644 --- a/src/include/zenmonitor.h +++ b/src/include/zenmonitor.h @@ -24,3 +24,4 @@ SensorInit* sensor_init_new(void); void sensor_init_free(SensorInit *s); gboolean check_zen(); gchar *cpu_model(); +guint get_core_count(); diff --git a/src/ss/msr.c b/src/ss/msr.c index 2da5d7a..8b26472 100644 --- a/src/ss/msr.c +++ b/src/ss/msr.c @@ -8,6 +8,7 @@ #include "string.h" #include "zenmonitor.h" #include "msr.h" +#include "sysfs.h" #define MSR_PWR_PRINTF_FORMAT " %8.3f W" #define MESUREMENT_TIME 0.1 @@ -15,16 +16,15 @@ // AMD PPR = https://www.amd.com/system/files/TechDocs/54945_PPR_Family_17h_Models_00h-0Fh.pdf // AMD OSRR = https://developer.amd.com/wp-content/resources/56255_3_03.PDF -guint cores = 0; -guint threads_per_code = 0; -gdouble energy_unit = 0; +static guint cores = 0; +static gdouble energy_unit = 0; -gint *msr_files = NULL; +static gint *msr_files = NULL; -gulong package_eng_b = 0; -gulong package_eng_a = 0; -gulong *core_eng_b = NULL; -gulong *core_eng_a = NULL; +static gulong package_eng_b = 0; +static gulong package_eng_a = 0; +static gulong *core_eng_b = NULL; +static gulong *core_eng_a = NULL; gfloat package_power; gfloat package_power_min; @@ -33,27 +33,10 @@ gfloat *core_power; gfloat *core_power_min; gfloat *core_power_max; -static guint get_core_count() { - guint eax = 0, ebx = 0, ecx = 0, edx = 0; - guint logical_cpus; - // 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; -} - -static gint open_msr(gshort core) { +static gint open_msr(gshort devid) { gchar msr_path[20]; - sprintf(msr_path, "/dev/cpu/%d/msr", core * threads_per_code); + sprintf(msr_path, "/dev/cpu/%d/msr", devid); return open(msr_path, O_RDONLY); } @@ -92,8 +75,8 @@ gulong get_core_energy(gint core) { } gboolean msr_init() { + gshort *cpu_dev_ids = NULL; int i; - size_t sz; if (!check_zen()) return FALSE; @@ -102,10 +85,12 @@ gboolean msr_init() { if (cores == 0) return FALSE; + cpu_dev_ids = get_cpu_dev_ids(); msr_files = malloc(cores * sizeof (gint)); for (i = 0; i < cores; i++) { - msr_files[i] = open_msr(i); + msr_files[i] = open_msr(cpu_dev_ids[i]); } + g_free(cpu_dev_ids); energy_unit = get_energy_unit(); if (energy_unit == 0) @@ -127,7 +112,6 @@ gboolean msr_init() { } void msr_update() { - GSList *list = NULL; gint i; package_eng_b = get_package_energy(); diff --git a/src/ss/os.c b/src/ss/os.c new file mode 100644 index 0000000..d232a1f --- /dev/null +++ b/src/ss/os.c @@ -0,0 +1,91 @@ +#include <glib.h> +#include "zenmonitor.h" +#include "sysfs.h" +#include "os.h" + +#define OS_FREQ_PRINTF_FORMAT " %8.3f GHz" + +static gchar **frq_files = NULL; +static guint cores; + +gfloat *core_freq; +gfloat *core_freq_min; +gfloat *core_freq_max; + +static gdouble get_frequency(guint coreid) { + gchar *data; + if (!g_file_get_contents(frq_files[coreid], &data, NULL, NULL)) + return 0.0; + + return atoi(data) / 1000000.0; +} + +gboolean os_init() { + gshort *cpu_dev_ids = NULL; + gint i; + + if (!check_zen()) + return FALSE; + + cores = get_core_count(); + if (cores == 0) + return FALSE; + + cpu_dev_ids = get_cpu_dev_ids(); + frq_files = malloc(cores * sizeof (gchar*)); + for (i = 0; i < cores; i++) { + frq_files[i] = g_strdup_printf( + "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_cur_freq", + cpu_dev_ids[i]); + } + g_free(cpu_dev_ids); + + core_freq = malloc(cores * sizeof (gfloat)); + core_freq_min = malloc(cores * sizeof (gfloat)); + core_freq_max = malloc(cores * sizeof (gfloat)); + + os_update(); + memcpy(core_freq_min, core_freq, cores * sizeof (gfloat)); + memcpy(core_freq_max, core_freq, cores * sizeof (gfloat)); + + return TRUE; +} + +void os_update() { + gint i; + + for (i = 0; i < cores; i++) { + core_freq[i] = get_frequency(i); + if (core_freq[i] < core_freq_min[i]) + core_freq_min[i] = core_freq[i]; + if (core_freq[i] > core_freq_max[i]) + core_freq_max[i] = core_freq[i]; + } +} + +void os_clear_minmax() { + gint i; + + for (i = 0; i < cores; i++) { + core_freq_min[i] = core_freq[i]; + core_freq_max[i] = core_freq[i]; + } +} + +GSList* os_get_sensors() { + GSList *list = NULL; + SensorInit *data; + gint i; + + for (i = 0; i < cores; i++) { + data = sensor_init_new(); + data->label = g_strdup_printf("Core %d Frequency", i); + data->value = &(core_freq[i]); + data->min = &(core_freq_min[i]); + data->max = &(core_freq_max[i]); + data->printf_format = OS_FREQ_PRINTF_FORMAT; + list = g_slist_append(list, data); + } + + return list; +} diff --git a/src/ss/zenpower.c b/src/ss/zenpower.c index 07a6b54..6af86dc 100644 --- a/src/ss/zenpower.c +++ b/src/ss/zenpower.c @@ -74,8 +74,7 @@ gboolean zenpower_init() { const gchar *entry; gchar *name = NULL; HwmonSensorType *type; - HwmonSensor *sensor; - + hwmon = g_dir_open("/sys/class/hwmon", 0, NULL); if (!hwmon) return FALSE; diff --git a/src/sysfs.c b/src/sysfs.c new file mode 100644 index 0000000..ea59c1b --- /dev/null +++ b/src/sysfs.c @@ -0,0 +1,47 @@ +#include <glib.h> +#include <stdio.h> +#include "sysfs.h" +#include "zenmonitor.h" + +gshort* get_cpu_dev_ids(){ + gshort *cpu_dev_ids = NULL; + gshort coreid, cpuid; + GDir *dir; + const gchar *entry; + gchar *filename, *buffer; + guint cores, i; + + cores = get_core_count(); + cpu_dev_ids = malloc(cores * sizeof (gshort)); + memset(cpu_dev_ids, -1, cores * sizeof (gshort)); + + dir = g_dir_open(SYSFS_DIR_CPUS, 0, NULL); + if (dir) { + while ((entry = g_dir_read_name(dir))) { + if (sscanf(entry, "cpu%hd", &cpuid) != 1) { + continue; + } + + filename = g_build_filename(SYSFS_DIR_CPUS, entry, "topology", "core_id", NULL); + if (g_file_get_contents(filename, &buffer, NULL, NULL)) { + coreid = (gshort) atoi(buffer); + + if (coreid < cores && cpu_dev_ids[coreid] == -1) { + cpu_dev_ids[coreid] = cpuid; + } + } + + g_free(filename); + g_free(buffer); + } + } + + for (i = 0; i < cores; i++) { + if (cpu_dev_ids[i] < 0) { + cpu_dev_ids[i] = i; + } + } + + return cpu_dev_ids; +} + diff --git a/src/zenmonitor.c b/src/zenmonitor.c index ee2be39..30e5370 100644 --- a/src/zenmonitor.c +++ b/src/zenmonitor.c @@ -3,6 +3,7 @@ #include "zenmonitor.h" #include "zenpower.h" #include "msr.h" +#include "os.h" #include "gui.h" #include "string.h" @@ -63,6 +64,24 @@ gchar *cpu_model() { 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; +} + static SensorSource sensor_sources[] = { { "zenpower", @@ -75,6 +94,11 @@ static SensorSource sensor_sources[] = { FALSE, NULL }, { + "os", + os_init, os_get_sensors, os_update, os_clear_minmax, + FALSE, NULL + }, + { NULL } }; |