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