From 80686673103879c1eb6b197c45493b521c7702a9 Mon Sep 17 00:00:00 2001 From: FlorealRISSO <floreal.risso@univ-tlse3.fr> Date: Tue, 21 Mar 2023 10:41:57 +0100 Subject: [PATCH 1/6] add memory sensor --- configure.sh | 6 +++- src/memory.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/memory.h | 43 +++++++++++++++++++++++ 3 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 src/memory.c create mode 100644 src/memory.h diff --git a/configure.sh b/configure.sh index 740e87a..7e10ec3 100755 --- a/configure.sh +++ b/configure.sh @@ -55,7 +55,7 @@ ls_sensors() { try find src -type f -name '*.h' | sed 's,src/\(.*\)\.h,\1,' | grep -xEv "($hdr_blacklist)" | - grep -xE "($hdr_whitelist)" + grep -xE "($hdr_whitelist)" } # gen_sensors_h(sensor, nb_sensors) @@ -118,6 +118,10 @@ detect_caps() { [ -d /sys/class/infiniband ] && hdr_whitelist="${hdr_whitelist}|infiniband" [ -r /proc/stat ] && hdr_whitelist="${hdr_whitelist}|load" + if [ "$(uname -r | cut -d "." -f 1)" -gt "2" ]; then + hdr_whitelist="${hdr_whitelist}|memory" + fi + if [ -r /proc/net/route ]; then dev=$(awk 'NR == 2 { print $1 }' /proc/net/route) [ -e "/sys/class/net/$dev" ] && hdr_whitelist="${hdr_whitelist}|network" diff --git a/src/memory.c b/src/memory.c new file mode 100644 index 0000000..3356a82 --- /dev/null +++ b/src/memory.c @@ -0,0 +1,97 @@ +/******************************************************* + Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr> + + This file is part of Mojitos. + + Mojitos is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Mojitos is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with MojitO/S. If not, see <https://www.gnu.org/licenses/>. + + *******************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <sys/sysinfo.h> +#include <string.h> + +#include "util.h" + +typedef enum { + TOTALRAM = 0, + FREERAM, + SHAREDRAM, + BUFFERRAM, + TOTALSWAP, + FREESWAP, + PROCS, + TOTALHIGH, + FREEHIGH, + MEM_UNIT, + + MEMORY_COUNT, +} MemoryKind; + +static const char *memory_labels[MEMORY_COUNT] = { + "totalram", "freeram", "sharedram", "bufferram", + "totalswap", "freeswap", + "procs", + "totalhigh", "freehigh", "mem_unit", +}; + +unsigned int init_memory(char *none1, void **none2) +{ + UNUSED(none1); + UNUSED(none2); + struct sysinfo info; + if (sysinfo(&info) < 0) { + fprintf(stderr, "Failed to get the memory information"); + return 0; + } + return MEMORY_COUNT; +} + +unsigned int get_memory(uint64_t *results, void *none) +{ + UNUSED(none); + struct sysinfo info; + if (sysinfo(&info) < 0) { + fprintf(stderr, "Failed to get the memory information"); + exit(99); + } + + // Can't use memcpy, the size isn't always the same + results[TOTALRAM] = info.totalram; + results[FREERAM] = info.freeram; + results[SHAREDRAM] = info.sharedram; + results[BUFFERRAM] = info.bufferram; + results[TOTALSWAP] = info.totalswap; + results[FREESWAP] = info.freeswap; + results[PROCS] = info.procs; + results[TOTALHIGH] = info.totalhigh; + results[FREEHIGH] = info.freehigh; + results[MEM_UNIT] = info.mem_unit; + + return MEMORY_COUNT; +} + +void label_memory(char **labels, void *none) +{ + UNUSED(none); + memcpy(labels, memory_labels, sizeof(char *) * MEMORY_COUNT); +} + +void clean_memory(void *none) +{ + UNUSED(none); + return; +} + diff --git a/src/memory.h b/src/memory.h new file mode 100644 index 0000000..6e275c6 --- /dev/null +++ b/src/memory.h @@ -0,0 +1,43 @@ +/******************************************************* + Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr> + + This file is part of Mojitos. + + Mojitos is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Mojitos is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with MojitO/S. If not, see <https://www.gnu.org/licenses/>. + + *******************************************************/ + +unsigned int init_memory(char *, void **); +unsigned int get_memory(uint64_t *results, void *); +void clean_memory(void *); +void label_memory(char **labels, void *); + + +Sensor memory = { + .init = init_memory, + .get = get_memory, + .clean = clean_memory, + .label = label_memory, + .nb_opt = 1, +}; + +Optparse memory_opt[1] = { + { + .longname = "memory", + .shortname = 'm', + .argtype = OPTPARSE_NONE, + .usage_arg = NULL, + .usage_msg = "Retrieves information about the memory via the syscall 'sysinfo(2)'.", + }, +}; -- GitLab From 482202be2c2811baf0f5f4fff1c5056f9b2b3e04 Mon Sep 17 00:00:00 2001 From: FlorealRISSO <floreal.risso@univ-tlse3.fr> Date: Tue, 21 Mar 2023 11:21:58 +0100 Subject: [PATCH 2/6] non breaking change, ptr -> const ptr --- tests/small_test.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/small_test.h b/tests/small_test.h index 66c4de9..8301ae7 100644 --- a/tests/small_test.h +++ b/tests/small_test.h @@ -253,8 +253,8 @@ #define DEFERRED_ERROR(nb_error) \ INDENTED_PRINT("|_Deferred Error : %d\n",nb_error); -typedef int (Comparator) (void *, void *); -typedef char *(Formatter) (char[FMT_BUFFER_SIZE], void *); +typedef int (Comparator) (const void *, const void *); +typedef char *(Formatter) (char[FMT_BUFFER_SIZE], const void *); typedef struct { Comparator *compare; @@ -263,7 +263,7 @@ typedef struct { // ---------------------------TEST FUNCTION -int test(char *file, int line, unsigned int __indentation_level, void *result, void *expected, const TestInterface *interface) +int test(char *file, int line, unsigned int __indentation_level, const void *result, const void *expected, const TestInterface *interface) { __indentation_level += 1; static char buffer_result[FMT_BUFFER_SIZE]; @@ -281,7 +281,7 @@ int test(char *file, int line, unsigned int __indentation_level, void *result, v // ------------------------------INTERFACES // -- str_interface -int str_compare(void *ptr1, void *ptr2) +int str_compare(const void *ptr1, const void *ptr2) { char *str1 = (char *) ptr1; char *str2 = (char *) ptr2; @@ -295,7 +295,7 @@ int str_compare(void *ptr1, void *ptr2) } } -char *str_format(char buffer[FMT_BUFFER_SIZE], void *ptr) +char *str_format(char buffer[FMT_BUFFER_SIZE], const void *ptr) { UNUSED(buffer); static char *str_null = "NULL"; @@ -310,14 +310,14 @@ static const TestInterface str_interface = { // -- bool_interface -int bool_compare(void *ptr1, void *ptr2) +int bool_compare(const void *ptr1, const void *ptr2) { bool *bool1 = (bool *) ptr1; bool *bool2 = (bool *) ptr2; return *bool1 == *bool2; } -char *bool_format(char buffer[FMT_BUFFER_SIZE], void *ptr) +char *bool_format(char buffer[FMT_BUFFER_SIZE], const void *ptr) { UNUSED(buffer); bool *_bool = (bool *) ptr; @@ -331,14 +331,14 @@ static const TestInterface bool_interface = { // -- int_interface -int int_compare(void *ptr1, void *ptr2) +int int_compare(const void *ptr1, const void *ptr2) { int *int1 = (int *) ptr1; int *int2 = (int *) ptr2; return *int1 == *int2; } -char *int_format(char buffer[FMT_BUFFER_SIZE], void *ptr) +char *int_format(char buffer[FMT_BUFFER_SIZE], const void *ptr) { int *_int = (int *) ptr; snprintf(buffer, FMT_BUFFER_SIZE, "%d", *_int); @@ -352,12 +352,12 @@ static const TestInterface int_interface = { // -- ptr_interface -int ptr_compare(void *ptr1, void *ptr2) +int ptr_compare(const void *ptr1, const void *ptr2) { return ptr1 == ptr2; } -char *ptr_format(char buffer[FMT_BUFFER_SIZE], void *ptr) +char *ptr_format(char buffer[FMT_BUFFER_SIZE], const void *ptr) { snprintf(buffer, FMT_BUFFER_SIZE, "%p", ptr); return buffer; @@ -370,14 +370,14 @@ static const TestInterface ptr_interface = { // -- u64_interface -int u64_compare(void *ptr1, void *ptr2) +int u64_compare(const void *ptr1, const void *ptr2) { uint64_t *v1 = (uint64_t *) ptr1; uint64_t *v2 = (uint64_t *) ptr2; return *v1 == *v2; } -char *u64_format(char buffer[FMT_BUFFER_SIZE], void *ptr) +char *u64_format(char buffer[FMT_BUFFER_SIZE], const void *ptr) { uint64_t *v = (uint64_t *) ptr; snprintf(buffer, FMT_BUFFER_SIZE, "%"PRIu64"", *v); -- GitLab From 32ff911bf1e940750eadf0e5080f374aa45921ef Mon Sep 17 00:00:00 2001 From: FlorealRISSO <floreal.risso@univ-tlse3.fr> Date: Tue, 21 Mar 2023 11:23:21 +0100 Subject: [PATCH 3/6] add tests --- tests/main.c | 2 ++ tests/memory.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 tests/memory.c diff --git a/tests/main.c b/tests/main.c index 3246f04..e90e8dd 100644 --- a/tests/main.c +++ b/tests/main.c @@ -21,9 +21,11 @@ #include "util.c" #include "amd_rapl.c" #include "info_reader.c" +#include "memory.c" TMAIN({ CALL_TFUNCTION(test_util); CALL_TFUNCTION(test_amd_rapl); CALL_TFUNCTION(test_info_reader); + CALL_TFUNCTION(test_memory); }) diff --git a/tests/memory.c b/tests/memory.c new file mode 100644 index 0000000..78efd28 --- /dev/null +++ b/tests/memory.c @@ -0,0 +1,78 @@ +/******************************************************* + Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr> + + This file is part of Mojitos. + + Mojitos is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Mojitos is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with MojitO/S. If not, see <https://www.gnu.org/licenses/>. + +*******************************************************/ + +#include "small_test.h" +#include "../src/memory.c" + +// In order to verify the integrity. +TFUNCTION(test_labels, { + // If it fails update the tests + int tested_count = 10; + int expected_count = MEMORY_COUNT; + TEST_INT(&tested_count, &expected_count); + + const char *result = NULL; + char *expected = NULL; + + expected = "totalram"; + result = memory_labels[TOTALRAM]; + TEST_STR(result, expected); + + expected = "freeram"; + result = memory_labels[FREERAM]; + TEST_STR(result, expected); + + expected = "sharedram"; + result = memory_labels[SHAREDRAM]; + TEST_STR(result, expected); + + expected = "bufferram"; + result = memory_labels[BUFFERRAM]; + TEST_STR(result, expected); + + expected = "totalswap"; + result = memory_labels[TOTALSWAP]; + TEST_STR(result, expected); + + expected = "freeswap"; + result = memory_labels[FREESWAP]; + TEST_STR(result, expected); + + expected = "procs"; + result = memory_labels[PROCS]; + TEST_STR(result, expected); + + expected = "totalhigh"; + result = memory_labels[TOTALHIGH]; + TEST_STR(result, expected); + + expected = "freehigh"; + result = memory_labels[FREEHIGH]; + TEST_STR(result, expected); + + expected = "mem_unit"; + result = memory_labels[MEM_UNIT]; + TEST_STR(result, expected); +}) + +TFILE_ENTRY_POINT(test_memory, { + CALL_TFUNCTION(test_labels); +}) + -- GitLab From 4ffdcfaf2192b0929cd7d0902bcb5a2cc34510fe Mon Sep 17 00:00:00 2001 From: FlorealRISSO <floreal.risso@univ-tlse3.fr> Date: Tue, 21 Mar 2023 11:39:45 +0100 Subject: [PATCH 4/6] add tests --- tests/util.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/tests/util.c b/tests/util.c index 69941bf..231ab47 100644 --- a/tests/util.c +++ b/tests/util.c @@ -77,6 +77,50 @@ TFUNCTION(test_modulo_substraction, { TEST_UINT64_T(&result, &expected); }) +TFUNCTION(test_max, { + int expected = 0; + int result = 0; + + expected = 10; + result = MAX(expected, 9); + TEST_INT(&result, &expected); + + expected = -15; + result = MAX(expected, -16); + TEST_INT(&result, &expected); + + expected = 0; + result = MAX(expected, -1); + TEST_INT(&result, &expected); + + expected = 1; + result = MAX(expected, 0); + TEST_INT(&result, &expected); +}) + +TFUNCTION(test_min, { + int expected = 0; + int result = 0; + + expected = 9; + result = MIN(expected, 10); + TEST_INT(&result, &expected); + + expected = -16; + result = MIN(expected, -15); + TEST_INT(&result, &expected); + + expected = -1; + result = MIN(expected, 0); + TEST_INT(&result, &expected); + + expected = 0; + result = MIN(expected, 1); + TEST_INT(&result, &expected); +}) + TFILE_ENTRY_POINT(test_util, { CALL_TFUNCTION(test_modulo_substraction); + CALL_TFUNCTION(test_max); + CALL_TFUNCTION(test_min); }) -- GitLab From bdb2908f2cecc768711d92eede0d41e5d856c404 Mon Sep 17 00:00:00 2001 From: FlorealRISSO <floreal.risso@univ-tlse3.fr> Date: Tue, 21 Mar 2023 12:46:42 +0100 Subject: [PATCH 5/6] add: exit information --- src/amd_rapl.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/amd_rapl.c b/src/amd_rapl.c index f08c5a7..adc4461 100644 --- a/src/amd_rapl.c +++ b/src/amd_rapl.c @@ -201,17 +201,36 @@ void debug_print_amd_rapl(AmdRapl *rapl) unsigned int get_nb_cpu() { char filename[BUFFER_SIZE]; + int cpy_errno; unsigned int n_cpu = 0; for (;; n_cpu++) { snprintf(filename, BUFFER_SIZE, base_str, n_cpu); int fd = open(filename, O_RDONLY); + cpy_errno = errno; if (fd < 0) { break; } close(fd); } + + if (n_cpu == 0) { + perror("open()"); + fprintf(stderr, "on %s\n", filename); + switch (cpy_errno) { + case ENOENT: + fprintf(stderr, "Amd rapl works with msr module, try to run 'sudo modprobe msr', then retry.\n"); + exit(99); + case EACCES: + fprintf(stderr, "Amd rapl must be executed with the administrator privilege, try with 'sudo'.\n"); + exit(98); + default: + fprintf(stderr, "Unexpected error"); + exit(97); + } + } + // n_cpu > 0 return n_cpu; } @@ -295,11 +314,6 @@ unsigned int init_amd_rapl(char *none, void **ptr) UNUSED(none); unsigned int max_cpus = get_nb_cpu(); - if (max_cpus == 0) { - fprintf(stderr, base_str, 0); - perror(":open()"); - exit(127); - } CpuSensor *cpu_information = (CpuSensor *) calloc(max_cpus, sizeof(CpuSensor)); if (parse_cpuinfo(cpu_information, max_cpus)) { -- GitLab From f3368b52b60d7b46a39411a0e8f69e378a285f0a Mon Sep 17 00:00:00 2001 From: FlorealRISSO <floreal.risso@univ-tlse3.fr> Date: Tue, 21 Mar 2023 12:52:02 +0100 Subject: [PATCH 6/6] error handling --- src/amd_rapl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/amd_rapl.c b/src/amd_rapl.c index adc4461..9eaac45 100644 --- a/src/amd_rapl.c +++ b/src/amd_rapl.c @@ -217,7 +217,7 @@ unsigned int get_nb_cpu() if (n_cpu == 0) { perror("open()"); - fprintf(stderr, "on %s\n", filename); + fprintf(stderr, "on the file: '%s'\n", filename); switch (cpy_errno) { case ENOENT: fprintf(stderr, "Amd rapl works with msr module, try to run 'sudo modprobe msr', then retry.\n"); @@ -226,7 +226,7 @@ unsigned int get_nb_cpu() fprintf(stderr, "Amd rapl must be executed with the administrator privilege, try with 'sudo'.\n"); exit(98); default: - fprintf(stderr, "Unexpected error"); + fprintf(stderr, "Unexpected error\n"); exit(97); } } -- GitLab