From eab8f8bf862f796b589374803af9d501d7a7ef08 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 6 Feb 2023 14:09:22 +0100
Subject: [PATCH 01/69] Add dev name to labels

plus some other changes, in particular:
- index --> strchr
- sprintf --> snprintf
---
 src/network.c | 34 ++++++++++++++++++++--------------
 1 file changed, 20 insertions(+), 14 deletions(-)

diff --git a/src/network.c b/src/network.c
index 543a053..aee5659 100644
--- a/src/network.c
+++ b/src/network.c
@@ -28,10 +28,17 @@
 #define NB_SENSOR 4
 
 static char *route = "/proc/net/route";
+char *_labels_network[NB_SENSOR] = {
+    "%s:rxp",
+    "%s:rxb",
+    "%s:txp",
+    "%s:txb",
+};
 struct network_t {
     uint64_t values[NB_SENSOR];
     uint64_t tmp_values[NB_SENSOR];
     int sources[NB_SENSOR];
+    char labels[NB_SENSOR][128];
 };
 
 unsigned int _get_network(uint64_t *results, int *sources)
@@ -54,8 +61,6 @@ unsigned int _get_network(uint64_t *results, int *sources)
     return NB_SENSOR;
 }
 
-
-
 unsigned int init_network(char *dev, void **ptr)
 {
     if (dev == NULL) {
@@ -79,25 +84,27 @@ unsigned int init_network(char *dev, void **ptr)
             exit(1);
         }
 
-        char *start_of_dev = index(buffer, '\n') + 1;
-        char *end_of_dev = index(start_of_dev, '\t');
+        char *start_of_dev = strchr(buffer, '\n') + 1;
+        char *end_of_dev = strchr(start_of_dev, '\t');
         *end_of_dev = '\0';
         dev = start_of_dev;
         close(fd);
     }
 
-    char *filenames[] = {"/sys/class/net/%s/statistics/rx_packets",
-                         "/sys/class/net/%s/statistics/rx_bytes",
-                         "/sys/class/net/%s/statistics/tx_packets",
-                         "/sys/class/net/%s/statistics/tx_bytes"
-                        };
+    char *filenames[] = {
+        "/sys/class/net/%s/statistics/rx_packets",
+        "/sys/class/net/%s/statistics/rx_bytes",
+        "/sys/class/net/%s/statistics/tx_packets",
+        "/sys/class/net/%s/statistics/tx_bytes",
+    };
 
     struct network_t *state = malloc(sizeof(struct network_t));
 
     char buffer2[256];
     for (int i = 0; i < NB_SENSOR; i++) {
-        sprintf(buffer2, filenames[i], dev);
+        snprintf(buffer2, sizeof(buffer2), filenames[i], dev);
         state->sources[i] = open(buffer2, O_RDONLY);
+        snprintf(state->labels[i], sizeof(state->labels[i]), _labels_network[i], dev);
     }
 
     *ptr = (void *) state;
@@ -134,12 +141,11 @@ void clean_network(void *ptr)
     free(state);
 }
 
-char *_labels_network[NB_SENSOR] = {"rxp", "rxb", "txp", "txb"};
-void label_network(char **labels, void *none)
+void label_network(char **labels, void *ptr)
 {
-    UNUSED(none);
+    struct network_t *state = (struct network_t *) ptr;
 
     for (int i = 0; i < NB_SENSOR; i++) {
-        labels[i] = _labels_network[i];
+        labels[i] = state->labels[i];
     }
 }
-- 
GitLab


From 72ae8099f4559689c3d8a30957a5933b695101a6 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 31 Jan 2023 12:44:18 +0000
Subject: [PATCH 02/69] fix unit size

---
 src/amd_rapl.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 09ea7c0..31944b1 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -49,7 +49,7 @@ struct cpu_sensor_t {
     char *name;
 
     int fd;
-    uint64_t energy_units;
+    unsigned int energy_units;
     uint64_t core_energy;
     uint64_t pkg_energy;
 };
@@ -107,7 +107,7 @@ uint64_t read_msr(int fd, uint64_t msr)
     return data;
 }
 
-uint64_t read_unit(int fd)
+unsigned int read_unit(int fd)
 {
     uint64_t unit = read_msr(fd, msr_rapl_power_unit);
     return ((unit & amd_energy_unit_mask) >> 8);
@@ -127,14 +127,12 @@ uint64_t read_raw_pkg_energy(int fd)
 
 // ---------------------------------ENERGY
 
-uint64_t raw_to_microjoule(uint64_t raw, uint64_t unit)
+uint64_t raw_to_microjoule(uint64_t raw, unsigned int unit)
 {
     static const double to_microjoule = 1000000.0;
-    double d_raw = (double) raw;
-    double d_unit = (double) unit;
     // raw * (1 / (unit^2)) -> Joule
     // Joule * 1000000 -> uJoule
-    return  ((d_raw * to_microjoule) / (d_unit * d_unit));
+    return (uint64_t) (((double) raw * to_microjoule) / (double)(1U << unit));
 }
 uint64_t raw_to_joule(uint64_t raw, uint64_t unit)
 {
@@ -149,7 +147,7 @@ uint64_t raw_to_joule(uint64_t raw, uint64_t unit)
 void debug_print_sensor(cpu_sensor_t *sensor)
 {
     //CASSERT(sizeof(cpu_sensor_t) == 56, amd_rapl_c);
-    printf("cpu_id : %ld, package_id : %ld, name : %s, fd: %d,  energy_units : %ld, core_energy: %ld, pkg_energy: %ld\n",
+    printf("cpu_id : %ld, package_id : %ld, name : %s, fd: %d,  energy_units : %d, core_energy: %ld, pkg_energy: %ld\n",
            sensor->cpu_id,
            sensor->package_id,
            sensor->name,
-- 
GitLab


From ae734b928303fa5690dd1c51b83bc1f1e25751b1 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 31 Jan 2023 13:03:20 +0000
Subject: [PATCH 03/69] clear code

---
 src/amd_rapl.c   | 52 ------------------------------------------------
 tests/amd_rapl.c |  6 +++---
 2 files changed, 3 insertions(+), 55 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 31944b1..0d2ed29 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -165,20 +165,6 @@ void debug_print_amd_rapl(_amd_rapl_t *rapl)
     }
 }
 
-// typedef struct {
-//     size_t cpu_id;
-//     uint64_t *results;
-//     size_t capacity;
-// } CpuLogger;
-//
-// CpuLogger init_logger(size_t cpu_id, size_t capacity)
-// {
-//
-// }
-//
-// void log_value();
-
-
 #endif
 
 // ---------------------------AMD_RAPL_UTIL
@@ -321,41 +307,3 @@ void clean_amd_rapl(void *ptr)
     free(rapl->sensors);
     free(rapl);
 }
-
-// -----------------------------ENTRY_POINT
-
-#ifdef __TESTING_AMD__
-#ifdef DEBUG
-int main()
-{
-    s_round_to_uint64(1.0);
-    static const unsigned int time = 10;
-    _amd_rapl_t *rapl = NULL;
-    unsigned int nb_cpu = init_amd_rapl(NULL, (void **) &rapl);
-    uint64_t results[nb_cpu];
-    char *labels[nb_cpu];
-
-    label_amd_rapl(labels, (void *) rapl);
-
-    for (unsigned int i = 0; i < rapl->nb; ++i) {
-        printf("%s ", labels[i]);
-    }
-    printf("\n");
-
-    // -- Run
-
-    for (unsigned int i = 0; i < time; ++i) {
-        sleep(1);
-        get_amd_rapl(results, (void *)rapl);
-
-        for (unsigned int j = 0; j < rapl->nb; ++j) {
-            printf("%ld ", results[j]);
-        }
-        printf("\n");
-    }
-
-    clean_amd_rapl(rapl);
-    return 0;
-}
-#endif
-#endif
diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index 3f97f32..ddf76ae 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -11,7 +11,7 @@ TFUNCTION(test_raw_to_microjoule, {
     // -- Setup
     raw = 100;
     unit = 1000;
-    expected = 100;
+    expected = 390625;
     // -- Run
     result = raw_to_microjoule(raw, unit);
     // -- Verification
@@ -21,7 +21,7 @@ TFUNCTION(test_raw_to_microjoule, {
     // -- Setup
     raw = 200;
     unit = 1;
-    expected = 200000000;
+    expected = 100000000;
     // -- Run
     result = raw_to_microjoule(raw, unit);
     // -- Verification
@@ -41,7 +41,7 @@ TFUNCTION(test_raw_to_microjoule, {
     // -- Setup
     raw = 1000;
     unit = 3;
-    expected = 111111111;
+    expected = 125000000;
     // -- Run
     result = raw_to_microjoule(raw, unit);
     // -- Verification
-- 
GitLab


From 5d63d39b713348c4596905f0cebaba9a127dfd3b Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 31 Jan 2023 14:46:27 +0000
Subject: [PATCH 04/69] format

---
 tests/info_reader.c | 67 +++++++++++++++++++++++----------------------
 1 file changed, 34 insertions(+), 33 deletions(-)

diff --git a/tests/info_reader.c b/tests/info_reader.c
index 761d86a..9504631 100644
--- a/tests/info_reader.c
+++ b/tests/info_reader.c
@@ -84,28 +84,29 @@ TFUNCTION(test_start_with, {
     TEST_BOOLEAN(&result, &_false);
 })
 
-#define DUMB_KEYFINDER(key_finder, key, delimiter)  \
-	do { 											\
-		key_finder = (KeyFinder) {					\
-			key,									\
-			delimiter,								\
-			0,										\
-			0										\
-		}; 											\
-	} while (0);
-
-#define DUMB_PARSER(parser, keys, nb_keys)  \
-	do {									\
-		parser = (Parser) {					\
-			0,			   					\
-			0,			   					\
-			0,			   					\
-			0,  							\
-			keys,			   				\
-			nb_keys, 		   				\
-			0								\
-		};							   		\
-	} while (0);
+#define NONE 0
+#define DUMMY_KEYFINDER(__key_finder, __key, __delimiter) \
+  do {                                                    \
+    __key_finder = (KeyFinder) {                          \
+      .key = __key,                                       \
+      .delimiter = __delimiter,                           \
+      .copy = NONE,                                       \
+      .set = NONE                                         \
+    };                                                    \
+  } while (0);
+
+#define DUMMY_PARSER(__parser, __keys, __nb_keys) \
+  do {                                            \
+    __parser = (Parser) {                         \
+      .storage = NONE,                            \
+      .nb_stored = NONE,                          \
+      .capacity = NONE,                           \
+      .storage_struct_size = NONE,                \
+      .keys = __keys,                             \
+      .nb_keys = __nb_keys,                       \
+      .file = NONE                                \
+    };                                            \
+  } while (0);
 
 
 TFUNCTION(test_match, {
@@ -121,8 +122,8 @@ TFUNCTION(test_match, {
 
     // Test 1:
     // -- Setup
-    DUMB_KEYFINDER(keys[0], "key", ": ");
-    DUMB_PARSER(parser, keys, 1);
+    DUMMY_KEYFINDER(keys[0], "key", ": ");
+    DUMMY_PARSER(parser, keys, 1);
     strcpy(line, "key: value");
     found_key_finder = NULL;
     raw_value = NULL;
@@ -135,8 +136,8 @@ TFUNCTION(test_match, {
 
     // Test 2:
     // -- Setup
-    DUMB_KEYFINDER(keys[0], "key", ": ");
-    DUMB_PARSER(parser, keys, 1)
+    DUMMY_KEYFINDER(keys[0], "key", ": ");
+    DUMMY_PARSER(parser, keys, 1)
     strcpy(line, "not a key: value");
     found_key_finder = NULL;
     raw_value = NULL;
@@ -149,8 +150,8 @@ TFUNCTION(test_match, {
 
     // Test 3:
     // -- Setup
-    DUMB_KEYFINDER(keys[0],"key", ": ");
-    DUMB_PARSER(parser, keys, 1);
+    DUMMY_KEYFINDER(keys[0],"key", ": ");
+    DUMMY_PARSER(parser, keys, 1);
     strcpy(line, "key:value");
     found_key_finder = NULL;
     raw_value = NULL;
@@ -163,9 +164,9 @@ TFUNCTION(test_match, {
 
     // Test 4:
     // -- Setup
-    DUMB_KEYFINDER(keys[0], "key", ": ");
-    DUMB_KEYFINDER(keys[1], "second_key", ": ");
-    DUMB_PARSER(parser, keys, 2);
+    DUMMY_KEYFINDER(keys[0], "key", ": ");
+    DUMMY_KEYFINDER(keys[1], "second_key", ": ");
+    DUMMY_PARSER(parser, keys, 2);
     strcpy(line, "second_key: value");
     found_key_finder = NULL;
     raw_value = NULL;
@@ -178,8 +179,8 @@ TFUNCTION(test_match, {
 
     // Test 5:
     // -- Setup
-    DUMB_KEYFINDER(keys[0], "key", ": ");
-    DUMB_PARSER(parser, keys, 1);
+    DUMMY_KEYFINDER(keys[0], "key", ": ");
+    DUMMY_PARSER(parser, keys, 1);
     strcpy(line, "");
     found_key_finder = NULL;
     raw_value = NULL;
-- 
GitLab


From e052fe6b71eb27213afbf631d6c25407e449aa24 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sat, 4 Feb 2023 15:18:03 +0000
Subject: [PATCH 05/69] modification of test api

---
 tests/amd_rapl.c   |  81 +++++++++++++++++++------------
 tests/main.c       |   2 +-
 tests/small_test.h | 115 ++++++++++++++++++++++++---------------------
 3 files changed, 115 insertions(+), 83 deletions(-)

diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index ddf76ae..262c1f8 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -85,25 +85,25 @@ TFUNCTION(test_get_name, {
 })
 
 #define NONE 0
-#define DUMB_SENSOR(sensor, cpu_id, name)	\
-	do {									\
-		sensor = (cpu_sensor_t) {			\
-			cpu_id,							\
-			NONE,							\
-			name,							\
-			NONE,							\
-			NONE,							\
-			NONE, 							\
-			NONE							\
-		}; 									\
+#define DUMMY_SENSOR(__sensor, __cpu_id, __name) \
+do {                                             \
+  __sensor = (cpu_sensor_t) {                    \
+    .cpu_id = __cpu_id,                          \
+    .package_id = NONE,                          \
+    .core_id = NONE,                             \
+    .name = __name,                              \
+    .fd = NONE,                                  \
+    .energy_units = NONE,                        \
+    .core_energy = NONE,                         \
+  };                                             \
 	} while(0);
 
-#define DUMB_RAPL(rapl, sensors, nb)		\
-	do {									\
-		rapl = (_amd_rapl_t) {				\
-			sensors,						\
-			nb								\
-		};									\
+#define DUMMY_RAPL(__rapl, __sensors, __sensors_count) \
+	do {                                                 \
+		__rapl = (_amd_rapl_t) {                           \
+			.sensors = __sensors,                            \
+			.sensor_count = __sensors_count                 \
+		};                                                 \
 	} while(0);
 
 TFUNCTION(test_label_amd_rapl, {
@@ -116,8 +116,8 @@ TFUNCTION(test_label_amd_rapl, {
     // Test 1:
     // -- Setup
     nb = 1;
-    DUMB_SENSOR(sensors[0], 0, "core0");
-    DUMB_RAPL(rapl, sensors, nb);
+    DUMMY_SENSOR(sensors[0], 0, "core0");
+    DUMMY_RAPL(rapl, sensors, nb);
     strcpy(expecteds[0], "core0");
     // -- Run
     label_amd_rapl(results, (void *) &rapl);
@@ -127,11 +127,11 @@ TFUNCTION(test_label_amd_rapl, {
     // Test 2:
     // -- Setup
     nb = 4;
-    DUMB_SENSOR(sensors[0], 0, "core0");
-    DUMB_SENSOR(sensors[1], 1, "core1");
-    DUMB_SENSOR(sensors[2], 2, "core2");
-    DUMB_SENSOR(sensors[3], 3, "core3");
-    DUMB_RAPL(rapl, sensors, nb);
+    DUMMY_SENSOR(sensors[0], 0, "core0");
+    DUMMY_SENSOR(sensors[1], 1, "core1");
+    DUMMY_SENSOR(sensors[2], 2, "core2");
+    DUMMY_SENSOR(sensors[3], 3, "core3");
+    DUMMY_RAPL(rapl, sensors, nb);
     strcpy(expecteds[0], "core0");
     strcpy(expecteds[1], "core1");
     strcpy(expecteds[2], "core2");
@@ -144,11 +144,11 @@ TFUNCTION(test_label_amd_rapl, {
     // Test 3:
     // -- Setup
     nb = 4;
-    DUMB_SENSOR(sensors[0], 0, "core0");
-    DUMB_SENSOR(sensors[1], 3, "core3");
-    DUMB_SENSOR(sensors[2], 1, "core1");
-    DUMB_SENSOR(sensors[3], 2, "core2");
-    DUMB_RAPL(rapl, sensors, nb);
+    DUMMY_SENSOR(sensors[0], 0, "core0");
+    DUMMY_SENSOR(sensors[1], 3, "core3");
+    DUMMY_SENSOR(sensors[2], 1, "core1");
+    DUMMY_SENSOR(sensors[3], 2, "core2");
+    DUMMY_RAPL(rapl, sensors, nb);
     strcpy(expecteds[0], "core0");
     strcpy(expecteds[1], "core3");
     strcpy(expecteds[2], "core1");
@@ -159,10 +159,33 @@ TFUNCTION(test_label_amd_rapl, {
     TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
 })
 
+TFUNCTION(test_init_cpu_sensor, {
+    static const unsigned int max_cpus = 10;
+    unsigned char cpus_map[max_cpus * max_cpus];
+    cpu_sensor_t sensor_t1;
+    unsigned int result;
+    unsigned int expected;
+
+    // Test 1:
+    // -- Setup
+    memset(cpus_map, 0, max_cpus *max_cpus * sizeof(unsigned char));
+    result = 0;
+    expected = 1;
+    memset(&sensor_t1, 0, sizeof(cpu_sensor_t));
+    sensor_t1.cpu_id = 1;
+    sensor_t1.core_id = 0;
+    sensor_t1.package_id = 0;
+    // -- Run
+    result = init_cpu_sensor(&sensor_t1, 0, cpus_map, max_cpus);
+    // -- Verification
+    TEST_UINT64_T(&result, &expected);
+})
+
 TFILE_ENTRY_POINT(test_amd_rapl, {
     CALL_TFUNCTION(test_raw_to_microjoule);
     CALL_TFUNCTION(test_get_name);
     CALL_TFUNCTION(test_label_amd_rapl);
+    // CALL_TFUNCTION(test_init_cpu_sensor);
 })
 
 #ifdef __TESTING__AMD__
diff --git a/tests/main.c b/tests/main.c
index a3a43cb..e48b56a 100644
--- a/tests/main.c
+++ b/tests/main.c
@@ -2,7 +2,7 @@
 #include "amd_rapl.c"
 #include "info_reader.c"
 
-TFILE_ENTRY_POINT(main, {
+TMAIN({
     CALL_TFUNCTION(test_util);
     CALL_TFUNCTION(test_amd_rapl);
     CALL_TFUNCTION(test_info_reader);
diff --git a/tests/small_test.h b/tests/small_test.h
index 0e39868..357479a 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -9,10 +9,23 @@
 
 // ---------------------------API_INTERFACE
 
+
+
+#define TMAIN(code)                                              \
+  int main()                                                     \
+{                                                                \
+  unsigned int __indentation_level = 0;                          \
+  INDENTED_PRINT("%s:%s\n", __FILE__, __func__);                 \
+  unsigned int __error_counter__ = 0;                            \
+  do code while (0);                                             \
+  DEFERRED_FILE_ERROR(__error_counter__);                        \
+  return __error_counter__;                                      \
+}
+
 /**
  * @brief Define the entry point of a test file.
  * This macro is used to define the entry point of a test file.
- * It defines a function with the specified file_name that contains the test code specified in code.
+ * It defines a function with the specified __filename that contains the test code specified in code.
  *
  * When the function is called, it initializes the test file using the INIT_TEST_FILE macro,
  * declares an integer variable __error_counter__ to keep track of any errors encountered during the tests,
@@ -20,17 +33,17 @@
  * The function returns the value of __error_counter__,
  * which indicates the number of errors encountered during the tests.
  *
- * @param file_name The name of the function that serves as the entry point for the test file.
- * @param code The test code to be executed in the function.
+ * @param __filename The name of the function that serves as the entry point for the test file.
+ * @param __code The test code to be executed in the function.
  */
-#define TFILE_ENTRY_POINT(file_name, code) \
-  int file_name() \
-{ \
-  INIT_TEST_FILE();\
-  int __error_counter__ = 0;\
-  do code while(0);\
-  DEFERRED_FILE_ERROR(__error_counter__); \
-  return __error_counter__;\
+#define TFILE_ENTRY_POINT(__filename, __code)       \
+  int __filename (unsigned int __indentation_level) \
+{                                                   \
+  INIT_TEST_FILE();                                 \
+  int __error_counter__ = 0;                        \
+  do __code while(0);                               \
+  DEFERRED_FILE_ERROR(__error_counter__);           \
+  return __error_counter__;                         \
 }
 
 /**
@@ -43,15 +56,15 @@
  * executes the test code in a do-while loop, and then checks for any deferred errors using the DEFERRED_ERROR macro.
  * The function returns the value of __error_counter__, which indicates the number of errors encountered during the tests.
  *
- * @param function_name The name of the test function.
- * @param code The test code to be executed in the function.
+ * @param __function_name The name of the test function.
+ * @param __code The test code to be executed in the function.
  */
-#define TFUNCTION(function_name, code) \
-  int function_name() \
+#define TFUNCTION(__function_name, __code) \
+  int __function_name(unsigned int __indentation_level) \
 { \
   INIT_TEST_FUNCTION(); \
   int __error_counter__ = 0; \
-  do code while(0); \
+  do __code while(0); \
   DEFERRED_FUNCTION_ERROR(__error_counter__); \
   return __error_counter__; \
 }
@@ -65,7 +78,7 @@
  * @param function_name The name of the test function to be called.
  */
 #define CALL_TFUNCTION(function_name) \
-  __error_counter__ += function_name()
+  __error_counter__ += function_name(__indentation_level + 1)
 
 
 /**
@@ -82,7 +95,7 @@
  * @endcode
  */
 #define TEST_STR(result, expected) \
-	__error_counter__ += test_str(__FILE__, __LINE__, result, expected)
+    __error_counter__ += test_str(__FILE__, __LINE__, __indentation_level, result, expected)
 
 /**
  * @def TEST_BOOLEAN(result, expected)
@@ -98,7 +111,7 @@
  * @endcode
  */
 #define TEST_BOOLEAN(result, expected) \
-	__error_counter__ += test_boolean(__FILE__, __LINE__, result, expected)
+	__error_counter__ += test_boolean(__FILE__, __LINE__, __indentation_level, result, expected)
 
 /**
  * @def TEST_PTR(result, expected)
@@ -116,7 +129,7 @@
  * @endcode
  */
 #define TEST_PTR(result, expected) \
-	__error_counter__ += test_ptr(__FILE__, __LINE__, result, expected)
+	__error_counter__ += test_ptr(__FILE__, __LINE__, __indentation_level, result, expected)
 
 
 /**
@@ -133,7 +146,7 @@
  * @endcode
  */
 #define TEST_UINT64_T(result, expected) \
-	__error_counter__ += test_uint64_t(__FILE__, __LINE__, result, expected)
+	__error_counter__ += test_uint64_t(__FILE__, __LINE__, __indentation_level, result, expected)
 
 /**
  * @def TEST_T_ARRAY(function, nb_error, size, results, expecteds)
@@ -161,6 +174,15 @@
 
 // --------------------------------API_CODE
 
+
+#define INDENTED_PRINT(__fmt, ...)                          \
+  do {                                                      \
+    for(unsigned int i = 0; i < __indentation_level; i++) { \
+      printf("|    ");                                       \
+    }                                                       \
+    printf(__fmt, ##__VA_ARGS__);                           \
+  } while(0)
+
 /**
  * @def INIT_TEST_FILE()
  * @brief Initialize the test file
@@ -173,8 +195,8 @@
  * INIT_TEST_FILE();
  * @endcode
  */
-#define INIT_TEST_FILE() \
-	init_test_file(__FILE__, __func__)
+#define INIT_TEST_FILE()     \
+  INDENTED_PRINT("%s:%s\n", __FILE__, __func__)
 
 /**
  * @def INIT_TEST_FUNCTION()
@@ -188,13 +210,14 @@
  * @endcode
  */
 #define INIT_TEST_FUNCTION() \
-	init_test_function(__func__)
+  INDENTED_PRINT("%s()\n", __func__);
 
 #define DEFERRED_FILE_ERROR(nb_error) \
-	  printf("========== Deferred Error : %d\n", nb_error);
+    INDENTED_PRINT("|_Deferred Error : %u\n",nb_error);
+//INDENTED_PRINT("Deferred Error in %s: %d\n",__FILE__, nb_error);
 
 #define DEFERRED_FUNCTION_ERROR(nb_error) \
-	  printf("       | Deferred Error : %d\n", nb_error);
+    INDENTED_PRINT("|_Deferred Error : %d\n",nb_error);
 
 #define FMT_NULL(string) \
 	string = string ? string : "NULL"
@@ -252,65 +275,51 @@ char *uint64_t_format(char *buffer, uint64_t *value)
     return buffer;
 }
 
-void init_test_file(const char *file, const char *function)
-{
-    printf("========== TEST in %s -> %s()\n", file, function);
-}
-
-void init_test_function(const char *function)
-{
-    printf("|=> %s()\n", function);
-}
-
-int test(char *file, int line, void *result, void *expected, Comparator *compare, Formatter *format)
+int test(char *file, int line, unsigned int __indentation_level, void *result, void *expected, Comparator *compare, Formatter *format)
 {
+    __indentation_level++;
     static char buffer_result[1000];
     static char buffer_expected[1000];
     int is_equal = compare(result, expected);
-    char c_result = is_equal ? 'V' : 'X';
-    printf("[%c]    | %s:%d: ", c_result, file, line);
 
+    char *fmt_result = format(buffer_result, expected);
+    char *fmt_expected = format(buffer_expected, result);
     if  (!is_equal) {
-        printf("failed, expected %s, got %s\n",
-               format(buffer_result, expected),
-               format(buffer_expected, result)
-              );
-    } else {
-        printf("passed\n");
+        INDENTED_PRINT("%s:%d: failed, expected %s, got %s\n", file, line, fmt_expected, fmt_result);
     }
     return !is_equal;
 }
 
-int test_str(char *file, int line, char *result, char *expected)
+int test_str(char *file, int line,unsigned int __indentation_level, char *result, char *expected)
 {
     Comparator *compare = (Comparator *) string_compare;
     Formatter *format = (Formatter *) string_format;
 
-    return test(file, line, result, expected, compare, format);
+    return test(file, line, __indentation_level, result, expected, compare, format);
 }
 
-int test_boolean(char *file, int line, bool *result, bool *expected)
+int test_boolean(char *file, int line, unsigned int __indentation_level, bool *result, bool *expected)
 {
     Comparator *compare = (Comparator *) boolean_compare;
     Formatter *format = (Formatter *) boolean_format;
 
-    return test(file, line, (int *) result, (void *) expected, compare, format);
+    return test(file, line, __indentation_level, (int *) result, (void *) expected, compare, format);
 }
 
-int test_ptr(char *file, int line, void *result, void *expected)
+int test_ptr(char *file, int line, unsigned int __indentation_level, void *result, void *expected)
 {
     Comparator *compare = (Comparator *) ptr_compare;
     Formatter *format = (Formatter *) ptr_format;
 
-    return test(file, line, result, expected, compare, format);
+    return test(file, line, __indentation_level, result, expected, compare, format);
 }
 
-int test_uint64_t(char *file, int line, void *result, void *expected)
+int test_uint64_t(char *file, int line, unsigned int __indentation_level, void *result, void *expected)
 {
     Comparator *compare = (Comparator *) uint64_t_compare;
     Formatter *format = (Formatter *) uint64_t_format;
 
-    return test(file, line, (uint64_t *)result, (uint64_t *)expected, compare, format);
+    return test(file, line, __indentation_level, (uint64_t *)result, (uint64_t *)expected, compare, format);
 }
 #endif
 
-- 
GitLab


From 49943ea17c5bdcb96cd808454e3044c15d984b55 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sat, 4 Feb 2023 15:18:26 +0000
Subject: [PATCH 06/69] format

---
 src/amd_rapl.c | 136 +++++++++++++++++++++++++------------------------
 1 file changed, 69 insertions(+), 67 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 0d2ed29..2f20ea2 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -25,8 +25,6 @@
 #include <string.h>
 #include <errno.h>
 #include <stdlib.h>
-#include <assert.h>
-#include <math.h>
 
 #include "info_reader.h"
 #include "util.h"
@@ -38,59 +36,66 @@ static const uint64_t amd_energy_mask = 0xFFFFFFFF;
 static const uint64_t amd_energy_unit_mask = 0x01F00;
 static const uint64_t msr_rapl_power_unit = 0xC0010299;
 static const uint64_t energy_core_msr = 0xC001029A;
-static const uint64_t energy_pkg_msr = 0xC001029B;
 
 // ------------------------------FILE_PATHS
 static const char *base_str = "/dev/cpu/%d/msr";
 
 struct cpu_sensor_t {
-    size_t cpu_id;
-    size_t package_id;
-    char *name;
+    unsigned int cpu_id;
+    unsigned int package_id;
+    unsigned int core_id;
 
+    char *name;
     int fd;
+
     unsigned int energy_units;
     uint64_t core_energy;
-    uint64_t pkg_energy;
 };
 typedef struct cpu_sensor_t cpu_sensor_t;
 
 struct _amd_rapl_t {
     cpu_sensor_t *sensors;
-    unsigned int nb;
+    unsigned int sensor_count;
 };
 typedef struct _amd_rapl_t _amd_rapl_t;
 
 // -----------------------------INFO_READER
 
 #ifdef __READ_CPUINFO__
-
 #warning "Must be modified before release"
 #define MAX_CPUS 64
-#define NB_KEYS 2
+#define NB_KEYS 3
 
 static const char *cpuinfo = "/proc/cpuinfo";
-static GenericPointer _size_t_allocator(char *s)
+
+static GenericPointer uint_allocator(char *s)
 {
-    size_t value = atoi(s);
+    unsigned int value = atoi(s);
     return (GenericPointer) value;
 }
 
 static void _set_cpu_id(GenericPointer storage, GenericPointer data)
 {
     cpu_sensor_t *cpu = (cpu_sensor_t *) storage;
-    cpu->cpu_id = (size_t) data;
+    cpu->cpu_id = (unsigned int) data;
 }
 
 static void _set_package_id(GenericPointer storage, GenericPointer data)
 {
     cpu_sensor_t *cpu = (cpu_sensor_t *) storage;
-    cpu->package_id = (size_t) data;
+    cpu->package_id = (unsigned int) data;
+}
+
+static void _set_core_id(GenericPointer storage, GenericPointer data)
+{
+    cpu_sensor_t *cpu = (cpu_sensor_t *) storage;
+    cpu->core_id = (unsigned int) data;
 }
 
 static KeyFinder keys[NB_KEYS] = {
-    {"processor", ": ", (CopyAllocator *) _size_t_allocator, (Setter *) _set_cpu_id},
-    {"physical id", ": ", (CopyAllocator *) _size_t_allocator, (Setter *) _set_package_id}
+    {"processor", ": ", uint_allocator, _set_cpu_id},
+    {"physical id", ": ", uint_allocator, _set_package_id},
+    {"core id", ": ", uint_allocator, _set_core_id}
 };
 #endif
 
@@ -119,13 +124,20 @@ uint64_t read_raw_core_energy(int fd)
     return energy & amd_energy_mask;
 }
 
+// -------------------------READ_PKG_ENERGY
+
+#ifdef __READ_PKG_ENERGY__
+// TODO: Verify if these functions are still useful (the package energy can be calculed)
+
+static const uint64_t energy_pkg_msr = 0xC001029B;
 uint64_t read_raw_pkg_energy(int fd)
 {
     uint64_t energy = read_msr(fd, energy_pkg_msr);
     return energy & amd_energy_mask;
 }
+#endif
 
-// ---------------------------------ENERGY
+// ----------------------------------ENERGY
 
 uint64_t raw_to_microjoule(uint64_t raw, unsigned int unit)
 {
@@ -147,20 +159,19 @@ uint64_t raw_to_joule(uint64_t raw, uint64_t unit)
 void debug_print_sensor(cpu_sensor_t *sensor)
 {
     //CASSERT(sizeof(cpu_sensor_t) == 56, amd_rapl_c);
-    printf("cpu_id : %ld, package_id : %ld, name : %s, fd: %d,  energy_units : %d, core_energy: %ld, pkg_energy: %ld\n",
+    printf("cpu_id : %d, package_id : %d, name : %s, fd: %d,  energy_units : %d, core_energy: %ld\n",
            sensor->cpu_id,
            sensor->package_id,
            sensor->name,
            sensor->fd,
            sensor->energy_units,
            sensor->core_energy,
-           sensor->pkg_energy
           );
 }
 
 void debug_print_amd_rapl(_amd_rapl_t *rapl)
 {
-    for (unsigned int i = 0; i < rapl->nb; i++) {
+    for (unsigned int i = 0; i < rapl->sensor_count; i++) {
         debug_print_sensor(&rapl->sensors[i]);
     }
 }
@@ -186,57 +197,46 @@ unsigned int get_nb_cpu()
     return n_cpu;
 }
 
-char *get_name(size_t cpu_id)
+char *get_name(unsigned int cpu_id)
 {
-    static const char *base_name = "core%ld";
+    static const char *base_name = "core%d";
     static const size_t max_lenght = 20;
     char *name = (char *)calloc(max_lenght, sizeof(char));
     snprintf(name, max_lenght, base_name, cpu_id);
     return name;
 }
 
-void init_cpu_sensor(cpu_sensor_t *sensor, unsigned int cpu_id)
+void update_cpu_sensor(cpu_sensor_t *sensor, uint64_t *energy_consumed)
 {
+    sensor->energy_units = read_unit(sensor->fd);
+    uint64_t raw_core_energy = read_raw_core_energy(sensor->fd);
+    uint64_t core_energy = raw_to_microjoule(raw_core_energy, sensor->energy_units);
+
+    *energy_consumed = modulo_substraction(core_energy, sensor->core_energy);
+    sensor->core_energy = core_energy;
+}
+
+unsigned int init_cpu_sensor(cpu_sensor_t *sensor, unsigned int cpu_id, unsigned char *cpus_map, unsigned int max_cpus)
+{
+    if (cpus_map[sensor->core_id * max_cpus + sensor->package_id] > 0) {
+        return 0;
+    }
+    cpus_map[sensor->core_id * max_cpus + sensor->package_id] += 1;
+
     static char filename[BUFFER_SIZE];
     sprintf(filename, base_str, cpu_id);
 
     int fd = open(filename, O_RDONLY);
     if (fd < 0) {
-        fprintf(stderr, "open(");
         fprintf(stderr, base_str, cpu_id);
-        perror(")");
+        perror(":open()");
         exit(127);
     }
 
-    uint64_t raw_core_energy = read_raw_core_energy(fd);
-    uint64_t raw_pkg_energy = read_raw_pkg_energy(fd);
-
     sensor->cpu_id = cpu_id;
     sensor->name = get_name(cpu_id);
     sensor->fd = fd;
-    sensor->energy_units = read_unit(fd);
-    sensor->core_energy = raw_to_microjoule(raw_core_energy, sensor->energy_units);
-    sensor->pkg_energy = raw_to_microjoule(raw_pkg_energy, sensor->energy_units);
-}
-
-uint64_t get_core_energy(cpu_sensor_t *sensor)
-{
-    uint64_t raw_core_energy = read_raw_core_energy(sensor->fd);
-    uint64_t core_energy = raw_to_microjoule(raw_core_energy, sensor->energy_units);
-
-    uint64_t energy_consumed = modulo_substraction(core_energy, sensor->core_energy);
-    sensor->core_energy = core_energy;
-    return energy_consumed;
-}
-
-uint64_t get_pkg_energy(cpu_sensor_t *sensor)
-{
-    uint64_t raw_pkg_energy = read_raw_pkg_energy(sensor->fd);
-    uint64_t pkg_energy = raw_to_microjoule(raw_pkg_energy, sensor->energy_units);
-
-    uint64_t energy_consumed = modulo_substraction(pkg_energy, sensor->pkg_energy);
-    sensor->pkg_energy = pkg_energy;
-    return energy_consumed;
+    return 1;
 }
 
 void clean_cpu_sensor(cpu_sensor_t *sensor)
@@ -258,41 +258,42 @@ unsigned int init_amd_rapl(char *none, void **ptr)
     UNUSED(none);
     _amd_rapl_t *rapl = (_amd_rapl_t *) calloc(1, sizeof(_amd_rapl_t));
 
-    unsigned int nb_cpu = get_nb_cpu();
-    if (nb_cpu == 0) {
-        fprintf(stderr, "open(");
-        fprintf(stderr, base_str,0);
-        perror(")");
+    unsigned int max_cpus = get_nb_cpu();
+    if (max_cpus == 0) {
+        fprintf(stderr, base_str, 0);
+        perror(":open()");
         exit(127);
     }
 
-    cpu_sensor_t *cpus = (cpu_sensor_t *) calloc(nb_cpu, sizeof(cpu_sensor_t));
-
-    rapl->nb = nb_cpu;
+    unsigned char *cpus_map = calloc(max_cpus * max_cpus, sizeof(unsigned char));
+    cpu_sensor_t *cpus = (cpu_sensor_t *) calloc(max_cpus, sizeof(cpu_sensor_t));
     rapl->sensors = cpus;
 
-    for (unsigned int i = 0; i < nb_cpu; i++) {
-        init_cpu_sensor(&rapl->sensors[i], i);
+    unsigned int nb_cpu = 0;
+    for (unsigned int i = 0; i < max_cpus; i++) {
+        nb_cpu += init_cpu_sensor(&rapl->sensors[nb_cpu], i, cpus_map, max_cpus);
     }
+    rapl->sensor_count = nb_cpu;
 
     *ptr = (void *) rapl;
-    return rapl->nb;
+    free(cpus_map);
+    return rapl->sensor_count;
 }
 
 
 unsigned int get_amd_rapl(uint64_t *results, void *ptr)
 {
     _amd_rapl_t *rapl = (_amd_rapl_t *) ptr;
-    for (unsigned int i = 0; i < rapl->nb; i++) {
-        results[i] = get_core_energy(&rapl->sensors[i]);
+    for (unsigned int i = 0; i < rapl->sensor_count; i++) {
+        update_cpu_sensor(&rapl->sensors[i], &results[i]);
     }
-    return rapl->nb;
+    return rapl->sensor_count;
 }
 
 void label_amd_rapl(char **labels, void *ptr)
 {
     _amd_rapl_t *rapl = (_amd_rapl_t *) ptr;
-    for (unsigned int i = 0; i < rapl->nb; i++) {
+    for (unsigned int i = 0; i < rapl->sensor_count; i++) {
         labels[i] = rapl->sensors[i].name;
     }
 }
@@ -301,9 +302,10 @@ void clean_amd_rapl(void *ptr)
 {
     _amd_rapl_t *rapl = (_amd_rapl_t *) ptr;
 
-    for (unsigned int i = 0; i < rapl->nb; ++i) {
+    for (unsigned int i = 0; i < rapl->sensor_count; ++i) {
         clean_cpu_sensor(&rapl->sensors[i]);
     }
     free(rapl->sensors);
     free(rapl);
 }
+
-- 
GitLab


From 6e2d8275d7863201bee91ee188adaadb6c2ad276 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 08:28:32 +0000
Subject: [PATCH 07/69] format

---
 tests/info_reader.c | 157 ++++++++++++++++++++++++++++++--------------
 1 file changed, 106 insertions(+), 51 deletions(-)

diff --git a/tests/info_reader.c b/tests/info_reader.c
index 9504631..32734c9 100644
--- a/tests/info_reader.c
+++ b/tests/info_reader.c
@@ -1,54 +1,117 @@
 #include "small_test.h"
 
 TFUNCTION(test_replace_first, {
-    char test1[] = "This is my string";
-    replace_first(test1, 'i', 'I');
-    TEST_STR(test1, "ThIs is my string");
+    // useful variables :
+    char result[100];
+    char expected[100];
 
-    char test2[] = "This is my string";
-    replace_first(test2, 'x', 'X');
-    TEST_STR(test2, "This is my string");
+    // -- Setup
+    strcpy(result, "This is my string");
+    strcpy(expected, "ThIs is my string");
+    // -- Run
+    replace_first(result, 'i', 'I');
+    // -- Verification
+    TEST_STR(result, expected);
+
+    // -- Setup
+    strcpy(result, "This is my string");
+    strcpy(expected, "This is my string");
+    // -- Run
+    replace_first(result, 'x', 'X');
+    // -- Verification
+    TEST_STR(result, expected);
+
+    // -- Setup
+    strcpy(result, "This is my string");
+    strcpy(expected, "This_is my string");
+    // -- Run
+    replace_first(result, ' ', '_');
+    // -- Verification
+    TEST_STR(result, expected);
 
+    // -- Setup
+    strcpy(result, "This is my string");
+    strcpy(expected, "This_is my string");
+    // -- Run
+    replace_first(result, ' ', '_');
+    // -- Verification
+    TEST_STR(result, expected);
 
-    char test3[] = "This is my string";
-    replace_first(test3, ' ', '_');
-    TEST_STR(test3, "This_is my string");
+    // -- Setup
+    strcpy(result, "This is my string");
+    strcpy(expected, "This is my string");
+    // -- Run
+    replace_first(result, 'T', 'T');
+    // -- Verification
+    TEST_STR(result, expected);
 })
 
 TFUNCTION(test_split_on_delimiter, {
-    char test4[] = "key:value";
-    char *key;
-    char *value;
-
-    split_on_delimiter(test4, ":", &key, &value);
-    TEST_STR(key, "key");
-    TEST_STR(value, "value");
-
-    char test5[] = "key: value";
-    split_on_delimiter(test5, ":", &key, &value);
-    TEST_STR(key, "key");
-    TEST_STR(value, " value");
-
-    char test6[] = "key:value";
-    replace_first(test6, ':', ' ');
-    split_on_delimiter(test6, " ", &key, &value);
-    TEST_STR(key, "key");
-    TEST_STR(value, "value");
-
-    char test7[] = "";
-    split_on_delimiter(test7, ":", &key, &value);
-    TEST_STR(key, NULL);
-    TEST_STR(value, NULL);
-
-    char test9[] = "key:value:extra";
-    split_on_delimiter(test9, ":", &key, &value);
-    TEST_STR(key, "key");
-    TEST_STR(value, "value:extra");
-
-    char test10[] = "key: value :extra";
-    split_on_delimiter(test10, ":", &key, &value);
-    TEST_STR(key, "key");
-    TEST_STR(value, " value :extra");
+    // Useful variables
+    char string[100];
+    char *result_key;
+    char *result_value;
+    char expected_key[100];
+    char expected_value[100];
+
+    // Setup
+    strcpy(string, "key:value");
+    strcpy(expected_key, "key");
+    strcpy(expected_value, "value");
+    // Run
+    split_on_delimiter(string, ":", &result_key, &result_value);
+    // Verification
+    TEST_STR(result_key, expected_key);
+    TEST_STR(result_value, expected_value);
+
+    // Setup
+    strcpy(string, "key: value");
+    strcpy(expected_key, "key");
+    strcpy(expected_value, " value");
+    // Run
+    split_on_delimiter(string, ":", &result_key, &result_value);
+    // Verification
+    TEST_STR(result_key, expected_key);
+    TEST_STR(result_value, expected_value);
+
+    // Setup
+    strcpy(string, "key:value");
+    strcpy(expected_key, "key");
+    strcpy(expected_value, "value");
+    replace_first(string, ':', ' ');
+    // Run
+    split_on_delimiter(string, " ", &result_key, &result_value);
+    // Verification
+    TEST_STR(result_key, expected_key);
+    TEST_STR(result_value, expected_value);
+
+    // Setup
+    strcpy(string, "");
+    // Run
+    split_on_delimiter(string, ":", &result_key, &result_value);
+    // Verification
+    TEST_STR(result_key, NULL);
+    TEST_STR(result_value, NULL);
+
+    // Setup
+    strcpy(string, "key:value:extra");
+    strcpy(expected_key, "key");
+    strcpy(expected_value, "value:extra");
+    // Run
+    split_on_delimiter(string, ":", &result_key, &result_value);
+    // Verification
+    TEST_STR(result_key, expected_key);
+    TEST_STR(result_value, expected_value);
+
+    // Setup
+    strcpy(string, "key: value :extra");
+    strcpy(expected_key, "key");
+    strcpy(expected_value, " value :extra");
+    // Run
+    split_on_delimiter(string, ":", &result_key, &result_value);
+    // Verification
+    TEST_STR(result_key, expected_key);
+    TEST_STR(result_value, expected_value);
 })
 
 TFUNCTION(test_start_with, {
@@ -110,7 +173,7 @@ TFUNCTION(test_start_with, {
 
 
 TFUNCTION(test_match, {
-    // usefull variable :
+    // useful variables :
     bool _true = true;
     bool _false = false;
     KeyFinder keys[10];
@@ -198,11 +261,3 @@ TFILE_ENTRY_POINT(test_info_reader, {
     CALL_TFUNCTION(test_match);
 })
 
-#ifdef __TESTING_INFO_READER__
-int main()
-{
-    test_info_reader();
-    return 0;
-}
-#endif
-
-- 
GitLab


From be9a5e0585953b8b3ce75adf0a273a9e32babb19 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 08:28:47 +0000
Subject: [PATCH 08/69] print format

---
 tests/small_test.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/small_test.h b/tests/small_test.h
index 357479a..d1aae8a 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -285,7 +285,7 @@ int test(char *file, int line, unsigned int __indentation_level, void *result, v
     char *fmt_result = format(buffer_result, expected);
     char *fmt_expected = format(buffer_expected, result);
     if  (!is_equal) {
-        INDENTED_PRINT("%s:%d: failed, expected %s, got %s\n", file, line, fmt_expected, fmt_result);
+        INDENTED_PRINT("%s:%d: failed, expected <%s>, got <%s>\n", file, line, fmt_expected, fmt_result);
     }
     return !is_equal;
 }
-- 
GitLab


From 221ec2635483b360fdd9d2198eba678609c6993c Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 08:35:26 +0000
Subject: [PATCH 09/69] remove the gcc dependence

---
 tests/small_test.h | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/tests/small_test.h b/tests/small_test.h
index d1aae8a..9ac572c 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -7,10 +7,9 @@
 #include <stdint.h>
 #include <stdio.h>
 
-// ---------------------------API_INTERFACE
-
-
+#include "../src/util.h"
 
+// ---------------------------API_INTERFACE
 #define TMAIN(code)                                              \
   int main()                                                     \
 {                                                                \
@@ -236,9 +235,10 @@ int string_compare(char *string1, char *string2)
     }
 }
 
-char *string_format(__attribute__((unused)) char *buffer, char *string)
+char *string_format(char *buffer, char *string)
 {
-    return FMT_NULL(string);
+  UNUSED(buffer); 
+  return FMT_NULL(string);
 }
 
 
@@ -247,8 +247,9 @@ int boolean_compare(bool *boolean1, bool *boolean2)
     return *boolean1 == *boolean2;
 }
 
-char *boolean_format(__attribute__((unused)) char *buffer, bool *boolean)
+char *boolean_format(char *buffer, bool *boolean)
 {
+    UNUSED(buffer);
     return *boolean ? "True" : "False";
 }
 
-- 
GitLab


From 26c34e9e53e0c139f7cecf578b9bcf41e16f670b Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 08:39:10 +0000
Subject: [PATCH 10/69] example of how to use src/nfo_reader.c

---
 .../info_reader_ex.c                          | 43 ++++++-------------
 1 file changed, 12 insertions(+), 31 deletions(-)
 rename tests/example_info_reader.c => doc/info_reader_ex.c (76%)

diff --git a/tests/example_info_reader.c b/doc/info_reader_ex.c
similarity index 76%
rename from tests/example_info_reader.c
rename to doc/info_reader_ex.c
index 1dd6464..38d948a 100644
--- a/tests/example_info_reader.c
+++ b/doc/info_reader_ex.c
@@ -1,23 +1,20 @@
 #include "info_reader.h"
 #include <stdint.h>
 
-#ifdef DEBUG
-#warning "PTR_TO_TPTR hide a cast warning"
-#endif
-
 #define MAX_PROCS 2
+#define NB_KEYS 6
 typedef struct {
-    size_t processor;
+    unsigned int processor;
     char *vendor_id;
-    size_t family;
-    size_t core_id;
-    size_t physical_id;
+    unsigned int family;
+    unsigned int core_id;
+    unsigned int physical_id;
     char *model_name;
 } Cpu;
 
 GenericPointer int_allocator(char *s)
 {
-    size_t value = atoi(s);
+    unsigned int value = atoi(s);
     return (GenericPointer) value;
 }
 
@@ -59,19 +56,6 @@ void set_model_name(GenericPointer storage, GenericPointer data)
     cpu->model_name = (char *) data;
 }
 
-struct cpu_sensor_t {
-    //TODO: check the reset of the msr registers
-#warning "Check the reset of the msr registers"
-    size_t cpu_id;
-    size_t package_id;
-    char *name;
-
-    int *fd;
-    uint64_t energy_units;
-    uint64_t core_energy;
-    uint64_t pkg_energy;
-};
-
 int main(int argc, char const *argv[])
 {
     Cpu cpus[MAX_PROCS];
@@ -91,7 +75,7 @@ int main(int argc, char const *argv[])
                      .capacity = MAX_PROCS,
                      .storage_struct_size = sizeof(Cpu),
                      .keys = keys,
-                     .nb_keys = 6,
+                     .nb_keys = NB_KEYS,
                      .file = fopen("/proc/cpuinfo", "r")
                     };
 
@@ -99,19 +83,16 @@ int main(int argc, char const *argv[])
 
     for (unsigned int i = 0; i < parser.nb_stored; ++i) {
         printf("========== PROC[%d] ==========\n", i);
-        printf("Processor: %ld\n", cpus[i].processor);
+        printf("Processor: %u\n", cpus[i].processor);
         printf("Vendor ID: %s\n", cpus[i].vendor_id);
-        printf("Family: %ld\n", cpus[i].family);
-        printf("Core ID: %ld\n", cpus[i].core_id);
-        printf("Physical ID: %ld\n", cpus[i].physical_id);
+        printf("Family: %u\n", cpus[i].family);
+        printf("Core ID: %u\n", cpus[i].core_id);
+        printf("Physical ID: %u\n", cpus[i].physical_id);
         printf("Model Name: %s\n", cpus[i].model_name);
-        printf("==============================\n");
         free(cpus[i].vendor_id);
         free(cpus[i].model_name);
     }
-
-    printf("size = %ld\n", sizeof (struct cpu_sensor_t));
-
+        printf("==============================\n");
     return 0;
 }
 
-- 
GitLab


From d1d5853bdd89bf2dac4b707d163958542aa5ac76 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 08:39:44 +0000
Subject: [PATCH 11/69] format

---
 doc/info_reader_ex.c | 2 +-
 tests/small_test.h   | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/doc/info_reader_ex.c b/doc/info_reader_ex.c
index 38d948a..6b284a5 100644
--- a/doc/info_reader_ex.c
+++ b/doc/info_reader_ex.c
@@ -92,7 +92,7 @@ int main(int argc, char const *argv[])
         free(cpus[i].vendor_id);
         free(cpus[i].model_name);
     }
-        printf("==============================\n");
+    printf("==============================\n");
     return 0;
 }
 
diff --git a/tests/small_test.h b/tests/small_test.h
index 9ac572c..33c34c6 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -237,8 +237,8 @@ int string_compare(char *string1, char *string2)
 
 char *string_format(char *buffer, char *string)
 {
-  UNUSED(buffer); 
-  return FMT_NULL(string);
+    UNUSED(buffer);
+    return FMT_NULL(string);
 }
 
 
-- 
GitLab


From d8d7594057326d29a07d48057cfba3574df122e8 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 09:00:30 +0000
Subject: [PATCH 12/69] cleanup

---
 doc/info_reader_ex.c | 28 +++++++++++++++++++++++++---
 1 file changed, 25 insertions(+), 3 deletions(-)

diff --git a/doc/info_reader_ex.c b/doc/info_reader_ex.c
index 6b284a5..23ee7d5 100644
--- a/doc/info_reader_ex.c
+++ b/doc/info_reader_ex.c
@@ -1,8 +1,30 @@
-#include "info_reader.h"
-#include <stdint.h>
+/*******************************************************
+ 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/>.
+
+*******************************************************/
+
+
+// ~/mojitos/doc/$ gcc -Wall -Wextra -Wpedantic -O3 -o info_reader_ex info_reader_ex.c ./../src/util.c && ./info_reader_ex
+#include "./../src/info_reader.h"
 
 #define MAX_PROCS 2
 #define NB_KEYS 6
+
 typedef struct {
     unsigned int processor;
     char *vendor_id;
@@ -56,7 +78,7 @@ void set_model_name(GenericPointer storage, GenericPointer data)
     cpu->model_name = (char *) data;
 }
 
-int main(int argc, char const *argv[])
+int main()
 {
     Cpu cpus[MAX_PROCS];
     KeyFinder keys[] = {
-- 
GitLab


From 730f969f8cd60054edf8cc995650fdee0f9d2d44 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 12:14:21 +0000
Subject: [PATCH 13/69] add test example

---
 doc/test_file_ex.c | 112 +++++++++++++++++++++++++++++++++++++++++++++
 doc/test_main_ex   | Bin 0 -> 17416 bytes
 doc/test_main_ex.c |  35 ++++++++++++++
 3 files changed, 147 insertions(+)
 create mode 100644 doc/test_file_ex.c
 create mode 100755 doc/test_main_ex
 create mode 100644 doc/test_main_ex.c

diff --git a/doc/test_file_ex.c b/doc/test_file_ex.c
new file mode 100644
index 0000000..44ebc2c
--- /dev/null
+++ b/doc/test_file_ex.c
@@ -0,0 +1,112 @@
+/*******************************************************
+ 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 of the test library
+#include "./../tests/small_test.h"
+
+// -- A simple function that should pass
+TFUNCTION(test_should_pass, {
+    char *result = "It's going to pass";
+    char *expected = "It's going to pass";
+    TEST_STR(result, expected);
+})
+
+// -- A simple function that should fail
+TFUNCTION(test_should_fail, {
+    char *result = "a fail";
+    char *expected = "a nice fail";
+    TEST_STR(result, expected);
+})
+
+// -- Add a new type in the test framework
+
+typedef struct {
+    int simple_int;
+    char simple_str[20];
+} UserType;
+
+
+// -- Implemet the interface
+int usertype_compare(void *ptr1, void *ptr2)
+{
+    return memcmp(ptr1, ptr2, sizeof(UserType)) == 0;
+}
+
+char *usertype_format(char buffer[1000], void *ptr)
+{
+    UserType *x = (UserType *) ptr;
+    sprintf(buffer, "UserType {simple_int: %d, simple_str: %s}", x->simple_int, x->simple_str);
+    return buffer;
+}
+
+// Create a variable which contains the functions
+static const TestInterface usertype_interface = {
+    .compare = usertype_compare,
+    .format = usertype_format
+};
+
+// -- Create the test macro to call
+#define TEST_USER_TYPE(__result, __expected) \
+    TEST_INTERFACE(__result, __expected, &usertype_interface);
+
+// -- Create a macro setter
+#define DUMMY_USER_TYPE(__user, __simple_int, __simple_str) \
+    do {                                                    \
+      __user = (UserType) {                                 \
+          .simple_int = __simple_int,                       \
+          .simple_str = __simple_str                        \
+    };                                                      \
+} while (0);
+
+// -- Compare two usertype
+TFUNCTION(test_user_type, {
+    UserType x1;
+    UserType x2;
+
+    DUMMY_USER_TYPE(x1, 1, "John Doe");
+    DUMMY_USER_TYPE(x2, 1, "John Doe");
+
+    TEST_USER_TYPE(&x1, &x2);
+})
+
+
+// -- Compare an array of usetype
+TFUNCTION(test_array_user_type, {
+    UserType *results[1];
+    UserType *expecteds[1];
+
+    UserType x1;
+    UserType x2;
+    DUMMY_USER_TYPE(x1, 1, "John Doe");
+    DUMMY_USER_TYPE(x2, 1, "John Doe");
+
+    results[0] = &x1;
+    expecteds[0] = &x2;
+
+    TEST_T_ARRAY(TEST_USER_TYPE, 1, (void **)results, (void **)expecteds);
+})
+
+// Define the entry point of a test file
+TFILE_ENTRY_POINT(test_file_ex, {
+    CALL_TFUNCTION(test_should_pass);
+    CALL_TFUNCTION(test_should_fail);
+    CALL_TFUNCTION(test_user_type);
+    CALL_TFUNCTION(test_array_user_type);
+})
diff --git a/doc/test_main_ex b/doc/test_main_ex
new file mode 100755
index 0000000000000000000000000000000000000000..0ab7870283c6ba20a50b3761a1c009eb89f3ac20
GIT binary patch
literal 17416
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
A`~Uy|

literal 0
HcmV?d00001

diff --git a/doc/test_main_ex.c b/doc/test_main_ex.c
new file mode 100644
index 0000000..0aa86b9
--- /dev/null
+++ b/doc/test_main_ex.c
@@ -0,0 +1,35 @@
+/*******************************************************
+ 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/>.
+
+*******************************************************/
+
+// ~/mojitos/doc$ gcc -Wall -Wextra -Wpedantic -o test_main_ex test_main_ex.c ./../src/util.c
+// Include of the test library
+#include "./../tests/small_test.h"
+
+// Include the *.c files that contain the tests
+#include "./test_file_ex.c"
+// #include "./test_another_test_file.c"
+
+// Define the entry point of the programme
+TMAIN({
+    // Must contain the call to the entry point functions of each file
+    // USE CALL_TFUNCTION(my_function) instead of my_function()
+    CALL_TFUNCTION(test_file_ex);
+    // CALL_TFUNCTION(another_file_entry_point_function);
+})
-- 
GitLab


From e16dc9f4d47bc55b5875136ff06629459839ffca Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 12:14:43 +0000
Subject: [PATCH 14/69] add licence

---
 src/amd_rapl.c      |   2 +-
 src/amd_rapl.h      |   2 +-
 tests/amd_rapl.c    |  20 ++++
 tests/info_reader.c |  40 ++++++--
 tests/main.c        |  20 ++++
 tests/small_test.h  | 216 +++++++++++++++++++++++++-------------------
 tests/util.c        |  20 ++++
 7 files changed, 215 insertions(+), 105 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 2f20ea2..51df298 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2022-2023 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/src/amd_rapl.h b/src/amd_rapl.h
index 4f375b9..f16ed4f 100644
--- a/src/amd_rapl.h
+++ b/src/amd_rapl.h
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2022-2023 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index 262c1f8..39214fc 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -1,3 +1,23 @@
+/*******************************************************
+ 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/amd_rapl.c"
 
diff --git a/tests/info_reader.c b/tests/info_reader.c
index 32734c9..b2a8c6f 100644
--- a/tests/info_reader.c
+++ b/tests/info_reader.c
@@ -1,3 +1,23 @@
+/*******************************************************
+ 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"
 
 TFUNCTION(test_replace_first, {
@@ -124,27 +144,27 @@ TFUNCTION(test_start_with, {
     prefix = "Hello";
     string = "Hello World";
     result = start_with(prefix, string);
-    TEST_BOOLEAN(&result, &_true);
+    TEST_BOOL(&result, &_true);
 
     prefix = "Goodbye";
     string = "Hello World";
     result = start_with(prefix, string);
-    TEST_BOOLEAN(&result, &_false);
+    TEST_BOOL(&result, &_false);
 
     prefix = "Hello World";
     string = "Hello";
     result = start_with(prefix, string);
-    TEST_BOOLEAN(&result, &_false);
+    TEST_BOOL(&result, &_false);
 
     prefix = "Hello";
     string = "Hello";
     result = start_with(prefix, string);
-    TEST_BOOLEAN(&result, &_true);
+    TEST_BOOL(&result, &_true);
 
     prefix = NULL;
     string = "Hello World";
     result = start_with(prefix, string);
-    TEST_BOOLEAN(&result, &_false);
+    TEST_BOOL(&result, &_false);
 })
 
 #define NONE 0
@@ -193,7 +213,7 @@ TFUNCTION(test_match, {
     // -- Run
     result = match(&parser, line, &found_key_finder, &raw_value);
     // -- Verification
-    TEST_BOOLEAN(&result, &_true);
+    TEST_BOOL(&result, &_true);
     TEST_PTR(found_key_finder, &keys[0]);
     TEST_STR(raw_value, "value");
 
@@ -207,7 +227,7 @@ TFUNCTION(test_match, {
     // -- Run
     result = match(&parser, line, &found_key_finder, &raw_value);
     // -- Verification
-    TEST_BOOLEAN(&result, &_false);
+    TEST_BOOL(&result, &_false);
     TEST_PTR(found_key_finder, NULL);
     TEST_STR(raw_value, NULL);
 
@@ -221,7 +241,7 @@ TFUNCTION(test_match, {
     // -- Run
     result = match(&parser, line, &found_key_finder, &raw_value);
     // -- Verification
-    TEST_BOOLEAN(&result, &_false);
+    TEST_BOOL(&result, &_false);
     TEST_PTR(found_key_finder, NULL);
     TEST_STR(raw_value, NULL);
 
@@ -236,7 +256,7 @@ TFUNCTION(test_match, {
     // -- Run
     result = match(&parser, line, &found_key_finder, &raw_value);
     // -- Verification
-    TEST_BOOLEAN(&result, &_true);
+    TEST_BOOL(&result, &_true);
     TEST_PTR(found_key_finder, &keys[1]);
     TEST_STR(raw_value, "value");
 
@@ -249,7 +269,7 @@ TFUNCTION(test_match, {
     raw_value = NULL;
     // -- Run
     result = match(&parser, line, &found_key_finder, &raw_value);
-    TEST_BOOLEAN(&result, &_false);
+    TEST_BOOL(&result, &_false);
     TEST_PTR(found_key_finder, NULL);
     TEST_STR(raw_value, NULL);
 })
diff --git a/tests/main.c b/tests/main.c
index e48b56a..3246f04 100644
--- a/tests/main.c
+++ b/tests/main.c
@@ -1,3 +1,23 @@
+/*******************************************************
+ 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 "util.c"
 #include "amd_rapl.c"
 #include "info_reader.c"
diff --git a/tests/small_test.h b/tests/small_test.h
index 33c34c6..9f6a6d9 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -1,3 +1,23 @@
+/*******************************************************
+ 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/>.
+
+*******************************************************/
+
 #ifndef __SMALL_TEST_H
 #define __SMALL_TEST_H
 
@@ -77,49 +97,48 @@
  * @param function_name The name of the test function to be called.
  */
 #define CALL_TFUNCTION(function_name) \
-  __error_counter__ += function_name(__indentation_level + 1)
-
+  do {__error_counter__ += function_name(__indentation_level + 1);} while(0)
 
 /**
  * @def TEST_STR(result, expected)
  * @brief Test strings
- * This macro is used to test strings. It takes two arguments: `result`, which is the string to be tested, and `expected`, which is the expected value of the string.
+ * This macro is used to test strings. It takes two arguments: `__result`, which is the string to be tested, and `__expected`, which is the expected value of the string.
  * The macro uses the `test_str()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
  *
- * @param result the string to be tested
- * @param expected the expected value of the string
+ * @param __result the string to be tested
+ * @param __expected the expected value of the string
  *
  * @code
  * TEST_STR("Hello", "Hello");
  * @endcode
  */
-#define TEST_STR(result, expected) \
-    __error_counter__ += test_str(__FILE__, __LINE__, __indentation_level, result, expected)
+#define TEST_STR(__result, __expected) \
+    do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, &str_interface);} while(0)
 
 /**
- * @def TEST_BOOLEAN(result, expected)
- * @brief Test booleans
- * This macro is used to test booleans. It takes two arguments: `result`, which is the boolean to be tested, and `expected`, which is the expected value of the boolean.
- * The macro uses the `test_boolean()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
+ * @def TEST_BOOL(__result, __expected)
+ * @brief Test bools
+ * This macro is used to test bools. It takes two arguments: `__result`, which is the bool to be tested, and `__expected`, which is the expected value of the bool.
+ * The macro uses the `test_bool()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
  *
- * @param result the boolean to be tested
- * @param expected the expected value of the boolean
+ * @param __result the bool to be tested
+ * @param __expected the expected value of the bool
  *
  * @code
- * TEST_BOOLEAN(1 == 1, true);
+ * TEST_BOOL(1 == 1, true);
  * @endcode
  */
-#define TEST_BOOLEAN(result, expected) \
-	__error_counter__ += test_boolean(__FILE__, __LINE__, __indentation_level, result, expected)
+#define TEST_BOOL(__result, __expected) \
+    do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, &bool_interface);} while (0)
 
 /**
- * @def TEST_PTR(result, expected)
+ * @def TEST_PTR(__result, __expected)
  * @brief Test pointers
- * This macro is used to test pointers. It takes two arguments: `result`, which is the pointer to be tested, and `expected`, which is the expected value of the pointer.
+ * This macro is used to test pointers. It takes two arguments: `__result`, which is the pointer to be tested, and `__expected`, which is the expected value of the pointer.
  * The macro uses the `test_ptr()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
  *
- * @param result the pointer to be tested
- * @param expected the expected value of the pointer
+ * @param __result the pointer to be tested
+ * @param __expected the expected value of the pointer
  *
  * @code
  * int x = 5;
@@ -127,47 +146,48 @@
  * TEST_PTR(ptr, &x);
  * @endcode
  */
-#define TEST_PTR(result, expected) \
-	__error_counter__ += test_ptr(__FILE__, __LINE__, __indentation_level, result, expected)
+#define TEST_PTR(__result, __expected) \
+	do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, &ptr_interface);} while(0)
 
 
 /**
- * @def TEST_UINT64_T(result, expected)
+ * @def TEST_UINT64_T(__result, __expected)
  * @brief Test 64-bit unsigned integers
- * This macro is used to test 64-bit unsigned integers. It takes two arguments: `result`, which is the integer to be tested, and `expected`, which is the expected value of the integer.
+ * This macro is used to test 64-bit unsigned integers. It takes two arguments: `__result`, which is the integer to be tested, and `__expected`, which is the expected value of the integer.
  * The macro uses the `test_uint64_t()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
  *
- * @param result the integer to be tested
- * @param expected the expected value of the integer
+ * @param __result the integer to be tested
+ * @param __expected the expected value of the integer
  *
  * @code
  * TEST_UINT64_T(5, 5);
  * @endcode
  */
-#define TEST_UINT64_T(result, expected) \
-	__error_counter__ += test_uint64_t(__FILE__, __LINE__, __indentation_level, result, expected)
+#define TEST_UINT64_T(__result, __expected) \
+	do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, &u64_interface);} while(0)
+
+#define TEST_INTERFACE(__result, __expected, __interface) \
+	do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, __interface);} while(0)
 
 /**
  * @def TEST_T_ARRAY(function, nb_error, size, results, expecteds)
  * @brief Test arrays of data
- * The macro uses a for loop to iterate through the array and apply the test function to each element,
- * adding any errors to the nb_error variable.
+ * The macro uses a for loop to iterate through the array and apply the test function to each element.
  *
- * @param function the test function to be used on each element of the array
- * @param nb_error the number of errors encountered during the test
- * @param size the number of elements in the array
- * @param results the array of elements to be tested
- * @param expecteds the array of expected values
+ * @param __test_macro the test function to be used on each element of the array
+ * @param __array_size the number of elements in the array
+ * @param __results the array of elements to be tested
+ * @param __expecteds the array of expected values
 
  * @code
  * int results[3] = {1, 2, 3};
  * int expecteds[3] = {1, 2, 3};
- * TEST_T_ARRAY(TEST_INT, errors, 3, results, expecteds);
+ * TEST_T_ARRAY(TEST_INT, 3, results, expecteds);
  * @endcode
 */
-#define TEST_T_ARRAY(function, size, results, expecteds)	\
-	for (unsigned int i = 0; i < size; i++) {						\
-		function(results[i], expecteds[i]);				\
+#define TEST_T_ARRAY(__test_macro, __array_size, __results, __expecteds)  \
+	for (unsigned int i = 0; i < __array_size; i++) {                       \
+      __test_macro(__results[i], __expecteds[i]);                         \
 	}
 
 
@@ -213,46 +233,71 @@
 
 #define DEFERRED_FILE_ERROR(nb_error) \
     INDENTED_PRINT("|_Deferred Error : %u\n",nb_error);
-//INDENTED_PRINT("Deferred Error in %s: %d\n",__FILE__, nb_error);
 
 #define DEFERRED_FUNCTION_ERROR(nb_error) \
     INDENTED_PRINT("|_Deferred Error : %d\n",nb_error);
 
-#define FMT_NULL(string) \
-	string = string ? string : "NULL"
-
 typedef int (Comparator) (void *, void *);
 typedef char *(Formatter) (char *, void *);
 
-int string_compare(char *string1, char *string2)
+typedef struct {
+    Comparator *compare;
+    Formatter *format;
+} TestInterface;
+
+//  ---------------------------str_interface
+
+int str_compare(void *ptr1, void *ptr2)
 {
-    if (string1 == NULL && string2 == NULL) {
+    char *str1 = (char *) ptr1;
+    char *str2 = (char *) ptr2;
+
+    if (str1 == NULL && str2 == NULL) {
         return 1;
-    } else if (string1 == NULL || string2 == NULL) {
+    } else if (str1 == NULL || str2 == NULL) {
         return 0;
     } else {
-        return (strcmp(string1, string2) == 0);
+        return (strcmp(str1, str2) == 0);
     }
 }
 
-char *string_format(char *buffer, char *string)
+char *str_format(char *buffer, void *ptr)
 {
     UNUSED(buffer);
-    return FMT_NULL(string);
+    static char *str_null = "NULL";
+    char *str = (char *) ptr;
+    return str ? str : str_null;
 }
 
+static const TestInterface str_interface = {
+    .compare = str_compare,
+    .format = str_format
+};
+
+//  --------------------------bool_interface
 
-int boolean_compare(bool *boolean1, bool *boolean2)
+
+int bool_compare(void *ptr1, void *ptr2)
 {
-    return *boolean1 == *boolean2;
+    bool *bool1 = (bool *) ptr1;
+    bool *bool2 = (bool *) ptr2;
+    return *bool1 == *bool2;
 }
 
-char *boolean_format(char *buffer, bool *boolean)
+char *bool_format(char *buffer, void *ptr)
 {
     UNUSED(buffer);
-    return *boolean ? "True" : "False";
+    bool *_bool = (bool *) ptr;
+    return *_bool ? "True" : "False";
 }
 
+static const TestInterface bool_interface = {
+    .compare = bool_compare,
+    .format = bool_format
+};
+
+// ---------------------------ptr_interface
+
 int ptr_compare(void *ptr1, void *ptr2)
 {
     return ptr1 == ptr2;
@@ -264,63 +309,48 @@ char *ptr_format(char *buffer, void *ptr)
     return buffer;
 }
 
+static const TestInterface ptr_interface = {
+    .compare = ptr_compare,
+    .format = ptr_format
+};
+
+// ---------------------------u64_interface
 
-int uint64_t_compare(uint64_t *value1, uint64_t *value2)
+int u64_compare(void *ptr1, void *ptr2)
 {
-    return *value1 == *value2;
+    uint64_t *v1 = (uint64_t *) ptr1;
+    uint64_t *v2 = (uint64_t *) ptr2;
+    return *v1 == *v2;
 }
 
-char *uint64_t_format(char *buffer, uint64_t *value)
+char *u64_format(char *buffer, void *ptr)
 {
-    sprintf(buffer, "%"PRIu64"", *value);
+    uint64_t *v = (uint64_t *) ptr;
+    sprintf(buffer, "%"PRIu64"", *v);
     return buffer;
 }
 
-int test(char *file, int line, unsigned int __indentation_level, void *result, void *expected, Comparator *compare, Formatter *format)
+static const TestInterface u64_interface = {
+    .compare = u64_compare,
+    .format = u64_format
+};
+
+// ---------------------------test_function
+
+int test(char *file, int line, unsigned int __indentation_level, void *result, void *expected, const TestInterface *interface)
 {
-    __indentation_level++;
+    __indentation_level += 1;
     static char buffer_result[1000];
     static char buffer_expected[1000];
-    int is_equal = compare(result, expected);
+    int is_equal = interface->compare(result, expected);
 
-    char *fmt_result = format(buffer_result, expected);
-    char *fmt_expected = format(buffer_expected, result);
+    char *fmt_result = interface->format(buffer_expected, expected);
+    char *fmt_expected = interface->format(buffer_result, result);
     if  (!is_equal) {
         INDENTED_PRINT("%s:%d: failed, expected <%s>, got <%s>\n", file, line, fmt_expected, fmt_result);
     }
     return !is_equal;
 }
 
-int test_str(char *file, int line,unsigned int __indentation_level, char *result, char *expected)
-{
-    Comparator *compare = (Comparator *) string_compare;
-    Formatter *format = (Formatter *) string_format;
-
-    return test(file, line, __indentation_level, result, expected, compare, format);
-}
-
-int test_boolean(char *file, int line, unsigned int __indentation_level, bool *result, bool *expected)
-{
-    Comparator *compare = (Comparator *) boolean_compare;
-    Formatter *format = (Formatter *) boolean_format;
-
-    return test(file, line, __indentation_level, (int *) result, (void *) expected, compare, format);
-}
-
-int test_ptr(char *file, int line, unsigned int __indentation_level, void *result, void *expected)
-{
-    Comparator *compare = (Comparator *) ptr_compare;
-    Formatter *format = (Formatter *) ptr_format;
-
-    return test(file, line, __indentation_level, result, expected, compare, format);
-}
-
-int test_uint64_t(char *file, int line, unsigned int __indentation_level, void *result, void *expected)
-{
-    Comparator *compare = (Comparator *) uint64_t_compare;
-    Formatter *format = (Formatter *) uint64_t_format;
-
-    return test(file, line, __indentation_level, (uint64_t *)result, (uint64_t *)expected, compare, format);
-}
 #endif
 
diff --git a/tests/util.c b/tests/util.c
index a91c58f..69941bf 100644
--- a/tests/util.c
+++ b/tests/util.c
@@ -1,3 +1,23 @@
+/*******************************************************
+ 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 "../src/util.h"
 #include "small_test.h"
 
-- 
GitLab


From 22cbdb2ae7804be8f3a03610175c3b4e56c93dc0 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 12:26:23 +0000
Subject: [PATCH 15/69] add informations

---
 tests/small_test.h | 31 ++++++++-----------------------
 1 file changed, 8 insertions(+), 23 deletions(-)

diff --git a/tests/small_test.h b/tests/small_test.h
index 9f6a6d9..aedc685 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -30,6 +30,11 @@
 #include "../src/util.h"
 
 // ---------------------------API_INTERFACE
+/**
+ * @brief Define the entry point of the tests
+ * It initializes each useful variables.
+ */
+
 #define TMAIN(code)                                              \
   int main()                                                     \
 {                                                                \
@@ -169,6 +174,7 @@
 #define TEST_INTERFACE(__result, __expected, __interface) \
 	do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, __interface);} while(0)
 
+
 /**
  * @def TEST_T_ARRAY(function, nb_error, size, results, expecteds)
  * @brief Test arrays of data
@@ -192,6 +198,7 @@
 
 
 // --------------------------------API_CODE
+// These functions should not be used, only use the previous macros.
 
 
 #define INDENTED_PRINT(__fmt, ...)                          \
@@ -202,32 +209,10 @@
     printf(__fmt, ##__VA_ARGS__);                           \
   } while(0)
 
-/**
- * @def INIT_TEST_FILE()
- * @brief Initialize the test file
- * This macro is used to initialize the test file. It takes the `__FILE__` and `__func__` preprocessor macros as arguments, which provide the name of the current file and the current function, respectively.
- *
- * @param __FILE__ preprocessor macro that provides the name of the current file
- * @param __func__ preprocessor macro that provides the name of the current function
- *
- * @code
- * INIT_TEST_FILE();
- * @endcode
- */
+
 #define INIT_TEST_FILE()     \
   INDENTED_PRINT("%s:%s\n", __FILE__, __func__)
 
-/**
- * @def INIT_TEST_FUNCTION()
- * @brief Initialize the test function
- * This macro is used to initialize the test function. It takes the `__func__` preprocessor macro as an argument, which provides the name of the current function.
- *
- * @param __func__ preprocessor macro that provides the name of the current function
- *
- * @code
- * INIT_TEST_FUNCTION();
- * @endcode
- */
 #define INIT_TEST_FUNCTION() \
   INDENTED_PRINT("%s()\n", __func__);
 
-- 
GitLab


From 95956fd34bad0e160dd15e96f25d006eef8df7a1 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 12:27:51 +0000
Subject: [PATCH 16/69] remove bin

---
 doc/test_main_ex | Bin 17416 -> 0 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100755 doc/test_main_ex

diff --git a/doc/test_main_ex b/doc/test_main_ex
deleted file mode 100755
index 0ab7870283c6ba20a50b3761a1c009eb89f3ac20..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 17416
zcmb<-^>JfjWMqH=W(GS35buEiM8p9?F>u&G84L^z4h$9yybKNu3JmfLYzzzxEMPH+
zJWM@|zQF_$htV7mE(0@Ep9F}(z`%e`%Rtq^XpoygLLeGsABc?&8$d09(F{<3fb_9~
zG(h<<aTx8&4U%MFfYC5<kUp?|3J`e)G+G2~C<6nGM%D)k8wXv8J_lP=8WtWexFF&%
zeW2h1>01ERw*aaSMt=Y~h=G9tMnk;|jsuW8Eui6vP8&e2fzjytGNAg<X&0zI7!9%m
zBozF#Bn8Aqw+F_D*#o0t_60!o^(cZ&VPHU~_dtXhU^K`MkWk>$k`z$5fY`)fSTqMg
z?ZXuh2S5SNz`y{bp~1_bpOcwnW}=^yqMMVMS6ZQ4VPU3gW};V|uV)0d9^@`iQUFE2
zyI&{+69dBmkQg)=8JHR%e3*G4IS~d1aJmPnpJ)5Nb?@T%=MPt`vFmpAvMSud+Xhkt
zayLj1NDas$ka<uig18`i7(ht|qy`cmjbL$*7>IE(^;|B9#)U!V3t^EgVPJqKZDeT+
z1_lOf>J4#-YvK@B!XZ8ZhrOV5gU#OgIMjo}17ruX+rjMk_~eSj__WNt#GK5kREGHY
zoXn);_~MepqLTRB#LPT~;*z4|+yaK&)Lal%Tu_vmSCYmM4^onx9iN<$9iNt%nZp3m
z28w<&26rD%C+B!0JtI9+INJoyGB#m|_YCokPf0CGP0uVYNi7QTb<WApOASd($^qG*
zo|~TsGQ6lHJ|3bJt3n0_1||kZ24)5pFl1z4VSr#}22TbCSaHEnDwW9zDuIKcVj`KD
zyr5JT59M!}IE@WtQYJVs7#LvX5G+3)5QIp0K+74Jcmq^C08RWPR6GJr+yoj~325R;
zQ1J{j@mWyu0yOdSQ1J>h@%K>i1~hREVTk)X(8Lp=;uFxsW5poqXP}8shKh4QD=t_#
z!1w}a;{QRJpMinlf<44MP+kP3K?sk5;Rcd8a{hgQB+d>~%)r3#0!f?`N&EwnI4qBY
zq*p-2L1uu;2#^>EZ$J_Ul_wxE5Z-|#4l1)iVjz3~NgU({kQfM`KoW<A1xS1pkA}c#
z2#kinXb6mkz-R~z{Sf%fFZau%`3;9hH|s@x1_qDT10_uVFL*Q`;W!NT+<(&|eFlb4
z|5c0i85sEG89?eYKr)|RKK%dx{{%1})bRQA@*<oMYVdq|c@WMAHBdgi+z97`8YZ7!
zE`;$v{Z~x|o9@B@HviLqRbDhcD;oc=9>_Ha^<UBWZ;|<iZ#_FN#(8u;@@RhYAt1!n
z@POe-k6znoP6memqNnv37`~+G@yoY>e8u3=Ys&}<hhElSdJGI6mOn~FJ-S)ff!M7F
zN;v;N;FoUzDLf3NJ$h{~f+TxQPk|`Se;%D5JPy9I_c-{2*@N+z$HjjoA|BnWwIIpX
z10@{)AEfciyD%`o^n=2$!FH-10|P^;cBn_QZ4`*<(fPE5$D`XeO^<=$#m#^J|G!B2
z|Ns9n)?7UX2FBRK{PHOJUzY#>{~u&fs7L2hkLEWD9-Xx>JUUAscyznI@aS~?;L+{+
zz@yXkhevbm2ZmBUkLKDR45jQlK+*Qv04!L-4if}<?zOZ>cjym~Zr2YUo!2}%kH47q
z@BjbS1N>7C@NYYC@-W;ggf%eZe=wA=d33w}c+Kw7&ALICfgu)~YE(ycyMEx`CIHgK
zzm37-5X2U&`XIJ+yZ+$c#?W%0gwvy!)rXgX;WfKQFRKSHnq@ycI!i%5|KVZn`T@hx
z<~IT!owZOkp%8VwyqvrY3?7~5JUWl>0ENSgb$|c=2RRI@pD}#l(GB*6M>m6qC8jq}
z;|1;&h^7}Fy}bQAsFoW-EPsJydGnh9kIvc~ouyYgLoaxA`kwIVbUonH>AR!Z^#Y?u
zx9bj%ZVr#`&;uUbt|uT-_y1z2>l=tn0Eb7n>j96>V;;S%t~wyQj{m;|O&&Wuy1~*X
zAku0E2<acqwQm?ogO0nt00qfw36EaZm)u}!NEk)^`TxJ!^#x<M>kDhw3q=n+x<SG2
z`=dMbibuEW4bRRG5HoinYf=Sis(r%%i5C<f8g$m)Iqv!dZdnbozPG<YmOWwYc70;)
zdZ*}tM=z@vIM_g*YCu+b`1k++$6eomjPdAY%?3-ke(>mJO@J_ecy#;z@aPWx(CvE1
zr<d17gMq=b^Mps|#m+<fKph^BURF=A%HuC;|NZ~Z==ugZ1fFvtg+K(@QP2>$Q}m$Q
z^$j?Xr6Bqt!DRgV|Nm~+H+a1|5!qBGu&F3stp^(j^6FG%l{bDNdv!Nh3hdSG5GI;e
zBh`_-%Fn>S;L*z(2UdCf#iYL&Uj4&~<kj3?pzz1^sy;+N#H${^FujVD+kC;fZI=Yd
zW^i76q5cbN@q#PI^m?#>G9@^-z3}KYeSqx3-#@`w7B$x-bk?p(@#tnz)c{-S`or+R
zan~)Nv;j`flE?;h{RDY&3uCwI7Hiiv;3Osw_8lnPWsy}T`~-zNc%<^U>j6+{>aoKs
zKO;}UB|mi+$Z(HN*CQUCp=XY}UIB5ByFLIb>U4eL(HZ*Yxa${?s7J5w1CQR&1KqA`
ze0q8Rs3JuUXpF+6m-QeAI0jyP{SAtoJ;z<a!3=hJJVXjC@Z!P`kjr;4cDwEXyS&?V
z4>%o8LRPf;2Pks(fC~5&4{Z@}h?KCtX!-H~KXTeU($HDkgArsiKn@05{EQv!CWyu1
zV2fukcDv57cI^QN84Ea|Ktc8jS*7j|P>{_58ADN!fyy!06&}6ddTqmT*99OGU)y%O
zF7W8~Il2K%ha6qe?b_qh%ez7aDNKDqDWI1%7vicH3x9#abWXGD0><Xr1q>y7kGn1b
zn*}Q87$J%vo-Fzf3f(1)-L6Z(p6qs=0}fpiWJSK;L7_VbJ#^K+qlWGqh0a=7{DXsY
zIvY}Oa)536!r1Nl#oF}^I5^LOEji@T%en=u5)`n)U@>S-b>$l<VE=%e-tGFP`2b_*
z@fXX%e)|LGH-Xa+f`9uD$nOaLKXB&%bKLa@$QZD@{<9*vtKb_b1b#4fyZ!*XtK0Pt
zI0Pnwodk7=_cu@o{6S7jZv>!59(Vl!H+d<t$zouWKQMN?ez11^0rv3=u%RFydxBXY
zA1i`cP>UXYMe^|vh>vH1OX@$+oCWrQEwVl9zJh!J4cQ-{k{aTJ^T>)izoPp9-cWG;
z;i2vNA@(q&oeFL@!&}NApN-<t5Eu=C(GVCqA;1WpQAD^mq^LBN!7VYTIF&)QfI&5<
zl%YmJK|z5*wb)8E#YzD*6_%Q!qmWurkeXbQnxbH%T5PAIke*)xW^pm77Hep7F?g1!
z7b~RaXXd3Vl;kTEBo-Gl=;@cF7MH}QW#**Dr&j1CGt|Vpq^6}76{V&qxE2-V7b#dN
zsHSi+B!cZ=NL0wnOiqQcL9PoePAv+lEJ#(TF3!v?$VrXQ%qszD&{2T$i%W{E6jY0A
z!7eT4!fJde7X#Q4pm{%tBm6>rd_cy-F<8DhBfm5!B_8Z<xD14WEDs6{h$sWZ+|uII
zqWF@^f>f9&R6Mb$D6ujgMHXxhG%y%I?qOhHV3cOI2DLRnQ&Cgi{r?Z@ynK20|Gx+$
z0|U$Z|NnIu85ly||NjqaOxk|<|KEj?fnmjm|Nm1M85pj8`2W9!k%58l<NyCl7#SFx
zKmPxJgpq+E`Q!ipPZ${(=6wABpM{Bm;p)f#|5cb67$iUa|L?-Y!0`Li|NkjW3=Gdc
z|Nq~@#K3Uz%m4pNm>3w?zyAM!go%N{|Lgz%PnZ}On!f%2&%(^W@ZkIZ|0>K34Cj9Q
z|L?-gz%b$G|Nkk>3=E*TZIG`StAZF9D+Cy&dDuB7FhayZYd9+2{r|59QsBZ4nu2Cf
zVPIe|VPIfb@b>@z1duqNfE%BL7e9A7M+1Ysl$DmT3V1pfWNr)t1H+BC|NnzEg48lV
z%mvL^UwHffe*jbrM1kz;VPIhR`0oGzY><E}pFkUvGcOxc5)V5E0|Q8Y4Fdy%&HMlV
zK_e{;F!@xlG+6!&0|SHC`~UwzbKh|Je1tqGUXtGb|8I(HehxyOhmnDy{QZB(6d}y~
zaD+T49zpV!$odNq@;;0V3=`h}|Bp*PhmnC{<@^8t!D}*L=2s*1_b@UroPGcQ|087c
znQnp=fc?+Nz|jBU|Nqx0@{i#1XBZh6qCVo5f5XVYp!(_me=}tLxnS+!@Z(`(V6gu5
z|Gx*ad_6*5hlzn9`P2XZ#-QF1%>B$-j35;t_xUg}FqD1%|33~zJ`^sW!^FU_<;(y7
z?~u)BdJ57Gw!a6IUcdhTe+Wf>CtQ9F69a?FxBvg8kmUox(jbvhJQ@O{Aut*OqaiRF
z0;3@?8UlDj0JeS(wq6dlJ`T1X4z~Ucw%!f4z74jX4Yqy_wq6akJ`J`W4b%hzIRLcg
z4@C2T2oQ!ghIv731_lNTX$V6SLc!PhL4_GWQyL&CaGM7-1PU5kW`MMZLE<p^umAq%
zgZLXjbG8f&46wCg4?uIa3=9mgHDWiQ@~|~&J3*Ql7#N_-s2M<``ye4v5P^iD+88E4
z*O!5&ib2v9AOhO12QfkG+Ca28h+tq~*Z~!QQVbuU4uiS-1T>&vYv*A0%R%+S)cyVs
z@gE}tBuM^2`5U0-{fF|Q#xZ<=@@GNie?s|uP;;qG!Pa@Bn`;1#ZwDwH0HqV4bODq`
z*GDWLw$2gKX<=Y+cXqZ?&<IT`%_}KYFf`ON)-%vGECq87>x_)_3`{hk!uV|fg(C~Y
z$N%W6K=A}x&)Ne`5YXk644`G3*wlmKk%>WoK>)h`6lNYsA4uE*P289PwCYuW0hTXe
z>OuL4kwKb40lJ<O<UWvGD5(F<AjSY&2MZDd;TotpuzU^@1K|#^dQo^j1Brp~a`3(e
zO#f~JtCwOxUq^ZnEH2IfTW1T4#`92d*m_!+_&umNY~3tO9MmUeWDsY7t&fF?{{pL*
zW^jP|_XRY(L48zEI5>bikqitlaT!Ji21W)U1_9{$d|0rmL&Xiy#Ern>;ta5LwlI5L
z!Qw&;9#Hk5c}7t91VF_TpyIIdAsQ-P0TqXpYiUsNR;V~M8!{Av#ze5BD_rTP0&I>5
zgMcc?6{r|ndTRr#mta88kNw~TBMjfS05fS3SiK~?T!V>&7Fh@}2r$6PdvKqgfq~&L
zBWPW{00XStheiX#Ij}fPH-di6h<$y29ur7h3bZK)p_qYzft?9rKCHe0<r9zsVJ6Vp
zaVZ7~XnFvNfv^-vJ(D239s!AgumVUN#6ZJg%pmj81Q{3@tikF97;>N$5x9>Is&Am;
zMbHQbk3BFjFhqjIG0g$>@dX$#{Z)xWJ*dwQ^CPlpvzZte1ev55VC5T3ZUsmjw6g)K
z30l1|YzLb!zyPbi!DB=W3=D^$;;{N1JhsHZz;F&6p3)2&;K2@<=?n~)q3Umg2J;vg
z7{Fs43=9lKP;uD)D)5*X0|Ub&s5q?NhZ*+?Dh_KWz|zk@sJ-a%$OVoU0fs1OMGqbW
zVPIh3hl<16A>gqq1_lOcs5q?M0Upy~U|`UJit|A$Qt(&|0|SF2R9ptyuz*^_5DFGY
z_#ei~WQK%4x;sn3>IE2J?IZA58v_GF6Ei41!*nC)IZ*ZOpaDS!1_oIAS<B4803Ikr
zC<U`lfYdYbfD${H4<pWj#2Ew_mVycjP`JY+f|H9%4E6FE;^PyOGUH1U(;1SBN{UNL
z)6(>k84#N};!ASllR?`#iW%bLQ}W}}bMliCbK+A<@{5Y&6H6-?lJh~s(<P}XdIs24
zfcBzf#zTgLQ}arSDjCv>5_41IQ%ZAlD;eVBk$CZ$d6^|BO2Na%py6W3@O5!XQG8x$
zPL7@hXd4S?OgyzHEipNjAt^sU2Z>uyQiQ}SH8VltC6%V7r544*M)dW}8K5FXsl}x^
zC3<EcH<jik$H(iLBA6x&py6!LST~YU@$qR8g~kYlMhK=Mf@#1|T9TQgm&_0!?-u0f
z>l*Ls=Mo>!5bqM{=jiL{%n%>%?iU*G>H(GYa0z0FclYska`cJ!cXJDN4T%qNbn<bH
zX8`#uEx#x?v4jESEhrOXmyZK%(++{{IUwUeF_>7C$`GHLl30?+0FEz={XlR7O&~-6
zu%Uc#1VQHy!1Du;eMNBPpiM*Z@gRdCdw@XkmYiFFCXc#DC_be)KRzQdF9o!J$kRW*
zxFjVr4>X;S0@581^)o0fAe^3;0&y28mLO9SAQm{jpz1-v1y>)RR9p;o5GZv)(hp2w
zacU7*BTO~ekB|fmG8AHbZhlH>PJVoGX;N`XQDSmQW_}(6bTbv2=R$m)q0tRar7%;$
zyQZ*ig#z0L4O8%(4C<aPRO3Ne2JCeP2EF3S+>*p32EF2vA_$!UV`b)*q!tx0=;h^?
zr0S*TmFg7~<rjdwi6oR%nwgWLo0$R?a&+?41r-Zm<r#^^84P+Um3hULxe&Ufhyg59
zmReK{@;fpozKB7uC^aV$qyfq*$SGma1G`nPAg4qxJ->tj%qUJxX3#51ttes8OUum5
zWY8<h2PGB;z0?e7$&is!gy2EUhzCaoL<fuw(gm_quP7hvz{K3lWClHuD1%-SXg)4E
zKQ}iu4>X4YD*`E@LDd1MX$0%f;o8p&vje0S#s<;Kpf(G*tqtNaFu?Ya!e|4CFr0+-
z=U@V$dJEJygxQb2j}<iE1XBy5Vf8(T4Z@&)0kVErzXV1@n+YJLV2rLmoPmMi+yDRh
zF#BQsXBZ8$AJ%_HcYh+Z?+nuq>tDlY4rqXZ+z4XA^h2v>2GIUKP}3f!AJ$)o(XjqG
z*zw>#0gMHq3mF&~Kz(1Bepr7OMnju1@cutc9gMDHU|<0CrD1$ne;P)^nw#kEhuF@*
z&<pN2f%<F^5m^5oM#K8|=-~(R|8%H+Cx~|VcmZtOpaLom(hq8yqKDr?XqbTH!AfBr
z87K`(-(Yblfgb;$C2gR1f$3L(>VwhXIZmiv5CxTn@8bmZ8<F)lKo!7fC>Nv^jA48j
zy#dYr6QB|>8hMTsWB^neZa*k}AlnaXpTg)c*gy|RGjwk$lnJKxquCD|kAl&#{v22_
zG_GK55PcM?AC`XLn~|XzuM6ZjkU}VixgW}9IE$tq*S>O?di40aji%oN+NgxlXW$Nl
zm;g&Z5FP`=Qw9bG(3lV?4}!#C`)pzR&e7Gw_%Qk-sErQY9}dzF8;9_Ko&x|=2a*F}
z7#~Leg}NVRKWsc90IDBX{DaH_VJ=3<*d9zjtltYehX8io04V>0)WhtB#lvbe`(fjI
z6ZAo<85qEOMj%Wu3DXawg~9!2(9UJBG@?HXE%;&i94ZSLyn}HV7#Jj>19~v`!^U?c
zp!zvr7D4qulNFT5z#s>;AF3QK4%4p<7lANf$q|`GOCn%}9#8`hKnn)YI2LFq1Lho<
zzc`WN9;^{caF|0Fmth`*aKUGEK$&0)G){x21T22r3QRG8#%~}j2nlmHgvY=D0FOXj
A`~Uy|

-- 
GitLab


From 427ee8f328e16521aa18d3778f9b769c417a5fba Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 12:29:11 +0000
Subject: [PATCH 17/69] ignore new bin

---
 .gitignore | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/.gitignore b/.gitignore
index 8110229..dd136f4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,5 @@ obj
 *.swp
 *.swo
 .vscode
+doc/test_main_ex
+doc/info_reader_ex
-- 
GitLab


From fb5106fc764e64a741fe9a5e97e67e4184fb1f09 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 6 Feb 2023 10:04:56 +0000
Subject: [PATCH 18/69] fix: NB_MAX cpu

---
 doc/info_reader_ex.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/info_reader_ex.c b/doc/info_reader_ex.c
index 23ee7d5..5cfa5f4 100644
--- a/doc/info_reader_ex.c
+++ b/doc/info_reader_ex.c
@@ -22,7 +22,7 @@
 // ~/mojitos/doc/$ gcc -Wall -Wextra -Wpedantic -O3 -o info_reader_ex info_reader_ex.c ./../src/util.c && ./info_reader_ex
 #include "./../src/info_reader.h"
 
-#define MAX_PROCS 2
+#define MAX_PROCS 64 
 #define NB_KEYS 6
 
 typedef struct {
-- 
GitLab


From 844433049c8f02aab7238679b6d052d2f84aa0ff Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 6 Feb 2023 10:05:38 +0000
Subject: [PATCH 19/69] core: amd_rapl.c

---
 src/amd_rapl.c   | 92 ++++++++++++++++++++++++++++++++++++------------
 tests/amd_rapl.c | 34 +++---------------
 2 files changed, 74 insertions(+), 52 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 51df298..f6eff43 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -30,6 +30,7 @@
 #include "util.h"
 
 #define BUFFER_SIZE 64
+#define __READ_CPUINFO__
 
 // ---------------------------MSR_REGISTERS
 static const uint64_t amd_energy_mask = 0xFFFFFFFF;
@@ -62,11 +63,9 @@ typedef struct _amd_rapl_t _amd_rapl_t;
 // -----------------------------INFO_READER
 
 #ifdef __READ_CPUINFO__
-#warning "Must be modified before release"
-#define MAX_CPUS 64
 #define NB_KEYS 3
 
-static const char *cpuinfo = "/proc/cpuinfo";
+static char *cpuinfo = "/proc/cpuinfo";
 
 static GenericPointer uint_allocator(char *s)
 {
@@ -97,6 +96,21 @@ static KeyFinder keys[NB_KEYS] = {
     {"physical id", ": ", uint_allocator, _set_package_id},
     {"core id", ": ", uint_allocator, _set_core_id}
 };
+
+
+static unsigned int parse_cpuinfo(cpu_sensor_t* storage, unsigned int capacity) {
+    Parser parser = {
+        .storage = (GenericPointer) storage,
+        .nb_stored = 0,
+        .capacity = capacity,
+        .storage_struct_size = sizeof(cpu_sensor_t),
+        .keys = keys,
+        .nb_keys = NB_KEYS,
+        .file = fopen(cpuinfo, "r")
+    };
+    return parse(&parser);
+}
+
 #endif
 
 // --------------------------------READ_MSR
@@ -159,13 +173,14 @@ uint64_t raw_to_joule(uint64_t raw, uint64_t unit)
 void debug_print_sensor(cpu_sensor_t *sensor)
 {
     //CASSERT(sizeof(cpu_sensor_t) == 56, amd_rapl_c);
-    printf("cpu_id : %d, package_id : %d, name : %s, fd: %d,  energy_units : %d, core_energy: %ld\n",
+    printf("cpu_id : %d, package_id : %d, core_id : %d, name : %s, fd: %d,  energy_units : %d, core_energy: %ld\n",
            sensor->cpu_id,
            sensor->package_id,
+           sensor->core_id,
            sensor->name,
            sensor->fd,
            sensor->energy_units,
-           sensor->core_energy,
+           sensor->core_energy
           );
 }
 
@@ -197,6 +212,22 @@ unsigned int get_nb_cpu()
     return n_cpu;
 }
 
+void get_arch(unsigned int *ret_nb_package, unsigned int *ret_nb_core, cpu_sensor_t *sensors, unsigned int nb_sensor)
+{
+    unsigned int nb_package = 0;
+    unsigned int nb_core = 0;
+    for (unsigned int i = 0; i < nb_sensor; i++) {
+        if (sensors[i].package_id > nb_package) {
+            nb_package = sensors[i].package_id;
+        }
+        if (sensors[i].core_id > nb_core) {
+            nb_core = sensors[i].core_id;
+        }
+    }
+    *ret_nb_package = nb_package + 1;
+    *ret_nb_core = nb_core + 1;
+}
+
 char *get_name(unsigned int cpu_id)
 {
     static const char *base_name = "core%d";
@@ -216,27 +247,29 @@ void update_cpu_sensor(cpu_sensor_t *sensor, uint64_t *energy_consumed)
     sensor->core_energy = core_energy;
 }
 
-unsigned int init_cpu_sensor(cpu_sensor_t *sensor, unsigned int cpu_id, unsigned char *cpus_map, unsigned int max_cpus)
-{
-    if (cpus_map[sensor->core_id * max_cpus + sensor->package_id] > 0) {
-        return 0;
+unsigned int is_duplicate(cpu_sensor_t *sensor, unsigned char map[], unsigned int nb_core) {
+    if (map[sensor->core_id * nb_core + sensor->package_id]) {
+        return 1;
     }
-    cpus_map[sensor->core_id * max_cpus + sensor->package_id] += 1;
+    map[sensor->core_id * nb_core + sensor->package_id] += 1;
+    return 0;
+}
 
+void init_cpu_sensor(cpu_sensor_t *sensor, cpu_sensor_t *cpu_info)
+{
     static char filename[BUFFER_SIZE];
-    sprintf(filename, base_str, cpu_id);
+    snprintf(filename,BUFFER_SIZE, base_str, cpu_info->cpu_id);
 
     int fd = open(filename, O_RDONLY);
     if (fd < 0) {
-        fprintf(stderr, base_str, cpu_id);
+        fprintf(stderr, base_str, cpu_info->cpu_id);
         perror(":open()");
         exit(127);
     }
 
-    sensor->cpu_id = cpu_id;
-    sensor->name = get_name(cpu_id);
+    memcpy(sensor, cpu_info, sizeof(cpu_sensor_t));
+    sensor->name = get_name(sensor->cpu_id);
     sensor->fd = fd;
-    return 1;
 }
 
 void clean_cpu_sensor(cpu_sensor_t *sensor)
@@ -256,7 +289,6 @@ void free_amd_rapl(_amd_rapl_t *rapl)
 unsigned int init_amd_rapl(char *none, void **ptr)
 {
     UNUSED(none);
-    _amd_rapl_t *rapl = (_amd_rapl_t *) calloc(1, sizeof(_amd_rapl_t));
 
     unsigned int max_cpus = get_nb_cpu();
     if (max_cpus == 0) {
@@ -265,18 +297,32 @@ unsigned int init_amd_rapl(char *none, void **ptr)
         exit(127);
     }
 
-    unsigned char *cpus_map = calloc(max_cpus * max_cpus, sizeof(unsigned char));
-    cpu_sensor_t *cpus = (cpu_sensor_t *) calloc(max_cpus, sizeof(cpu_sensor_t));
-    rapl->sensors = cpus;
+    cpu_sensor_t *cpu_information = (cpu_sensor_t *) calloc(max_cpus, sizeof(cpu_sensor_t));
+    if (parse_cpuinfo(cpu_information, max_cpus)) {
+        free(cpu_information);
+        PANIC(1, "cpuinfo");
+    }
 
-    unsigned int nb_cpu = 0;
+    unsigned int nb_package;
+    unsigned int nb_core;
+    get_arch(&nb_package, &nb_core, cpu_information, max_cpus);
+
+    unsigned char *cpu_map = (unsigned char*) calloc(nb_core * nb_package, sizeof(unsigned char));
+    cpu_sensor_t *sensors = (cpu_sensor_t*) calloc(max_cpus, sizeof(cpu_sensor_t));
+
+    unsigned int sensor_count = 0;
     for (unsigned int i = 0; i < max_cpus; i++) {
-        nb_cpu += init_cpu_sensor(&rapl->sensors[nb_cpu], i, cpus_map, max_cpus);
+        if (!is_duplicate(cpu_information, cpu_map, nb_core)) {
+            init_cpu_sensor(&sensors[sensor_count],&cpu_information[i]);
+            sensor_count += 1;
+        }
     }
-    rapl->sensor_count = nb_cpu;
+    free(cpu_information);
 
+    _amd_rapl_t *rapl = (_amd_rapl_t *) calloc(1, sizeof(_amd_rapl_t));
+    rapl->sensors = sensors;
+    rapl->sensor_count = sensor_count;
     *ptr = (void *) rapl;
-    free(cpus_map);
     return rapl->sensor_count;
 }
 
diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index 39214fc..2425287 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -179,48 +179,24 @@ TFUNCTION(test_label_amd_rapl, {
     TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
 })
 
-TFUNCTION(test_init_cpu_sensor, {
-    static const unsigned int max_cpus = 10;
-    unsigned char cpus_map[max_cpus * max_cpus];
-    cpu_sensor_t sensor_t1;
-    unsigned int result;
-    unsigned int expected;
-
-    // Test 1:
-    // -- Setup
-    memset(cpus_map, 0, max_cpus *max_cpus * sizeof(unsigned char));
-    result = 0;
-    expected = 1;
-    memset(&sensor_t1, 0, sizeof(cpu_sensor_t));
-    sensor_t1.cpu_id = 1;
-    sensor_t1.core_id = 0;
-    sensor_t1.package_id = 0;
-    // -- Run
-    result = init_cpu_sensor(&sensor_t1, 0, cpus_map, max_cpus);
-    // -- Verification
-    TEST_UINT64_T(&result, &expected);
-})
-
 TFILE_ENTRY_POINT(test_amd_rapl, {
     CALL_TFUNCTION(test_raw_to_microjoule);
     CALL_TFUNCTION(test_get_name);
     CALL_TFUNCTION(test_label_amd_rapl);
-    // CALL_TFUNCTION(test_init_cpu_sensor);
 })
 
 #ifdef __TESTING__AMD__
 int main()
 {
-    test_amd_rapl();
     static const unsigned int time = 10;
     _amd_rapl_t *rapl = NULL;
-    unsigned int nb_cpu = init_amd_rapl(NULL, (void **) &rapl);
-    uint64_t results[nb_cpu];
-    char *labels[nb_cpu];
+    unsigned int count_cpu = init_amd_rapl(NULL, (void **) &rapl);
+    uint64_t results[count_cpu];
+    char *labels[count_cpu];
 
     label_amd_rapl(labels, (void *) rapl);
 
-    for (unsigned int i = 0; i < rapl->nb; ++i) {
+    for (unsigned int i = 0; i < rapl->sensor_count; ++i) {
         printf("%s ", labels[i]);
     }
     printf("\n");
@@ -231,7 +207,7 @@ int main()
         sleep(1);
         get_amd_rapl(results, (void *)rapl);
 
-        for (unsigned int j = 0; j < rapl->nb; ++j) {
+        for (unsigned int j = 0; j < rapl->sensor_count; ++j) {
             printf("%ld ", results[j]);
         }
         printf("\n");
-- 
GitLab


From 76653cfafb1f60a31791a761fcd41d5c54b6b9c4 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 6 Feb 2023 11:47:35 +0000
Subject: [PATCH 20/69] core: small_test modification of the api

---
 doc/info_reader_ex.c |   2 +-
 doc/test_file_ex.c   |  31 ++++++++----
 src/amd_rapl.c       |  14 +++---
 tests/amd_rapl.c     | 116 ++++++++++++++++++++++++++++++++++++++----
 tests/small_test.h   | 117 +++++++++++++++++++++++++++++++++++--------
 5 files changed, 231 insertions(+), 49 deletions(-)

diff --git a/doc/info_reader_ex.c b/doc/info_reader_ex.c
index 5cfa5f4..f672d98 100644
--- a/doc/info_reader_ex.c
+++ b/doc/info_reader_ex.c
@@ -22,7 +22,7 @@
 // ~/mojitos/doc/$ gcc -Wall -Wextra -Wpedantic -O3 -o info_reader_ex info_reader_ex.c ./../src/util.c && ./info_reader_ex
 #include "./../src/info_reader.h"
 
-#define MAX_PROCS 64 
+#define MAX_PROCS 64
 #define NB_KEYS 6
 
 typedef struct {
diff --git a/doc/test_file_ex.c b/doc/test_file_ex.c
index 44ebc2c..4e3a093 100644
--- a/doc/test_file_ex.c
+++ b/doc/test_file_ex.c
@@ -35,6 +35,20 @@ TFUNCTION(test_should_fail, {
     TEST_STR(result, expected);
 })
 
+// -- A simple test of array
+TFUNCTION(test_array, {
+    static unsigned int size = 10;
+    int array[10];
+    TEST_ARRAY(TEST_INT, size, array, array);
+})
+
+// -- A simple test of array of pointer
+TFUNCTION(test_ptr_array, {
+    static unsigned int size = 10;
+    void *array[10];
+    TEST_PTR_ARRAY(TEST_PTR, size, array, array);
+})
+
 // -- Add a new type in the test framework
 
 typedef struct {
@@ -89,24 +103,21 @@ TFUNCTION(test_user_type, {
 
 // -- Compare an array of usetype
 TFUNCTION(test_array_user_type, {
-    UserType *results[1];
-    UserType *expecteds[1];
-
-    UserType x1;
-    UserType x2;
-    DUMMY_USER_TYPE(x1, 1, "John Doe");
-    DUMMY_USER_TYPE(x2, 1, "John Doe");
+    UserType results[1];
+    UserType expecteds[1];
 
-    results[0] = &x1;
-    expecteds[0] = &x2;
+    DUMMY_USER_TYPE(results[0], 1, "John Doe");
+    DUMMY_USER_TYPE(expecteds[0], 1, "John Doe");
 
-    TEST_T_ARRAY(TEST_USER_TYPE, 1, (void **)results, (void **)expecteds);
+    TEST_ARRAY(TEST_USER_TYPE, 1, results, expecteds);
 })
 
 // Define the entry point of a test file
 TFILE_ENTRY_POINT(test_file_ex, {
     CALL_TFUNCTION(test_should_pass);
     CALL_TFUNCTION(test_should_fail);
+    CALL_TFUNCTION(test_array);
+    CALL_TFUNCTION(test_ptr_array);
     CALL_TFUNCTION(test_user_type);
     CALL_TFUNCTION(test_array_user_type);
 })
diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index f6eff43..1d9bc37 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -98,7 +98,8 @@ static KeyFinder keys[NB_KEYS] = {
 };
 
 
-static unsigned int parse_cpuinfo(cpu_sensor_t* storage, unsigned int capacity) {
+static unsigned int parse_cpuinfo(cpu_sensor_t *storage, unsigned int capacity)
+{
     Parser parser = {
         .storage = (GenericPointer) storage,
         .nb_stored = 0,
@@ -247,12 +248,13 @@ void update_cpu_sensor(cpu_sensor_t *sensor, uint64_t *energy_consumed)
     sensor->core_energy = core_energy;
 }
 
-unsigned int is_duplicate(cpu_sensor_t *sensor, unsigned char map[], unsigned int nb_core) {
+unsigned int is_duplicate(cpu_sensor_t *sensor, unsigned char map[], unsigned int nb_core)
+{
     if (map[sensor->core_id * nb_core + sensor->package_id]) {
-        return 1;
+        return 0;
     }
     map[sensor->core_id * nb_core + sensor->package_id] += 1;
-    return 0;
+    return 1;
 }
 
 void init_cpu_sensor(cpu_sensor_t *sensor, cpu_sensor_t *cpu_info)
@@ -307,8 +309,8 @@ unsigned int init_amd_rapl(char *none, void **ptr)
     unsigned int nb_core;
     get_arch(&nb_package, &nb_core, cpu_information, max_cpus);
 
-    unsigned char *cpu_map = (unsigned char*) calloc(nb_core * nb_package, sizeof(unsigned char));
-    cpu_sensor_t *sensors = (cpu_sensor_t*) calloc(max_cpus, sizeof(cpu_sensor_t));
+    unsigned char *cpu_map = (unsigned char *) calloc(nb_core * nb_package, sizeof(unsigned char));
+    cpu_sensor_t *sensors = (cpu_sensor_t *) calloc(max_cpus, sizeof(cpu_sensor_t));
 
     unsigned int sensor_count = 0;
     for (unsigned int i = 0; i < max_cpus; i++) {
diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index 2425287..1857a6a 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -116,15 +116,15 @@ do {                                             \
     .energy_units = NONE,                        \
     .core_energy = NONE,                         \
   };                                             \
-	} while(0);
+} while(0);
 
 #define DUMMY_RAPL(__rapl, __sensors, __sensors_count) \
-	do {                                                 \
-		__rapl = (_amd_rapl_t) {                           \
-			.sensors = __sensors,                            \
-			.sensor_count = __sensors_count                 \
-		};                                                 \
-	} while(0);
+do {                                                   \
+    __rapl = (_amd_rapl_t) {                           \
+        .sensors = __sensors,                          \
+        .sensor_count = __sensors_count                \
+    };                                                 \
+} while(0);
 
 TFUNCTION(test_label_amd_rapl, {
     cpu_sensor_t sensors[100];
@@ -142,7 +142,7 @@ TFUNCTION(test_label_amd_rapl, {
     // -- Run
     label_amd_rapl(results, (void *) &rapl);
     // -- Verification
-    TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
+    TEST_PTR_ARRAY(TEST_STR, nb, results, expecteds);
 
     // Test 2:
     // -- Setup
@@ -159,7 +159,7 @@ TFUNCTION(test_label_amd_rapl, {
     // -- Run
     label_amd_rapl(results, (void *) &rapl);
     // -- Verification
-    TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
+    TEST_PTR_ARRAY(TEST_STR, nb, results, expecteds);
 
     // Test 3:
     // -- Setup
@@ -176,13 +176,109 @@ TFUNCTION(test_label_amd_rapl, {
     // -- Run
     label_amd_rapl(results, (void *) &rapl);
     // -- Verification
-    TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
+    TEST_PTR_ARRAY(TEST_STR, nb, results, expecteds);
 })
 
+
+#define DUMMY_CPUINFO(__sensor, __cpu_id, __package_id, __core_id) \
+do {                                                               \
+    __sensor = (cpu_sensor_t) {                                    \
+        .cpu_id = __cpu_id,                                        \
+        .package_id = __package_id,                                \
+        .core_id = __core_id,                                      \
+        .name = NULL,                                              \
+        .fd = NONE,                                                \
+        .energy_units = NONE,                                      \
+        .core_energy = NONE                                        \
+    };                                                             \
+} while (0);
+
+TFUNCTION(test_is_duplicate, {
+    static const unsigned int nb_core = 4;
+    static const unsigned int nb_package = 2;
+    static const unsigned int max_cpu = 10;
+
+    unsigned char map[nb_core * nb_package];
+    cpu_sensor_t cpu_information[max_cpu];
+    unsigned int results[2];
+    unsigned int expecteds[2];
+
+    // -- Setup
+    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
+    expecteds[0] = 1;
+    expecteds[1] = 0;
+    // -- Run
+    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
+    results[1] = is_duplicate(&cpu_information[0], map, nb_core);
+    // -- Verification
+    TEST_BOOL(&results[0], &expecteds[0]);
+    TEST_BOOL(&results[1], &expecteds[1]);
+
+    // -- Setup
+    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
+    DUMMY_CPUINFO(cpu_information[1], 0, 1, 1);
+    expecteds[0] = 1;
+    expecteds[1] = 0;
+    // -- Run
+    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
+    results[1] = is_duplicate(&cpu_information[1], map, nb_core);
+    // -- Verification
+    TEST_BOOL(&results[0], &expecteds[0]);
+    TEST_BOOL(&results[1], &expecteds[1]);
+
+    // -- Setup
+    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
+    DUMMY_CPUINFO(cpu_information[1], 0, 0, 0);
+    expecteds[0] = 1;
+    expecteds[1] = 1;
+    // -- Run
+    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
+    results[1] = is_duplicate(&cpu_information[1], map, nb_core);
+    // -- Verification
+    TEST_BOOL(&results[0], &expecteds[0]);
+    TEST_BOOL(&results[1], &expecteds[1]);
+
+    // -- Setup
+    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
+    DUMMY_CPUINFO(cpu_information[1], 0, 1, 0);
+    expecteds[0] = 1;
+    expecteds[1] = 1;
+    // -- Run
+    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
+    results[1] = is_duplicate(&cpu_information[1], map, nb_core);
+    // -- Verification
+    TEST_BOOL(&results[0], &expecteds[0]);
+    TEST_BOOL(&results[1], &expecteds[1]);
+
+    // -- Setup
+    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
+    DUMMY_CPUINFO(cpu_information[1], 0, 0, 1);
+    expecteds[0] = 1;
+    expecteds[1] = 1;
+    // -- Run
+    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
+    results[1] = is_duplicate(&cpu_information[1], map, nb_core);
+    // -- Verification
+    TEST_BOOL(&results[0], &expecteds[0]);
+    TEST_BOOL(&results[1], &expecteds[1]);
+})
+
+
 TFILE_ENTRY_POINT(test_amd_rapl, {
     CALL_TFUNCTION(test_raw_to_microjoule);
     CALL_TFUNCTION(test_get_name);
     CALL_TFUNCTION(test_label_amd_rapl);
+    CALL_TFUNCTION(test_is_duplicate);
 })
 
 #ifdef __TESTING__AMD__
diff --git a/tests/small_test.h b/tests/small_test.h
index aedc685..ef9d90b 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -33,15 +33,17 @@
 /**
  * @brief Define the entry point of the tests
  * It initializes each useful variables.
+ *
+ * @param __code The code that contains the calls to the test functions
  */
 
-#define TMAIN(code)                                              \
+#define TMAIN(__code)                                              \
   int main()                                                     \
 {                                                                \
   unsigned int __indentation_level = 0;                          \
   INDENTED_PRINT("%s:%s\n", __FILE__, __func__);                 \
   unsigned int __error_counter__ = 0;                            \
-  do code while (0);                                             \
+  do __code while (0);                                             \
   DEFERRED_FILE_ERROR(__error_counter__);                        \
   return __error_counter__;                                      \
 }
@@ -108,7 +110,6 @@
  * @def TEST_STR(result, expected)
  * @brief Test strings
  * This macro is used to test strings. It takes two arguments: `__result`, which is the string to be tested, and `__expected`, which is the expected value of the string.
- * The macro uses the `test_str()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
  *
  * @param __result the string to be tested
  * @param __expected the expected value of the string
@@ -124,23 +125,43 @@
  * @def TEST_BOOL(__result, __expected)
  * @brief Test bools
  * This macro is used to test bools. It takes two arguments: `__result`, which is the bool to be tested, and `__expected`, which is the expected value of the bool.
- * The macro uses the `test_bool()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
  *
- * @param __result the bool to be tested
- * @param __expected the expected value of the bool
+ * @param __result the pointer to bool to be tested
+ * @param __expected the pointer to the expected value of the bool
  *
  * @code
- * TEST_BOOL(1 == 1, true);
+ * bool x = true;
+ * bool y = false;
+ * TEST_BOOL(&x, &y);
  * @endcode
  */
 #define TEST_BOOL(__result, __expected) \
     do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, &bool_interface);} while (0)
 
+/**
+ * @def TEST_INT(__result, __expected)
+ * @brief Test ints
+ * This macro is used to test ints. It takes two arguments: `__result`, which is the int to be tested, and `__expected`, which is the expected value of the int.
+ *
+ * @param __result the pointer to int to be tested
+ * @param __expected the pointer to expected value of the int
+ *
+ * @code
+ * int x = 1;
+ * int y = 1;
+ * TEST_INT(&x, &y)
+ * @endcode
+ */
+#define TEST_INT(__result, __expected) \
+    do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, &int_interface);} while (0)
+
+
+
+
 /**
  * @def TEST_PTR(__result, __expected)
  * @brief Test pointers
  * This macro is used to test pointers. It takes two arguments: `__result`, which is the pointer to be tested, and `__expected`, which is the expected value of the pointer.
- * The macro uses the `test_ptr()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
  *
  * @param __result the pointer to be tested
  * @param __expected the expected value of the pointer
@@ -159,24 +180,38 @@
  * @def TEST_UINT64_T(__result, __expected)
  * @brief Test 64-bit unsigned integers
  * This macro is used to test 64-bit unsigned integers. It takes two arguments: `__result`, which is the integer to be tested, and `__expected`, which is the expected value of the integer.
- * The macro uses the `test_uint64_t()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
  *
- * @param __result the integer to be tested
- * @param __expected the expected value of the integer
+ * @param __result the pointer to integer to be tested
+ * @param __expected the pointer to expected value of the integer
  *
  * @code
- * TEST_UINT64_T(5, 5);
+ * uint64_t x = 5;
+ * uint64_t y = 5;
+ * TEST_UINT64_T(&x, &y);
  * @endcode
  */
 #define TEST_UINT64_T(__result, __expected) \
-	do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, &u64_interface);} while(0)
+    do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, &u64_interface);} while(0)
 
+/**
+ * @def TEST_INTERFACE(__result, __expected, __interface)
+ * @brief Define a macro on a usertype with the given __interface
+ * This macro is used by the user to define a new test macro on a usertype.
+ *
+ * @param __result
+ * @param __expected
+ * @param __interface the usertype interface
+ *
+ * @code
+ * #define TEST_USERTYPE(__result, __expected)
+ * TEST_INTERFACE(__result, __expected, usertype_interface)
+ * @endcode
+ */
 #define TEST_INTERFACE(__result, __expected, __interface) \
-	do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, __interface);} while(0)
-
+    do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, __interface);} while(0)
 
 /**
- * @def TEST_T_ARRAY(function, nb_error, size, results, expecteds)
+ * @def TEST_T_ARRAY(__test_macro, __size, __results, __expecteds)
  * @brief Test arrays of data
  * The macro uses a for loop to iterate through the array and apply the test function to each element.
  *
@@ -188,15 +223,33 @@
  * @code
  * int results[3] = {1, 2, 3};
  * int expecteds[3] = {1, 2, 3};
- * TEST_T_ARRAY(TEST_INT, 3, results, expecteds);
+ * TEST_ARRAY(TEST_INT, 3, results, expecteds);
  * @endcode
 */
-#define TEST_T_ARRAY(__test_macro, __array_size, __results, __expecteds)  \
-	for (unsigned int i = 0; i < __array_size; i++) {                       \
-      __test_macro(__results[i], __expecteds[i]);                         \
-	}
+#define TEST_ARRAY(__test_macro, __array_size, __results, __expecteds) \
+    for (unsigned i = 0; i < __array_size; i++) {                      \
+        __test_macro(&__results[i], &__expecteds[i]);                   \
+    }
 
+/**
+ * @def TEST_T_PTR_ARRAY(__test_macro, __array_size, __results, __expecteds)
+ * @brief Test arrays of pointer
+ * The macro uses a for loop to iterate through the array and apply the test function to each element.
+ *
+ * @param __test_macro the test function to be used on each element of the array
+ * @param __array_size the number of elements in the array
+ * @param __results the array of elements to be tested
+ * @param __expecteds the array of expected values
 
+ * @code
+ * void* array[3];
+ * TEST_PTR_ARRAY(TEST_PTR, 3, array, array);
+ * @endcode
+*/
+#define TEST_PTR_ARRAY(__test_macro, __array_size, __results, __expecteds)  \
+    for (unsigned int i = 0; i < __array_size; i++) {                     \
+      __test_macro(__results[i], __expecteds[i]);                         \
+    }
 // --------------------------------API_CODE
 // These functions should not be used, only use the previous macros.
 
@@ -261,7 +314,6 @@ static const TestInterface str_interface = {
 
 //  --------------------------bool_interface
 
-
 int bool_compare(void *ptr1, void *ptr2)
 {
     bool *bool1 = (bool *) ptr1;
@@ -281,6 +333,27 @@ static const TestInterface bool_interface = {
     .format = bool_format
 };
 
+// ---------------------------int_interface
+
+int int_compare(void *ptr1, void *ptr2)
+{
+    int *int1 = (int *) ptr1;
+    int *int2 = (int *) ptr2;
+    return *int1 == *int2;
+}
+
+char *int_format(char buffer[1000], void *ptr)
+{
+    int *_int = (int *) ptr;
+    snprintf(buffer, 1000, "%d", *_int);
+    return buffer;
+}
+
+static const TestInterface int_interface = {
+    .compare = int_compare,
+    .format = int_format
+};
+
 // ---------------------------ptr_interface
 
 int ptr_compare(void *ptr1, void *ptr2)
-- 
GitLab


From bab4a95c8dccf445cb0bb359fc8dfe9b8eee0d59 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 6 Feb 2023 12:09:00 +0000
Subject: [PATCH 21/69] fix: is_duplicate

---
 src/amd_rapl.c   |  2 +-
 tests/amd_rapl.c | 24 ++++++++++++++++++++++--
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 1d9bc37..0c363af 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -314,7 +314,7 @@ unsigned int init_amd_rapl(char *none, void **ptr)
 
     unsigned int sensor_count = 0;
     for (unsigned int i = 0; i < max_cpus; i++) {
-        if (!is_duplicate(cpu_information, cpu_map, nb_core)) {
+        if (is_duplicate(cpu_information, cpu_map, nb_core) == 1) {
             init_cpu_sensor(&sensors[sensor_count],&cpu_information[i]);
             sensor_count += 1;
         }
diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index 1857a6a..f2d13ef 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -200,8 +200,8 @@ TFUNCTION(test_is_duplicate, {
 
     unsigned char map[nb_core * nb_package];
     cpu_sensor_t cpu_information[max_cpu];
-    unsigned int results[2];
-    unsigned int expecteds[2];
+    unsigned int results[max_cpu];
+    unsigned int expecteds[max_cpu];
 
     // -- Setup
     memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
@@ -271,6 +271,26 @@ TFUNCTION(test_is_duplicate, {
     // -- Verification
     TEST_BOOL(&results[0], &expecteds[0]);
     TEST_BOOL(&results[1], &expecteds[1]);
+    
+    // -- Setup
+    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    DUMMY_CPUINFO(cpu_information[0], 0, 0, 0);
+    DUMMY_CPUINFO(cpu_information[1], 0, 0, 1);
+    DUMMY_CPUINFO(cpu_information[2], 0, 1, 0);
+    DUMMY_CPUINFO(cpu_information[3], 0, 1, 1);
+    DUMMY_CPUINFO(cpu_information[4], 0, 0, 0);
+    DUMMY_CPUINFO(cpu_information[5], 0, 0, 1);
+    DUMMY_CPUINFO(cpu_information[6], 0, 1, 0);
+    DUMMY_CPUINFO(cpu_information[7], 0, 1, 1);
+    memset(expecteds, 1, sizeof(unsigned int) * 4);
+    memset(&expecteds[4], 0, sizeof(unsigned int) * 4);
+    // -- Run
+    for (unsigned int i = 0; i < 8; i++) {
+        results[i] = is_duplicate(&cpu_information[i], map, nb_core);
+    }
+    // -- Verification
+    TEST_ARRAY(TEST_BOOL, 8, results, expecteds);
 })
 
 
-- 
GitLab


From a1cded04769e4d1c90e9b370419026e8c296b8e3 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 6 Feb 2023 12:15:20 +0000
Subject: [PATCH 22/69] fix: init_amd_rapl

---
 src/amd_rapl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 0c363af..888df5a 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -314,7 +314,7 @@ unsigned int init_amd_rapl(char *none, void **ptr)
 
     unsigned int sensor_count = 0;
     for (unsigned int i = 0; i < max_cpus; i++) {
-        if (is_duplicate(cpu_information, cpu_map, nb_core) == 1) {
+        if (is_duplicate(&cpu_information[i], cpu_map, nb_core) == 1) {
             init_cpu_sensor(&sensors[sensor_count],&cpu_information[i]);
             sensor_count += 1;
         }
-- 
GitLab


From 00600d4ad379584817de4a5cdabaeb78a8206a1c Mon Sep 17 00:00:00 2001
From: Floreal Risso <frisso@grue-2.nancy.grid5000.fr>
Date: Mon, 6 Feb 2023 13:54:44 +0100
Subject: [PATCH 23/69] fix is_duplicate

---
 src/amd_rapl.c   | 11 ++++++-----
 tests/amd_rapl.c | 36 ++++++++++++++++++------------------
 2 files changed, 24 insertions(+), 23 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 888df5a..805e698 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -248,12 +248,12 @@ void update_cpu_sensor(cpu_sensor_t *sensor, uint64_t *energy_consumed)
     sensor->core_energy = core_energy;
 }
 
-unsigned int is_duplicate(cpu_sensor_t *sensor, unsigned char map[], unsigned int nb_core)
+unsigned int is_duplicate(cpu_sensor_t *sensor,unsigned int nb_core, unsigned int nb_package, unsigned char map[nb_core][nb_package])
 {
-    if (map[sensor->core_id * nb_core + sensor->package_id]) {
+    if (map[sensor->core_id][sensor->package_id] == 1) {
         return 0;
     }
-    map[sensor->core_id * nb_core + sensor->package_id] += 1;
+    map[sensor->core_id][sensor->package_id] += 1;
     return 1;
 }
 
@@ -309,12 +309,13 @@ unsigned int init_amd_rapl(char *none, void **ptr)
     unsigned int nb_core;
     get_arch(&nb_package, &nb_core, cpu_information, max_cpus);
 
-    unsigned char *cpu_map = (unsigned char *) calloc(nb_core * nb_package, sizeof(unsigned char));
+    unsigned char cpu_map[nb_core][nb_package];
+    memset(cpu_map, 0, sizeof(cpu_map));
     cpu_sensor_t *sensors = (cpu_sensor_t *) calloc(max_cpus, sizeof(cpu_sensor_t));
 
     unsigned int sensor_count = 0;
     for (unsigned int i = 0; i < max_cpus; i++) {
-        if (is_duplicate(&cpu_information[i], cpu_map, nb_core) == 1) {
+        if (is_duplicate(&cpu_information[i], nb_core, nb_package, cpu_map) == 1) {
             init_cpu_sensor(&sensors[sensor_count],&cpu_information[i]);
             sensor_count += 1;
         }
diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index f2d13ef..09ac0d9 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -198,82 +198,82 @@ TFUNCTION(test_is_duplicate, {
     static const unsigned int nb_package = 2;
     static const unsigned int max_cpu = 10;
 
-    unsigned char map[nb_core * nb_package];
+    unsigned char map[nb_core][nb_package];
     cpu_sensor_t cpu_information[max_cpu];
     unsigned int results[max_cpu];
     unsigned int expecteds[max_cpu];
 
     // -- Setup
-    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(map, NONE, sizeof(map));
     memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
     expecteds[0] = 1;
     expecteds[1] = 0;
     // -- Run
-    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
-    results[1] = is_duplicate(&cpu_information[0], map, nb_core);
+    results[0] = is_duplicate(&cpu_information[0], nb_core, nb_package,map);
+    results[1] = is_duplicate(&cpu_information[0], nb_core, nb_package,map);
     // -- Verification
     TEST_BOOL(&results[0], &expecteds[0]);
     TEST_BOOL(&results[1], &expecteds[1]);
 
     // -- Setup
-    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(map, NONE, sizeof(map));
     memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
     DUMMY_CPUINFO(cpu_information[1], 0, 1, 1);
     expecteds[0] = 1;
     expecteds[1] = 0;
     // -- Run
-    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
-    results[1] = is_duplicate(&cpu_information[1], map, nb_core);
+    results[0] = is_duplicate(&cpu_information[0], nb_core, nb_package, map);
+    results[1] = is_duplicate(&cpu_information[1], nb_core, nb_package, map);
     // -- Verification
     TEST_BOOL(&results[0], &expecteds[0]);
     TEST_BOOL(&results[1], &expecteds[1]);
 
     // -- Setup
-    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(map, NONE, sizeof(map));
     memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
     DUMMY_CPUINFO(cpu_information[1], 0, 0, 0);
     expecteds[0] = 1;
     expecteds[1] = 1;
     // -- Run
-    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
-    results[1] = is_duplicate(&cpu_information[1], map, nb_core);
+    results[0] = is_duplicate(&cpu_information[0], nb_core, nb_package, map);
+    results[1] = is_duplicate(&cpu_information[1], nb_core, nb_package, map);
     // -- Verification
     TEST_BOOL(&results[0], &expecteds[0]);
     TEST_BOOL(&results[1], &expecteds[1]);
 
     // -- Setup
-    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(map, NONE, sizeof(map));
     memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
     DUMMY_CPUINFO(cpu_information[1], 0, 1, 0);
     expecteds[0] = 1;
     expecteds[1] = 1;
     // -- Run
-    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
-    results[1] = is_duplicate(&cpu_information[1], map, nb_core);
+    results[0] = is_duplicate(&cpu_information[0], nb_core, nb_package, map);
+    results[1] = is_duplicate(&cpu_information[1], nb_core, nb_package, map);
     // -- Verification
     TEST_BOOL(&results[0], &expecteds[0]);
     TEST_BOOL(&results[1], &expecteds[1]);
 
     // -- Setup
-    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(map, NONE, sizeof(map));
     memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
     DUMMY_CPUINFO(cpu_information[1], 0, 0, 1);
     expecteds[0] = 1;
     expecteds[1] = 1;
     // -- Run
-    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
-    results[1] = is_duplicate(&cpu_information[1], map, nb_core);
+    results[0] = is_duplicate(&cpu_information[0], nb_core, nb_package, map);
+    results[1] = is_duplicate(&cpu_information[1], nb_core, nb_package, map);
     // -- Verification
     TEST_BOOL(&results[0], &expecteds[0]);
     TEST_BOOL(&results[1], &expecteds[1]);
     
     // -- Setup
-    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(map, NONE, sizeof(map));
     memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 0, 0);
     DUMMY_CPUINFO(cpu_information[1], 0, 0, 1);
@@ -287,7 +287,7 @@ TFUNCTION(test_is_duplicate, {
     memset(&expecteds[4], 0, sizeof(unsigned int) * 4);
     // -- Run
     for (unsigned int i = 0; i < 8; i++) {
-        results[i] = is_duplicate(&cpu_information[i], map, nb_core);
+        results[i] = is_duplicate(&cpu_information[i], nb_core, nb_package, map );
     }
     // -- Verification
     TEST_ARRAY(TEST_BOOL, 8, results, expecteds);
-- 
GitLab


From 851cef1b09b4bf468aed0e11ca8c6cba31826067 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 6 Feb 2023 16:39:07 +0000
Subject: [PATCH 24/69] fix: add ifndef

---
 src/info_reader.h | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/src/info_reader.h b/src/info_reader.h
index 1696ede..e83b2c3 100644
--- a/src/info_reader.h
+++ b/src/info_reader.h
@@ -1,3 +1,26 @@
+/*******************************************************
+ 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/>.
+
+*******************************************************/
+
+#ifndef _INFO_READER_H
+#define _INFO_READER_
+
 #include <string.h>
 #include <stdbool.h>
 #include <stdio.h>
@@ -216,3 +239,5 @@ static bool start_with(const char *prefix, const char *string)
     }
 }
 
+#endif
+
-- 
GitLab


From 5e505cc72bb11a4a119527a21c80b6d208fffdbb Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 6 Feb 2023 16:49:39 +0000
Subject: [PATCH 25/69] fix: add safety

---
 doc/test_file_ex.c |  4 ++--
 tests/small_test.h | 24 +++++++++++++-----------
 2 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/doc/test_file_ex.c b/doc/test_file_ex.c
index 4e3a093..13e1f48 100644
--- a/doc/test_file_ex.c
+++ b/doc/test_file_ex.c
@@ -63,10 +63,10 @@ int usertype_compare(void *ptr1, void *ptr2)
     return memcmp(ptr1, ptr2, sizeof(UserType)) == 0;
 }
 
-char *usertype_format(char buffer[1000], void *ptr)
+char *usertype_format(char buffer[FMT_BUFFER_SIZE], void *ptr)
 {
     UserType *x = (UserType *) ptr;
-    sprintf(buffer, "UserType {simple_int: %d, simple_str: %s}", x->simple_int, x->simple_str);
+    snprintf(buffer, FMT_BUFFER_SIZE, "UserType {simple_int: %d, simple_str: %s}", x->simple_int, x->simple_str);
     return buffer;
 }
 
diff --git a/tests/small_test.h b/tests/small_test.h
index ef9d90b..eddbdb0 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -29,6 +29,8 @@
 
 #include "../src/util.h"
 
+#define FMT_BUFFER_SIZE 1000
+
 // ---------------------------API_INTERFACE
 /**
  * @brief Define the entry point of the tests
@@ -276,7 +278,7 @@
     INDENTED_PRINT("|_Deferred Error : %d\n",nb_error);
 
 typedef int (Comparator) (void *, void *);
-typedef char *(Formatter) (char *, void *);
+typedef char *(Formatter) (char[FMT_BUFFER_SIZE], void *);
 
 typedef struct {
     Comparator *compare;
@@ -299,7 +301,7 @@ int str_compare(void *ptr1, void *ptr2)
     }
 }
 
-char *str_format(char *buffer, void *ptr)
+char *str_format(char buffer[FMT_BUFFER_SIZE], void *ptr)
 {
     UNUSED(buffer);
     static char *str_null = "NULL";
@@ -321,7 +323,7 @@ int bool_compare(void *ptr1, void *ptr2)
     return *bool1 == *bool2;
 }
 
-char *bool_format(char *buffer, void *ptr)
+char *bool_format(char buffer[FMT_BUFFER_SIZE], void *ptr)
 {
     UNUSED(buffer);
     bool *_bool = (bool *) ptr;
@@ -342,10 +344,10 @@ int int_compare(void *ptr1, void *ptr2)
     return *int1 == *int2;
 }
 
-char *int_format(char buffer[1000], void *ptr)
+char *int_format(char buffer[FMT_BUFFER_SIZE], void *ptr)
 {
     int *_int = (int *) ptr;
-    snprintf(buffer, 1000, "%d", *_int);
+    snprintf(buffer, FMT_BUFFER_SIZE, "%d", *_int);
     return buffer;
 }
 
@@ -361,9 +363,9 @@ int ptr_compare(void *ptr1, void *ptr2)
     return ptr1 == ptr2;
 }
 
-char *ptr_format(char *buffer, void *ptr)
+char *ptr_format(char buffer[FMT_BUFFER_SIZE], void *ptr)
 {
-    sprintf(buffer, "%p", ptr);
+    snprintf(buffer, FMT_BUFFER_SIZE, "%p", ptr);
     return buffer;
 }
 
@@ -381,10 +383,10 @@ int u64_compare(void *ptr1, void *ptr2)
     return *v1 == *v2;
 }
 
-char *u64_format(char *buffer, void *ptr)
+char *u64_format(char buffer[FMT_BUFFER_SIZE], void *ptr)
 {
     uint64_t *v = (uint64_t *) ptr;
-    sprintf(buffer, "%"PRIu64"", *v);
+    snprintf(buffer, FMT_BUFFER_SIZE, "%"PRIu64"", *v);
     return buffer;
 }
 
@@ -398,8 +400,8 @@ static const TestInterface u64_interface = {
 int test(char *file, int line, unsigned int __indentation_level, void *result, void *expected, const TestInterface *interface)
 {
     __indentation_level += 1;
-    static char buffer_result[1000];
-    static char buffer_expected[1000];
+    static char buffer_result[FMT_BUFFER_SIZE];
+    static char buffer_expected[FMT_BUFFER_SIZE];
     int is_equal = interface->compare(result, expected);
 
     char *fmt_result = interface->format(buffer_expected, expected);
-- 
GitLab


From 9b9a4c4206947e9cd6180cd1071441911a3783ba Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 7 Feb 2023 07:55:33 +0000
Subject: [PATCH 26/69] fix: documentation

---
 doc/test_file_ex.c |  93 +++++++++++++++--------
 doc/test_main_ex.c |   3 +-
 tests/amd_rapl.c   |  26 +++++--
 tests/small_test.h | 183 +++++++++++++++++++--------------------------
 4 files changed, 163 insertions(+), 142 deletions(-)

diff --git a/doc/test_file_ex.c b/doc/test_file_ex.c
index 13e1f48..95baaa7 100644
--- a/doc/test_file_ex.c
+++ b/doc/test_file_ex.c
@@ -20,49 +20,70 @@
 
 // Include of the test library
 #include "./../tests/small_test.h"
+// Include the file that contains the function you want to test 
+// #include "a_file.c"
 
-// -- A simple function that should pass
+// This example is divided into three parts:
+// 1. SOME SIMPLE EXAMPLES
+// 2. A MORE COMPLEX EXAMPLE
+// 3. FILE ENTRY POINT
+
+//  -----------------1. SOME SIMPLE EXAMPLES
+
+// A simple function that should pass
+// test_should_pass is the name of the function
+// {} is the function code
+// Use one of the define TEST_XXX defined in small_test.h
 TFUNCTION(test_should_pass, {
-    char *result = "It's going to pass";
-    char *expected = "It's going to pass";
-    TEST_STR(result, expected);
+    int result = 42;
+    int expected = 42;
+    TEST_INT(&result, &expected);
 })
 
-// -- A simple function that should fail
+// A simple function that should pass
+// test_should_fail is the name of the function
+// {} is the function code
+// Use one of the define TEST_XXX defined in small_test.h
 TFUNCTION(test_should_fail, {
     char *result = "a fail";
     char *expected = "a nice fail";
     TEST_STR(result, expected);
 })
 
-// -- A simple test of array
+// A simple test on an array
+// test_array is the name of the function
+// {} is the function code
+// Use one of the define TEST_XXX defined in small_test.h
 TFUNCTION(test_array, {
     static unsigned int size = 10;
-    int array[10];
-    TEST_ARRAY(TEST_INT, size, array, array);
+    int results[10] = {0};
+    int expecteds[10] = {0};
+    for (unsigned int i = 0; i < size; i++) {
+        TEST_INT(&results[i], &expecteds[i]);
+    }
 })
 
-// -- A simple test of array of pointer
-TFUNCTION(test_ptr_array, {
-    static unsigned int size = 10;
-    void *array[10];
-    TEST_PTR_ARRAY(TEST_PTR, size, array, array);
-})
+// See "TFILE_ENTRY_POINT" for how to call these functions.
 
-// -- Add a new type in the test framework
+// ------------2. THE MORE COMPLEX EXAMPLE
+// This example shows how to add a new type to the framework
 
+// The type that you want to add :
 typedef struct {
     int simple_int;
     char simple_str[20];
 } UserType;
 
 
-// -- Implemet the interface
+// The test framework needs two functions :
+
+// A function that compares two values.
 int usertype_compare(void *ptr1, void *ptr2)
 {
     return memcmp(ptr1, ptr2, sizeof(UserType)) == 0;
 }
 
+// A function to format a value.
 char *usertype_format(char buffer[FMT_BUFFER_SIZE], void *ptr)
 {
     UserType *x = (UserType *) ptr;
@@ -70,17 +91,18 @@ char *usertype_format(char buffer[FMT_BUFFER_SIZE], void *ptr)
     return buffer;
 }
 
-// Create a variable which contains the functions
+// Store the functions in the interface type.
 static const TestInterface usertype_interface = {
     .compare = usertype_compare,
     .format = usertype_format
 };
 
-// -- Create the test macro to call
+// Create a macro that implements the interface by passing the interface created to the TEST_INTERFACE macro.
 #define TEST_USER_TYPE(__result, __expected) \
-    TEST_INTERFACE(__result, __expected, &usertype_interface);
+    TEST_INTERFACE(__result, __expected, &usertype_interface)
 
-// -- Create a macro setter
+
+// Creating a constructor is recommended (C can have problems parsing macros where "," is used).
 #define DUMMY_USER_TYPE(__user, __simple_int, __simple_str) \
     do {                                                    \
       __user = (UserType) {                                 \
@@ -89,19 +111,22 @@ static const TestInterface usertype_interface = {
     };                                                      \
 } while (0);
 
-// -- Compare two usertype
+// Now you can write test for your new type
+// all you have to do is call the macro that implements "TEST_INTERFACE".
+// here it's "TEST_USERTYPE"
 TFUNCTION(test_user_type, {
-    UserType x1;
-    UserType x2;
+    UserType result;
+    UserType expected;
 
-    DUMMY_USER_TYPE(x1, 1, "John Doe");
-    DUMMY_USER_TYPE(x2, 1, "John Doe");
+    DUMMY_USER_TYPE(result, 1, "John Doe");
+    DUMMY_USER_TYPE(expected, 1, "John Doe");
 
-    TEST_USER_TYPE(&x1, &x2);
+    TEST_USER_TYPE(&result, &expected);
 })
 
-
-// -- Compare an array of usetype
+// Now you can write test for your new type
+// all you have to do is call the macro that implements "TEST_INTERFACE".
+// here it's "TEST_USERTYPE"
 TFUNCTION(test_array_user_type, {
     UserType results[1];
     UserType expecteds[1];
@@ -109,15 +134,23 @@ TFUNCTION(test_array_user_type, {
     DUMMY_USER_TYPE(results[0], 1, "John Doe");
     DUMMY_USER_TYPE(expecteds[0], 1, "John Doe");
 
-    TEST_ARRAY(TEST_USER_TYPE, 1, results, expecteds);
+    for (unsigned int i = 0; i < 1; i++) {
+        TEST_USER_TYPE(&results[i], &expecteds[i]);
+    }
 })
 
+// ---------------------3. FILE ENTRY POINT
+
 // Define the entry point of a test file
+// Use the macro "CALL_TFUNCTION" where the name of a function is defined with the macro "TFUNCTION".
 TFILE_ENTRY_POINT(test_file_ex, {
+    // Call the simple examples
     CALL_TFUNCTION(test_should_pass);
     CALL_TFUNCTION(test_should_fail);
     CALL_TFUNCTION(test_array);
-    CALL_TFUNCTION(test_ptr_array);
+
+    // Call the more complex example
     CALL_TFUNCTION(test_user_type);
     CALL_TFUNCTION(test_array_user_type);
 })
+
diff --git a/doc/test_main_ex.c b/doc/test_main_ex.c
index 0aa86b9..a5e7841 100644
--- a/doc/test_main_ex.c
+++ b/doc/test_main_ex.c
@@ -22,7 +22,7 @@
 // Include of the test library
 #include "./../tests/small_test.h"
 
-// Include the *.c files that contain the tests
+// Include the *.c files containing the tests
 #include "./test_file_ex.c"
 // #include "./test_another_test_file.c"
 
@@ -33,3 +33,4 @@ TMAIN({
     CALL_TFUNCTION(test_file_ex);
     // CALL_TFUNCTION(another_file_entry_point_function);
 })
+
diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index 09ac0d9..0485099 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -142,7 +142,10 @@ TFUNCTION(test_label_amd_rapl, {
     // -- Run
     label_amd_rapl(results, (void *) &rapl);
     // -- Verification
-    TEST_PTR_ARRAY(TEST_STR, nb, results, expecteds);
+    for(unsigned int i = 0; i < nb; i++)
+    {
+        TEST_STR(results[i], expecteds[i]);
+    }
 
     // Test 2:
     // -- Setup
@@ -159,8 +162,10 @@ TFUNCTION(test_label_amd_rapl, {
     // -- Run
     label_amd_rapl(results, (void *) &rapl);
     // -- Verification
-    TEST_PTR_ARRAY(TEST_STR, nb, results, expecteds);
-
+    for(unsigned int i = 0; i < nb; i++)
+    {
+        TEST_STR(results[i], expecteds[i]);
+    }
     // Test 3:
     // -- Setup
     nb = 4;
@@ -176,7 +181,10 @@ TFUNCTION(test_label_amd_rapl, {
     // -- Run
     label_amd_rapl(results, (void *) &rapl);
     // -- Verification
-    TEST_PTR_ARRAY(TEST_STR, nb, results, expecteds);
+    for(unsigned int i = 0; i < nb; i++)
+    {
+        TEST_STR(results[i], expecteds[i]);
+    }
 })
 
 
@@ -271,7 +279,7 @@ TFUNCTION(test_is_duplicate, {
     // -- Verification
     TEST_BOOL(&results[0], &expecteds[0]);
     TEST_BOOL(&results[1], &expecteds[1]);
-    
+
     // -- Setup
     memset(map, NONE, sizeof(map));
     memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
@@ -286,11 +294,15 @@ TFUNCTION(test_is_duplicate, {
     memset(expecteds, 1, sizeof(unsigned int) * 4);
     memset(&expecteds[4], 0, sizeof(unsigned int) * 4);
     // -- Run
-    for (unsigned int i = 0; i < 8; i++) {
+    for (unsigned int i = 0; i < 8; i++)
+    {
         results[i] = is_duplicate(&cpu_information[i], nb_core, nb_package, map );
     }
     // -- Verification
-    TEST_ARRAY(TEST_BOOL, 8, results, expecteds);
+    for(unsigned int i = 0; i < 8; i++)
+    {
+        TEST_BOOL(&results[i], &expecteds[i]);
+    }
 })
 
 
diff --git a/tests/small_test.h b/tests/small_test.h
index eddbdb0..abae768 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -33,10 +33,10 @@
 
 // ---------------------------API_INTERFACE
 /**
- * @brief Define the entry point of the tests
- * It initializes each useful variables.
+ * @brief Define the entry point for the tests.
+ * It initialises any useful variables and acts as the main one.
  *
- * @param __code The code that contains the calls to the test functions
+ * @param __code The code that contains the calls to the test functions.
  */
 
 #define TMAIN(__code)                                              \
@@ -46,22 +46,24 @@
   INDENTED_PRINT("%s:%s\n", __FILE__, __func__);                 \
   unsigned int __error_counter__ = 0;                            \
   do __code while (0);                                             \
-  DEFERRED_FILE_ERROR(__error_counter__);                        \
+  DEFERRED_ERROR(__error_counter__);                        \
   return __error_counter__;                                      \
 }
 
 /**
+ * @def TFILE_ENTRY_POINT(__filename, __code)
+ *
  * @brief Define the entry point of a test file.
  * This macro is used to define the entry point of a test file.
  * It defines a function with the specified __filename that contains the test code specified in code.
  *
- * When the function is called, it initializes the test file using the INIT_TEST_FILE macro,
+ * When the function is called, it initialises the test file using the INIT_TEST_FILE macro,
  * declares an integer variable __error_counter__ to keep track of any errors encountered during the tests,
  * executes the test code in a do-while loop, and then checks for any deferred errors using the DEFERRED_ERROR macro.
  * The function returns the value of __error_counter__,
  * which indicates the number of errors encountered during the tests.
  *
- * @param __filename The name of the function that serves as the entry point for the test file.
+ * @param __filename The name of the function to be used as an entry point for the test file.
  * @param __code The test code to be executed in the function.
  */
 #define TFILE_ENTRY_POINT(__filename, __code)       \
@@ -70,16 +72,18 @@
   INIT_TEST_FILE();                                 \
   int __error_counter__ = 0;                        \
   do __code while(0);                               \
-  DEFERRED_FILE_ERROR(__error_counter__);           \
+  DEFERRED_ERROR(__error_counter__);           \
   return __error_counter__;                         \
 }
 
 /**
+ * @def TFUNCTION(__function_name, __code)
+ *
  * @brief Define a test function within a test file.
  * This macro is used to define a test function within a test file.
- * It defines a function with the specified function_name that contains the test code specified in code.
+ * It defines a function with the given __function_name containing the test code specified in __code.
  *
- * When the function is called, it initializes the test function using the INIT_TEST_FUNCTION macro,
+ * When the function is called, it initialises the test function using the INIT_TEST_FUNCTION macro,
  * declares an integer variable __error_counter__ to keep track of any errors encountered during the tests,
  * executes the test code in a do-while loop, and then checks for any deferred errors using the DEFERRED_ERROR macro.
  * The function returns the value of __error_counter__, which indicates the number of errors encountered during the tests.
@@ -93,28 +97,32 @@
   INIT_TEST_FUNCTION(); \
   int __error_counter__ = 0; \
   do __code while(0); \
-  DEFERRED_FUNCTION_ERROR(__error_counter__); \
+  DEFERRED_ERROR(__error_counter__); \
   return __error_counter__; \
 }
 
 /**
+ * @def CALL_TFUNCTION(__function_name)
+ *
  * @brief Call a test function within a test file.
  * This macro is used to call a test function within a test file.
- * It calls the function specified by function_name and adds the return value to the __error_counter__ variable.
+ * It calls the function specified by __function_name and adds the return value to the __error_counter__ variable.
  * This allows multiple test functions to be executed and their error count to be accumulated.
  *
- * @param function_name The name of the test function to be called.
+ * @param __function_name The name of the test function to be called.
  */
-#define CALL_TFUNCTION(function_name) \
-  do {__error_counter__ += function_name(__indentation_level + 1);} while(0)
+#define CALL_TFUNCTION(__function_name) \
+  do {__error_counter__ += __function_name(__indentation_level + 1);} while(0)
 
 /**
- * @def TEST_STR(result, expected)
+ * @def TEST_STR(__result, __expected)
+ *
  * @brief Test strings
- * This macro is used to test strings. It takes two arguments: `__result`, which is the string to be tested, and `__expected`, which is the expected value of the string.
+ * This macro is used to test strings. It takes two arguments: `__result`, which is the string to test, and `__expected`,
+ * which is the expected value of the string.
  *
- * @param __result the string to be tested
- * @param __expected the expected value of the string
+ * @param __result the string to test.
+ * @param __expected the expected value of the string.
  *
  * @code
  * TEST_STR("Hello", "Hello");
@@ -125,15 +133,17 @@
 
 /**
  * @def TEST_BOOL(__result, __expected)
+ *
  * @brief Test bools
- * This macro is used to test bools. It takes two arguments: `__result`, which is the bool to be tested, and `__expected`, which is the expected value of the bool.
+ * This macro is used to test bools. It takes two arguments: `__result`, which is the bool to test, and `__expected`,
+ * which is the expected value of the bool.
  *
- * @param __result the pointer to bool to be tested
- * @param __expected the pointer to the expected value of the bool
+ * @param __result the pointer to bool to test.
+ * @param __expected the pointer to the expected value of the bool.
  *
  * @code
  * bool x = true;
- * bool y = false;
+ * bool y = true;
  * TEST_BOOL(&x, &y);
  * @endcode
  */
@@ -142,11 +152,13 @@
 
 /**
  * @def TEST_INT(__result, __expected)
+ *
  * @brief Test ints
- * This macro is used to test ints. It takes two arguments: `__result`, which is the int to be tested, and `__expected`, which is the expected value of the int.
+ * This macro is used to test ints. It takes two arguments: `__result`, which is the int to be test, and `__expected`,
+ * which is the expected value of the int.
  *
- * @param __result the pointer to int to be tested
- * @param __expected the pointer to expected value of the int
+ * @param __result the pointer to int to test.
+ * @param __expected the pointer to expected value of the int.
  *
  * @code
  * int x = 1;
@@ -157,16 +169,15 @@
 #define TEST_INT(__result, __expected) \
     do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, &int_interface);} while (0)
 
-
-
-
 /**
  * @def TEST_PTR(__result, __expected)
+ *
  * @brief Test pointers
- * This macro is used to test pointers. It takes two arguments: `__result`, which is the pointer to be tested, and `__expected`, which is the expected value of the pointer.
+ * This macro is used to test pointers. It takes two arguments: `__result`, which is the pointer to test, and `__expected`,
+ * which is the expected value of the pointer.
  *
- * @param __result the pointer to be tested
- * @param __expected the expected value of the pointer
+ * @param __result the pointer to test.
+ * @param __expected the expected value of the pointer.
  *
  * @code
  * int x = 5;
@@ -180,11 +191,13 @@
 
 /**
  * @def TEST_UINT64_T(__result, __expected)
+ *
  * @brief Test 64-bit unsigned integers
- * This macro is used to test 64-bit unsigned integers. It takes two arguments: `__result`, which is the integer to be tested, and `__expected`, which is the expected value of the integer.
+ * This macro is used to test 64-bit unsigned integers. It takes two arguments: `__result`,
+ * which is the integer to test, and `__expected`, which is the expected value of the integer.
  *
- * @param __result the pointer to integer to be tested
- * @param __expected the pointer to expected value of the integer
+ * @param __result the pointer to integer to test.
+ * @param __expected the pointer to expected value of the integer.
  *
  * @code
  * uint64_t x = 5;
@@ -197,64 +210,28 @@
 
 /**
  * @def TEST_INTERFACE(__result, __expected, __interface)
- * @brief Define a macro on a usertype with the given __interface
+ *
+ * @brief Define a macro on a usertype with the given __interface.
  * This macro is used by the user to define a new test macro on a usertype.
  *
  * @param __result
  * @param __expected
- * @param __interface the usertype interface
+ * @param __interface the interface of the usertype.
  *
  * @code
- * #define TEST_USERTYPE(__result, __expected)
- * TEST_INTERFACE(__result, __expected, usertype_interface)
+ * TestInterface usertype_interface = {.compare = ..., .format = ...};
+ * #define TEST_USERTYPE(__result, __expected) \
+ * TEST_INTERFACE(__result, __expected, &usertype_interface)
  * @endcode
  */
 #define TEST_INTERFACE(__result, __expected, __interface) \
     do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, __interface);} while(0)
 
-/**
- * @def TEST_T_ARRAY(__test_macro, __size, __results, __expecteds)
- * @brief Test arrays of data
- * The macro uses a for loop to iterate through the array and apply the test function to each element.
- *
- * @param __test_macro the test function to be used on each element of the array
- * @param __array_size the number of elements in the array
- * @param __results the array of elements to be tested
- * @param __expecteds the array of expected values
-
- * @code
- * int results[3] = {1, 2, 3};
- * int expecteds[3] = {1, 2, 3};
- * TEST_ARRAY(TEST_INT, 3, results, expecteds);
- * @endcode
-*/
-#define TEST_ARRAY(__test_macro, __array_size, __results, __expecteds) \
-    for (unsigned i = 0; i < __array_size; i++) {                      \
-        __test_macro(&__results[i], &__expecteds[i]);                   \
-    }
 
-/**
- * @def TEST_T_PTR_ARRAY(__test_macro, __array_size, __results, __expecteds)
- * @brief Test arrays of pointer
- * The macro uses a for loop to iterate through the array and apply the test function to each element.
- *
- * @param __test_macro the test function to be used on each element of the array
- * @param __array_size the number of elements in the array
- * @param __results the array of elements to be tested
- * @param __expecteds the array of expected values
 
- * @code
- * void* array[3];
- * TEST_PTR_ARRAY(TEST_PTR, 3, array, array);
- * @endcode
-*/
-#define TEST_PTR_ARRAY(__test_macro, __array_size, __results, __expecteds)  \
-    for (unsigned int i = 0; i < __array_size; i++) {                     \
-      __test_macro(__results[i], __expecteds[i]);                         \
-    }
-// --------------------------------API_CODE
-// These functions should not be used, only use the previous macros.
 
+// ------------------------------------CODE
+// These functions should not be in use, only the previous macros should be in use.
 
 #define INDENTED_PRINT(__fmt, ...)                          \
   do {                                                      \
@@ -271,10 +248,7 @@
 #define INIT_TEST_FUNCTION() \
   INDENTED_PRINT("%s()\n", __func__);
 
-#define DEFERRED_FILE_ERROR(nb_error) \
-    INDENTED_PRINT("|_Deferred Error : %u\n",nb_error);
-
-#define DEFERRED_FUNCTION_ERROR(nb_error) \
+#define DEFERRED_ERROR(nb_error) \
     INDENTED_PRINT("|_Deferred Error : %d\n",nb_error);
 
 typedef int (Comparator) (void *, void *);
@@ -285,8 +259,26 @@ typedef struct {
     Formatter *format;
 } TestInterface;
 
-//  ---------------------------str_interface
+// ---------------------------TEST FUNCTION
+
+int test(char *file, int line, unsigned int __indentation_level, void *result, void *expected, const TestInterface *interface)
+{
+    __indentation_level += 1;
+    static char buffer_result[FMT_BUFFER_SIZE];
+    static char buffer_expected[FMT_BUFFER_SIZE];
+    int is_equal = interface->compare(result, expected);
+
+    char *fmt_result = interface->format(buffer_expected, expected);
+    char *fmt_expected = interface->format(buffer_result, result);
+    if  (!is_equal) {
+        INDENTED_PRINT("%s:%d: failed, expected <%s>, got <%s>\n", file, line, fmt_expected, fmt_result);
+    }
+    return !is_equal;
+}
+
+// ------------------------------INTERFACES
 
+// -- str_interface
 int str_compare(void *ptr1, void *ptr2)
 {
     char *str1 = (char *) ptr1;
@@ -314,7 +306,7 @@ static const TestInterface str_interface = {
     .format = str_format
 };
 
-//  --------------------------bool_interface
+// -- bool_interface
 
 int bool_compare(void *ptr1, void *ptr2)
 {
@@ -335,7 +327,7 @@ static const TestInterface bool_interface = {
     .format = bool_format
 };
 
-// ---------------------------int_interface
+// -- int_interface
 
 int int_compare(void *ptr1, void *ptr2)
 {
@@ -356,7 +348,7 @@ static const TestInterface int_interface = {
     .format = int_format
 };
 
-// ---------------------------ptr_interface
+// -- ptr_interface
 
 int ptr_compare(void *ptr1, void *ptr2)
 {
@@ -374,7 +366,7 @@ static const TestInterface ptr_interface = {
     .format = ptr_format
 };
 
-// ---------------------------u64_interface
+// -- u64_interface
 
 int u64_compare(void *ptr1, void *ptr2)
 {
@@ -395,22 +387,5 @@ static const TestInterface u64_interface = {
     .format = u64_format
 };
 
-// ---------------------------test_function
-
-int test(char *file, int line, unsigned int __indentation_level, void *result, void *expected, const TestInterface *interface)
-{
-    __indentation_level += 1;
-    static char buffer_result[FMT_BUFFER_SIZE];
-    static char buffer_expected[FMT_BUFFER_SIZE];
-    int is_equal = interface->compare(result, expected);
-
-    char *fmt_result = interface->format(buffer_expected, expected);
-    char *fmt_expected = interface->format(buffer_result, result);
-    if  (!is_equal) {
-        INDENTED_PRINT("%s:%d: failed, expected <%s>, got <%s>\n", file, line, fmt_expected, fmt_result);
-    }
-    return !is_equal;
-}
-
 #endif
 
-- 
GitLab


From 585fa51e2a9f1d181ccd1bc10f2ac3deba544a3b Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 7 Feb 2023 07:58:49 +0000
Subject: [PATCH 27/69] format

---
 doc/test_file_ex.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/doc/test_file_ex.c b/doc/test_file_ex.c
index 95baaa7..0595e9a 100644
--- a/doc/test_file_ex.c
+++ b/doc/test_file_ex.c
@@ -20,7 +20,7 @@
 
 // Include of the test library
 #include "./../tests/small_test.h"
-// Include the file that contains the function you want to test 
+// Include the file that contains the function you want to test
 // #include "a_file.c"
 
 // This example is divided into three parts:
@@ -58,7 +58,8 @@ TFUNCTION(test_array, {
     static unsigned int size = 10;
     int results[10] = {0};
     int expecteds[10] = {0};
-    for (unsigned int i = 0; i < size; i++) {
+    for (unsigned int i = 0; i < size; i++)
+    {
         TEST_INT(&results[i], &expecteds[i]);
     }
 })
@@ -134,7 +135,8 @@ TFUNCTION(test_array_user_type, {
     DUMMY_USER_TYPE(results[0], 1, "John Doe");
     DUMMY_USER_TYPE(expecteds[0], 1, "John Doe");
 
-    for (unsigned int i = 0; i < 1; i++) {
+    for (unsigned int i = 0; i < 1; i++)
+    {
         TEST_USER_TYPE(&results[i], &expecteds[i]);
     }
 })
-- 
GitLab


From bea62d235a126b799dd3e05692903e27cc7129ed Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 7 Feb 2023 07:59:19 +0000
Subject: [PATCH 28/69] fix: use a const

---
 src/load.c | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/src/load.c b/src/load.c
index 6dcf2b0..1c049ce 100644
--- a/src/load.c
+++ b/src/load.c
@@ -26,11 +26,12 @@
 #include "util.h"
 
 #define LOAD_BUFFER_SIZE 1024
+#define LOAD_VALUES_SIZE 10
 char buffer[LOAD_BUFFER_SIZE];
 
 static int load_fid = -1;
-static uint64_t load_values[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-static uint64_t tmp_load_values[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+static uint64_t load_values[LOAD_VALUES_SIZE] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+static uint64_t tmp_load_values[LOAD_VALUES_SIZE] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 static char *stat = "/proc/stat";
 
 void _get_load(uint64_t *results)
@@ -46,8 +47,8 @@ void _get_load(uint64_t *results)
         pos++;
     }
 
-    for (int i = 0; i < 10; i++) {
-        results[i] = strtoull(buffer + pos, NULL, 10);
+    for (int i = 0; i < LOAD_VALUES_SIZE; i++) {
+        results[i] = strtoull(buffer + pos, NULL, LOAD_VALUES_SIZE);
 
         while (buffer[pos] <= '9' && buffer[pos] >= '0') {
             pos++;
@@ -71,7 +72,7 @@ unsigned int init_load(char *argument, void **state)
     }
 
     _get_load(load_values);
-    return 10;
+    return LOAD_VALUES_SIZE;
 }
 
 unsigned int get_load(uint64_t *results, void *state)
@@ -79,12 +80,12 @@ unsigned int get_load(uint64_t *results, void *state)
     UNUSED(state);
     _get_load(tmp_load_values);
 
-    for (int i = 0; i < 10; i++) {
+    for (int i = 0; i < LOAD_VALUES_SIZE; i++) {
         results[i] = tmp_load_values[i] - load_values[i];
     }
 
     memcpy(load_values, tmp_load_values, sizeof(load_values));
-    return 10;
+    return LOAD_VALUES_SIZE;
 }
 
 void clean_load(void *state)
@@ -93,14 +94,15 @@ void clean_load(void *state)
     close(load_fid);
 }
 
-char *_labels[10] = {"user", "nice", "system", "idle", "iowait", "irq",
-                     "softirq", "steal", "guest", "guest_nice"
-                    };
+char *_labels[LOAD_VALUES_SIZE] = {
+    "user", "nice", "system", "idle", "iowait", "irq",
+    "softirq", "steal", "guest", "guest_nice"
+};
 void label_load(char **labels, void *none)
 {
     UNUSED(none);
 
-    for (int i = 0; i < 10; i++) {
+    for (int i = 0; i < LOAD_VALUES_SIZE; i++) {
         labels[i] = _labels[i];
     }
 }
-- 
GitLab


From fa47271704f8d2fe67a86d94b8746c8d39eb527d Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 7 Feb 2023 08:17:33 +0000
Subject: [PATCH 29/69] cleanup

---
 doc/info_reader_ex.c | 54 ++++++++++++++++++++++++++++++--------------
 src/info_reader.h    |  8 +++----
 2 files changed, 41 insertions(+), 21 deletions(-)

diff --git a/doc/info_reader_ex.c b/doc/info_reader_ex.c
index f672d98..2e76251 100644
--- a/doc/info_reader_ex.c
+++ b/doc/info_reader_ex.c
@@ -23,8 +23,8 @@
 #include "./../src/info_reader.h"
 
 #define MAX_PROCS 64
-#define NB_KEYS 6
 
+// -----------------------------The storage
 typedef struct {
     unsigned int processor;
     char *vendor_id;
@@ -34,12 +34,16 @@ typedef struct {
     char *model_name;
 } Cpu;
 
+// --------------IMPLEMENTING THE INTERFACE
+
+// -- Define the behaviour if the attempted value is an int
 GenericPointer int_allocator(char *s)
 {
     unsigned int value = atoi(s);
     return (GenericPointer) value;
 }
 
+// -- Define the behaviour if the attempted value is a string
 GenericPointer string_allocator(char *s)
 {
     char *value = malloc(strlen(s) + 1);
@@ -47,31 +51,42 @@ GenericPointer string_allocator(char *s)
     return (GenericPointer) value;
 }
 
+// -- Define the processor setter
 void set_processor(GenericPointer storage, GenericPointer data)
 {
     Cpu *cpu = (Cpu *) storage;
     cpu->processor = data;
 }
+
+// -- Define the vendor_id setter
 void set_vendor_id(GenericPointer storage, GenericPointer data)
 {
     Cpu *cpu = (Cpu *) storage;
     cpu->vendor_id = (char *) data;
 }
+
+// -- Define the family setter
 void set_family(GenericPointer storage, GenericPointer data)
 {
     Cpu *cpu = (Cpu *) storage;
     cpu->family = data;
 }
+
+// -- Define the core_id setter
 void set_core_id(GenericPointer storage, GenericPointer data)
 {
     Cpu *cpu = (Cpu *) storage;
     cpu->core_id = data;
 }
+
+// -- Define the physical_id setter
 void set_physical_id(GenericPointer storage, GenericPointer data)
 {
     Cpu *cpu = (Cpu *) storage;
     cpu->physical_id = data;
 }
+
+// -- Define the model_name setter
 void set_model_name(GenericPointer storage, GenericPointer data)
 {
     Cpu *cpu = (Cpu *) storage;
@@ -81,28 +96,33 @@ void set_model_name(GenericPointer storage, GenericPointer data)
 int main()
 {
     Cpu cpus[MAX_PROCS];
+
+    // -- Define the setter, the allocator for each key / separator.
     KeyFinder keys[] = {
-        {"processor", ": ", (CopyAllocator *) int_allocator, (Setter *)set_processor},
-        {"vendor_id", ": ", (CopyAllocator *) string_allocator, (Setter *)set_vendor_id},
-        {"cpu family", ": ", (CopyAllocator *) int_allocator, (Setter *)set_family},
-        {"core id", ": ", (CopyAllocator *) int_allocator, (Setter *)set_core_id},
-        {"physical id", ": ", (CopyAllocator *) int_allocator,(Setter *)set_physical_id},
-        {
-            "model name", ": ", (CopyAllocator *) string_allocator,
-            (Setter *)set_model_name
-        }
+        {.key = "processor", .delimiter = ": ", .copy = (CopyAllocator *) int_allocator, .set = (Setter *)set_processor},
+        {.key = "vendor_id", .delimiter = ": ", .copy = (CopyAllocator *) string_allocator, .set = (Setter *)set_vendor_id},
+        {.key = "cpu family", .delimiter = ": ", .copy = (CopyAllocator *) int_allocator, .set = (Setter *)set_family},
+        {.key = "core id", .delimiter = ": ", .copy = (CopyAllocator *) int_allocator, .set = (Setter *)set_core_id},
+        {.key = "physical id", .delimiter = ": ", .copy = (CopyAllocator *) int_allocator, .set = (Setter *)set_physical_id},
+        {.key = "model name", .delimiter = ": ", .copy = (CopyAllocator *) string_allocator, .set = (Setter *)set_model_name}
     };
 
-    Parser parser = {.storage = (GenericPointer) cpus,
-                     .capacity = MAX_PROCS,
-                     .storage_struct_size = sizeof(Cpu),
-                     .keys = keys,
-                     .nb_keys = NB_KEYS,
-                     .file = fopen("/proc/cpuinfo", "r")
-                    };
+    size_t nb_keys = sizeof(keys)/sizeof(KeyFinder);
+
+    // -- Init the parser
+    Parser parser = {
+        .storage = (GenericPointer) cpus,
+        .capacity = MAX_PROCS,
+        .storage_struct_size = sizeof(Cpu),
+        .keys = keys,
+        .nb_keys = nb_keys,
+        .file = fopen("/proc/cpuinfo", "r")
+    };
 
+    // -- Parse the file
     parse(&parser);
 
+    // Print and free the results
     for (unsigned int i = 0; i < parser.nb_stored; ++i) {
         printf("========== PROC[%d] ==========\n", i);
         printf("Processor: %u\n", cpus[i].processor);
diff --git a/src/info_reader.h b/src/info_reader.h
index e83b2c3..0d694d3 100644
--- a/src/info_reader.h
+++ b/src/info_reader.h
@@ -96,10 +96,10 @@ static bool start_with(const char *prefix, const char *string);
 /**
  * @brief Matches a line of text to a key in the parser's list of keys.
  *
- * @param parser Pointer to the Parser struct.
- * @param line Line of text to match.
- * @param key_finder Pointer to a KeyFinder pointer where the matched key will be stored.
- * @param raw_value Pointer to a char pointer where the value associated with the matched key will be stored.
+ * @param[in] parser Pointer to the Parser struct.
+ * @param[in] line Line of text to match.
+ * @param[out] key_finder Pointer to a KeyFinder pointer where the matched key will be stored.
+ * @param[out] raw_value Pointer to a char pointer where the value associated with the matched key will be stored.
  *
  * @return Returns 1 if a key is matched, 0 otherwise.
  */
-- 
GitLab


From 402140300f756114e7ed4f18fd4692b9b5e6aae4 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 7 Feb 2023 08:25:30 +0000
Subject: [PATCH 30/69] format

---
 tests/small_test.h | 38 +++++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/tests/small_test.h b/tests/small_test.h
index abae768..bf0ca10 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -39,15 +39,15 @@
  * @param __code The code that contains the calls to the test functions.
  */
 
-#define TMAIN(__code)                                              \
-  int main()                                                     \
-{                                                                \
-  unsigned int __indentation_level = 0;                          \
-  INDENTED_PRINT("%s:%s\n", __FILE__, __func__);                 \
-  unsigned int __error_counter__ = 0;                            \
-  do __code while (0);                                             \
-  DEFERRED_ERROR(__error_counter__);                        \
-  return __error_counter__;                                      \
+#define TMAIN(__code)                            \
+  int main()                                     \
+{                                                \
+  unsigned int __indentation_level = 0;          \
+  INDENTED_PRINT("%s:%s\n", __FILE__, __func__); \
+  unsigned int __error_counter__ = 0;            \
+  do __code while (0);                           \
+  DEFERRED_ERROR(__error_counter__);             \
+  return __error_counter__;                      \
 }
 
 /**
@@ -72,7 +72,7 @@
   INIT_TEST_FILE();                                 \
   int __error_counter__ = 0;                        \
   do __code while(0);                               \
-  DEFERRED_ERROR(__error_counter__);           \
+  DEFERRED_ERROR(__error_counter__);                \
   return __error_counter__;                         \
 }
 
@@ -91,14 +91,14 @@
  * @param __function_name The name of the test function.
  * @param __code The test code to be executed in the function.
  */
-#define TFUNCTION(__function_name, __code) \
+#define TFUNCTION(__function_name, __code)              \
   int __function_name(unsigned int __indentation_level) \
-{ \
-  INIT_TEST_FUNCTION(); \
-  int __error_counter__ = 0; \
-  do __code while(0); \
-  DEFERRED_ERROR(__error_counter__); \
-  return __error_counter__; \
+{                                                       \
+  INIT_TEST_FUNCTION();                                 \
+  int __error_counter__ = 0;                            \
+  do __code while(0);                                   \
+  DEFERRED_ERROR(__error_counter__);                    \
+  return __error_counter__;                             \
 }
 
 /**
@@ -236,13 +236,13 @@
 #define INDENTED_PRINT(__fmt, ...)                          \
   do {                                                      \
     for(unsigned int i = 0; i < __indentation_level; i++) { \
-      printf("|    ");                                       \
+      printf("|    ");                                      \
     }                                                       \
     printf(__fmt, ##__VA_ARGS__);                           \
   } while(0)
 
 
-#define INIT_TEST_FILE()     \
+#define INIT_TEST_FILE() \
   INDENTED_PRINT("%s:%s\n", __FILE__, __func__)
 
 #define INIT_TEST_FUNCTION() \
-- 
GitLab


From 4b22f61991d079ebfce3c387d4ceae227a57ed47 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 7 Feb 2023 08:26:24 +0000
Subject: [PATCH 31/69] doc

---
 tests/small_test.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/tests/small_test.h b/tests/small_test.h
index bf0ca10..66c4de9 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -33,6 +33,8 @@
 
 // ---------------------------API_INTERFACE
 /**
+ * @def TMAIN(__code)
+ *
  * @brief Define the entry point for the tests.
  * It initialises any useful variables and acts as the main one.
  *
-- 
GitLab


From f29c9ade9da41bc824c40c59b4ce0e48e79c13fb Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 7 Feb 2023 08:35:54 +0000
Subject: [PATCH 32/69] fix: header

---
 src/info_reader.h   | 2 +-
 tests/info_reader.c | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/info_reader.h b/src/info_reader.h
index 0d694d3..ec28db6 100644
--- a/src/info_reader.h
+++ b/src/info_reader.h
@@ -19,7 +19,7 @@
 *******************************************************/
 
 #ifndef _INFO_READER_H
-#define _INFO_READER_
+#define _INFO_READER_H
 
 #include <string.h>
 #include <stdbool.h>
diff --git a/tests/info_reader.c b/tests/info_reader.c
index b2a8c6f..19d9c0a 100644
--- a/tests/info_reader.c
+++ b/tests/info_reader.c
@@ -19,6 +19,7 @@
 *******************************************************/
 
 #include "small_test.h"
+#include "./../src/info_reader.h"
 
 TFUNCTION(test_replace_first, {
     // useful variables :
-- 
GitLab


From 8aeab626fdda56b5090c4b88ae6ca46631509491 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Tue, 31 Jan 2023 12:39:47 +0100
Subject: [PATCH 33/69] build: support for multiple options per captor

- Makefile now includes captors.mk which defines captor object files to
  build (the previous behaviour was to build all captors regardless of
  the captor selection during configuration)
- correct a bug in configure.sh : now properly detect amd cpu family
- configure.sh now print an error when 0 captors are selected
- configure.sh now do a `make clean` on successful configuration
---
 .gitignore        |  21 +++++-----
 configure.sh      |  71 ++++++++++++++++++++++++--------
 makefile          |  14 +++----
 src/amd_rapl.h    |  16 ++++++--
 src/counters.h    |  29 +++++++++----
 src/infiniband.h  |  17 ++++++--
 src/load.h        |  16 ++++++--
 src/mojitos.c     | 101 ++++++++++++++++++++++++++++++----------------
 src/network.h     |  15 +++++--
 src/optparse.h    |   2 +
 src/rapl.h        |  16 ++++++--
 src/temperature.h |  16 ++++++--
 12 files changed, 234 insertions(+), 100 deletions(-)

diff --git a/.gitignore b/.gitignore
index dd136f4..6643912 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,10 +1,11 @@
-src/counters_option.h
-src/captors.h
-tests/run
-bin
-obj
-*.swp
-*.swo
-.vscode
-doc/test_main_ex
-doc/info_reader_ex
+doc/test_main_ex
+doc/info_reader_ex
+tests/run
+src/counters_option.h
+src/sensors.h
+captors.mk
+bin
+obj
+*.swp
+*.swo
+.vscode
diff --git a/configure.sh b/configure.sh
index 2d21bf5..49e1789 100755
--- a/configure.sh
+++ b/configure.sh
@@ -20,7 +20,8 @@ decho() {
 }
 
 debug=0
-target=src/captors.h
+target_hdr=src/captors.h
+target_mk=captors.mk
 
 noncaptor='counters_option|optparse|captors|util|info_reader'
 
@@ -41,8 +42,8 @@ ls_captors() {
 	try cd src
 
 	[ -z "$hdr_whitelist" ] && hdr_whitelist='.*'
-	dprint hdr_blacklist
-	dprint hdr_whitelist
+	dprint hdr_blacklist >&2
+	dprint hdr_whitelist >&2
 
 	ls -1 *.h |
 		grep -xEv "($hdr_blacklist)\.h" |
@@ -50,31 +51,53 @@ ls_captors() {
 		sed 's/\.h$//'
 }
 
+# gen_captors_h(captors, nb_captors)
 gen_captors_h() {
-	captors=$(ls_captors)
-	nb_captors=$(echo "$captors" | sed '/^$/d' | wc -l)
-	printf -- 'Run `make` to build `bin/mojitos`.\n' >&2
-	printf -- 'The resulting binary will have the %d following captors:\n' "$nb_captors" >&2
-	echo "$captors" >&2
-
-	[ -n "$captors" ] || return
+	captors=$1
+	nb_captors=$2
+	nb_captor_opts=$(
+		for captor in $captors; do
+			sed -n 's/.*'"${captor}"'_opt\[\([0-9]\+\)\].*/\1/p' "src/${captor}.h"
+		done |
+			paste -s -d '+' |
+			bc
+	)
+
+	dprint captors >&2
+	dprint nb_captor_opts >&2
+	isnum "$nb_captor_opts" || die "could not get total number of captors's command-line options"
 
 	# gen includes
 	for captor in $captors; do
 		printf '#include "%s.h"\n' "$captor"
 	done
-	printf '\n#define NB_CAPTORS %d\n\n' "$nb_captors"
+	printf '\n#define NB_CAPTOR %d\n\n' "$nb_captors"
+	printf '\n#define NB_CAPTOR_OPT %d\n\n' "$nb_captor_opts"
 
 	# gen `init_captors()`
-	printf 'void init_captors(struct optparse_long *longopts, struct captor *captors, size_t len, size_t offset, int *nb_defined)\n{\n'
+	printf 'void init_captors(Optparse *longopts, Captor *captors, size_t len, size_t offset, int *nb_defined)\n{\n'
+	printf '    int opt_idx = offset;\n'
 	for captor in $captors; do
-		printf '    longopts[offset + *nb_defined] = %s_opt;\n' "$captor"
-		printf '    captors[(*nb_defined)++] = %s;\n' "$captor"
+		cat <<-!
+		    for (int i = 0; i < ${captor}.nb_opt; i++) {
+		        longopts[opt_idx++] = ${captor}_opt[i];
+		    }
+		    captors[(*nb_defined)++] = ${captor};
+		!
 	done
 	printf '    assert((offset + *nb_defined) <= len);\n'
 	printf '}\n'
 }
 
+gen_captors_mk() {
+	captors=$1
+	printf 'CAPTOR_OBJ = '
+	for captor in $captors; do
+		printf '$(OBJ_DIR)/%s.o ' "$captor"
+	done
+	printf '\n'
+}
+
 detect_caps() {
 	[ -r /usr/include/linux/perf_event.h ] && hdr_whitelist=counters
 	[ -d /sys/class/infiniband ] && hdr_whitelist=${hdr_whitelist}|infiniband
@@ -92,7 +115,7 @@ detect_caps() {
 		hdr_whitelist="${hdr_whitelist}|rapl"
 		;;
 	*amd*)
-		family=$(awk '/cpu[ \t]*family/ {print $3; exit}' /proc/cpuinfo)
+		family=$(awk '/cpu[ \t]*family/ {print $4; exit}' /proc/cpuinfo)
 		if isnum "$family"; then
 			[ $family -ge 17 ] && hdr_whitelist="${hdr_whitelist}|amd_rapl"
 		fi
@@ -132,4 +155,20 @@ while [ "$1" ]; do
 	shift
 done
 
-gen_captors_h > "$target"
+captors=$(ls_captors)
+nb_captors=$(echo "$captors" | sed '/^$/d' | wc -l)
+
+if [ "$nb_captors" -eq 0 ]; then
+	printf -- '0 captors are selected. cannot build.\n' >&2
+	exit 1
+fi
+
+try gen_captors_h "$captors" "$nb_captors" > "$target_hdr"
+try gen_captors_mk "$captors" > "$target_mk"
+
+printf -- 'Run `make` to build `bin/mojitos`.\n' >&2
+printf -- 'The resulting binary will have the %d following captors:\n' "$nb_captors" >&2
+echo "$captors" >&2
+
+make clean >/dev/null
+
diff --git a/makefile b/makefile
index eabffaf..3f8a70b 100644
--- a/makefile
+++ b/makefile
@@ -8,15 +8,13 @@ TESTS_DIR = tests
 
 BIN = mojitos
 
+CAPTOR_OBJ =
+
+include ./captors.mk
+
 OBJ =  \
-	$(OBJ_DIR)/counters.o \
-	$(OBJ_DIR)/rapl.o \
-	$(OBJ_DIR)/network.o \
-	$(OBJ_DIR)/load.o \
-	$(OBJ_DIR)/infiniband.o \
-	$(OBJ_DIR)/temperature.o \
-	$(OBJ_DIR)/util.o \
-	$(OBJ_DIR)/amd_rapl.o 
+	$(CAPTOR_OBJ) \
+	$(OBJ_DIR)/util.o
 
 CC = gcc
 CPPFLAGS = -std=gnu99 -Wall -Wextra -Wpedantic -Wno-unused-function
diff --git a/src/amd_rapl.h b/src/amd_rapl.h
index f16ed4f..52a7c6c 100644
--- a/src/amd_rapl.h
+++ b/src/amd_rapl.h
@@ -23,12 +23,20 @@ unsigned int get_amd_rapl(uint64_t *results, void *);
 void clean_amd_rapl(void *);
 void label_amd_rapl(char **labels, void *);
 
-struct optparse_long amd_rapl_opt = {"amd_rapl", 'a', OPTPARSE_NONE};
-struct captor amd_rapl = {
-    .usage_arg = NULL,
-    .usage_msg = "AMD_RAPL",
+Captor amd_rapl = {
     .init = init_amd_rapl,
     .get = get_amd_rapl,
     .clean = clean_amd_rapl,
     .label = label_amd_rapl,
+    .nb_opt = 1,
+};
+
+Optparse amd_rapl_opt[1] = {
+    {
+        .longname = "amd-rapl",
+        .shortname = 'a',
+        .argtype = OPTPARSE_NONE,
+        .usage_arg = NULL,
+        .usage_msg = "AMD RAPL",
+    },
 };
diff --git a/src/counters.h b/src/counters.h
index 313feeb..a191e5a 100644
--- a/src/counters.h
+++ b/src/counters.h
@@ -22,17 +22,32 @@ unsigned int init_counters(char *, void **);
 unsigned int get_counters(uint64_t *results, void *);
 void clean_counters(void *);
 void label_counters(char **labels, void *);
+void show_all_counters();
 
-struct optparse_long counters_opt = {"perf-list", 'p', OPTPARSE_REQUIRED};
-struct captor counters = {
-    .usage_arg = "<perf_list>",
-    .usage_msg = "performance counters\n"
-    "\tperf_list is a coma separated list of performance counters.\n"
-    "\tEx: instructions,cache_misses",
+Captor counters = {
     .init = init_counters,
     .get = get_counters,
     .clean = clean_counters,
     .label = label_counters,
+    .nb_opt = 2,
+};
+
+Optparse counters_opt[2] = {
+    {
+        .longname = "perf-list",
+        .shortname = 'p',
+        .argtype = OPTPARSE_REQUIRED,
+        .usage_arg = "<perf_list>",
+        .usage_msg = "performance counters\n"
+        "\tperf_list is a coma separated list of performance counters.\n"
+        "\tEx: instructions,cache_misses",
+    },
+    {
+        .longname = "list",
+        .shortname = 'l',
+        .argtype = OPTPARSE_NONE,
+        .usage_arg = NULL,
+        .usage_msg = "list the possible performance counters and quit"
+    },
 };
 
-void show_all_counters();
diff --git a/src/infiniband.h b/src/infiniband.h
index 0f1ad11..285b2ba 100644
--- a/src/infiniband.h
+++ b/src/infiniband.h
@@ -21,12 +21,21 @@
 unsigned int init_infiniband(char *infi_path, void **ptr);
 void label_infiniband(char **labels, void *);
 
-struct optparse_long infiniband_opt = {"monitor-infiniband", 'i', OPTPARSE_REQUIRED};
-struct captor infiniband = {
-    .usage_arg = "<infiniband_path>",
-    .usage_msg = "infiniband monitoring (if infiniband_path is X, tries to detect it automatically)",
+Captor infiniband = {
     .init = init_infiniband,
     .get = NULL,
     .clean = NULL,
     .label = label_infiniband,
+    .nb_opt = 1,
 };
+
+Optparse infiniband_opt[1] = {
+    {
+        .longname = "monitor-infiniband",
+        .shortname = 'i',
+        .argtype = OPTPARSE_REQUIRED,
+        .usage_arg = "<infiniband_path>",
+        .usage_msg = "infiniband monitoring (if infiniband_path is X, tries to detect it automatically)",
+    },
+};
+
diff --git a/src/load.h b/src/load.h
index 366e448..c7c5575 100644
--- a/src/load.h
+++ b/src/load.h
@@ -23,12 +23,20 @@ unsigned int get_load(uint64_t *results, void *);
 void clean_load(void *);
 void label_load(char **labels, void *);
 
-struct optparse_long load_opt = {"sysload", 'u', OPTPARSE_NONE};
-struct captor load = {
-    .usage_arg = NULL,
-    .usage_msg = "system load",
+Captor load = {
     .init = init_load,
     .get = get_load,
     .clean = clean_load,
     .label = label_load,
+    .nb_opt = 1,
+};
+
+Optparse load_opt[1] = {
+    {
+        .longname = "sysload",
+        .shortname = 'u',
+        .argtype = OPTPARSE_NONE,
+        .usage_arg = NULL,
+        .usage_msg = "system load",
+    },
 };
diff --git a/src/mojitos.c b/src/mojitos.c
index dc113fc..683bdfa 100644
--- a/src/mojitos.c
+++ b/src/mojitos.c
@@ -37,44 +37,75 @@ typedef void (*labeler_t)(char **, void *);
 typedef unsigned int (*getter_t)(uint64_t *, void *);
 typedef void (*cleaner_t)(void *);
 
-struct captor {
-    char *usage_arg;
-    char *usage_msg;
+typedef struct Opt Opt;
+typedef struct Captor Captor;
+/* optparse typedef */
+typedef struct optparse_long Optparse;
+
+struct Captor {
     initializer_t init;
     getter_t get;
     cleaner_t clean;
     labeler_t label;
+    int nb_opt;
 };
 
 int nb_defined_captors = 0;
 
 #include "captors.h"
 
-struct captor captors[NB_CAPTORS];
-
-#define NB_OPTS 6
-struct optparse_long longopts[NB_OPTS + NB_CAPTORS + 1] = {
-    {"overhead-stats", 's', OPTPARSE_NONE},
-    {"list", 'l', OPTPARSE_NONE},
-    {"freq", 'f', OPTPARSE_REQUIRED},
-    {"time", 't', OPTPARSE_REQUIRED},
-    {"exec", 'e', OPTPARSE_REQUIRED},
-    {"logfile", 'o', OPTPARSE_REQUIRED},
+Captor captors[NB_CAPTOR];
+
+#define NB_OPT 5
+Optparse longopts[NB_OPT + NB_CAPTOR_OPT + 1] = {
+    {
+        .longname = "freq", .shortname = 'f', .argtype = OPTPARSE_REQUIRED,
+        .usage_arg = "<freq>",
+        .usage_msg = "specify frequency",
+    },
+    {
+        .longname = "time", .shortname = 't', .argtype = OPTPARSE_REQUIRED,
+        .usage_arg = "<time>",
+        .usage_msg = "specify time",
+    },
+    {
+        .longname = "exec", .shortname = 'e', .argtype = OPTPARSE_REQUIRED,
+        .usage_arg = "<cmd>",
+        .usage_msg = "specify a command",
+    },
+    {
+        .longname = "logfile", .shortname = 'o', .argtype = OPTPARSE_REQUIRED,
+        .usage_arg = "<file>",
+        .usage_msg = "specify a log file",
+    },
+    {
+        .longname = "overhead-stats", .shortname = 's', .argtype = OPTPARSE_NONE,
+        .usage_arg = NULL,
+        .usage_msg = "enable overhead statistics in nanoseconds",
+    },
 };
 
 
+void printopt(Optparse *opt)
+{
+    printf("-%c", opt->shortname);
+    printf("|--%s", opt->longname);
+    if (opt->usage_arg != NULL) {
+        printf(" %s", opt->usage_arg);
+    }
+    printf("\n\t%s\n", opt->usage_msg);
+}
+
 void usage(char **argv)
 {
-    printf("Usage : %s [OPTIONS] [CAPTOR ...] [-o logfile] [-e cmd ...]\n"
-           "\nOPTIONS:\n"
-           "-t <time>\t\tspecify time\n"
-           "-f <freq>\t\tspecify frequency\n"
-           "-e <cmd>\t\tspecify a command\n"
-           "-l\t\tlist the possible performance counters and quit\n"
-           "-s\t\tenable overhead statistics in nanoseconds\n"
-           "if time==0 then loops infinitively\n"
-           "if -e is present, time and freq are not used\n"
-           , argv[0]);
+    printf("Usage : %s [OPTIONS] [CAPTOR ...]\n", argv[0]);
+
+    printf("\nOPTIONS:\n");
+    for (int i = 0; i < NB_OPT; i++) {
+        printopt(&longopts[i]);
+    }
+    printf("if time==0 then loops infinitively\n"
+           "if -e is present, time and freq are not used\n");
 
     if (nb_defined_captors == 0) {
         // no captor to show
@@ -82,13 +113,8 @@ void usage(char **argv)
     }
 
     printf("\nCAPTORS:\n");
-
-    for (int i = 0; i < nb_defined_captors; i++) {
-        printf("-%c", longopts[NB_OPTS + i].shortname);
-        if (captors[i].usage_arg != NULL) {
-            printf(" %s", captors[i].usage_arg);
-        }
-        printf("\n\t%s\n", captors[i].usage_msg);
+    for (int i = 0; i < NB_CAPTOR_OPT; i++) {
+        printopt(&longopts[NB_OPT + i]);
     }
 
     exit(EXIT_FAILURE);
@@ -123,7 +149,7 @@ unsigned int nb_sensors = 0;
 char **labels = NULL;
 uint64_t *values = NULL;
 
-void add_source(struct captor *cpt, char *arg)
+void add_source(Captor *cpt, char *arg)
 {
     nb_sources++;
     initializer_t init = cpt->init;
@@ -160,7 +186,7 @@ int main(int argc, char **argv)
     char **application = NULL;
     int stat_mode = -1;
 
-    init_captors(longopts, captors, NB_OPTS + NB_CAPTORS, NB_OPTS, &nb_defined_captors);
+    init_captors(longopts, captors, NB_OPT + NB_CAPTOR_OPT, NB_OPT, &nb_defined_captors);
 
     if (argc == 1) {
         usage(argv);
@@ -207,10 +233,15 @@ int main(int argc, char **argv)
             break;
         default: {
             int ismatch = 0;
+            int opt_idx = NB_OPT;
             for (int i = 0; i < nb_defined_captors && !ismatch; i++) {
-                if (opt == longopts[NB_OPTS + i].shortname) {
-                    ismatch = 1;
-                    add_source(&captors[i], options.optarg);
+                for (int j = 0; j < captors[i].nb_opt; j++) {
+                    if (opt == longopts[opt_idx].shortname) {
+                        ismatch = 1;
+                        add_source(&captors[i], options.optarg);
+                        break;
+                    }
+                    opt_idx++;
                 }
             }
             if (!ismatch) {
diff --git a/src/network.h b/src/network.h
index 3182587..82fcfc3 100644
--- a/src/network.h
+++ b/src/network.h
@@ -23,13 +23,20 @@ unsigned int get_network(uint64_t *results, void *);
 void clean_network(void *);
 void label_network(char **labels, void *);
 
-struct optparse_long network_opt = {"net-dev", 'd', OPTPARSE_REQUIRED};
-struct captor network = {
-    .usage_arg = "<net_dev>",
-    .usage_msg = "network monitoring (if network_device is X, tries to detect it automatically)",
+Captor network = {
     .init = init_network,
     .get = get_network,
     .clean = clean_network,
     .label = label_network,
+    .nb_opt = 1,
 };
 
+Optparse network_opt[1] = {
+    {
+        .longname = "net-dev",
+        .shortname = 'd',
+        .argtype = OPTPARSE_REQUIRED,
+        .usage_arg = "<net_dev>",
+        .usage_msg = "network monitoring (if network_device is X, tries to detect it automatically)",
+    },
+};
diff --git a/src/optparse.h b/src/optparse.h
index 04e60f6..b1908d4 100644
--- a/src/optparse.h
+++ b/src/optparse.h
@@ -71,6 +71,8 @@ struct optparse_long {
     const char *longname;
     int shortname;
     enum optparse_argtype argtype;
+    char *usage_arg;
+    char *usage_msg;
 };
 
 /**
diff --git a/src/rapl.h b/src/rapl.h
index b8dc9a2..95f9fd4 100644
--- a/src/rapl.h
+++ b/src/rapl.h
@@ -23,13 +23,21 @@ unsigned int get_rapl(uint64_t *results, void *);
 void clean_rapl(void *);
 void label_rapl(char **labels, void *);
 
-struct optparse_long rapl_opt = {"rapl", 'r', OPTPARSE_NONE};
-struct captor rapl = {
-    .usage_arg = NULL,
-    .usage_msg = "RAPL",
+Captor rapl = {
     .init = init_rapl,
     .get = get_rapl,
     .clean = clean_rapl,
     .label = label_rapl,
+    .nb_opt = 1,
+};
+
+Optparse rapl_opt[1] = {
+    {
+        .longname = "rapl",
+        .shortname = 'r',
+        .argtype = OPTPARSE_NONE,
+        .usage_arg = NULL,
+        .usage_msg = "RAPL",
+    },
 };
 
diff --git a/src/temperature.h b/src/temperature.h
index 5e8046e..ec2faef 100644
--- a/src/temperature.h
+++ b/src/temperature.h
@@ -23,12 +23,20 @@ unsigned int get_temperature(uint64_t *results, void *);
 void clean_temperature(void *);
 void label_temperature(char **labels, void *);
 
-struct optparse_long temperature_opt = {"cpu-temp", 'c', OPTPARSE_NONE};
-struct captor temperature = {
-    .usage_arg = NULL,
-    .usage_msg = "processor temperature",
+Captor temperature = {
     .init = init_temperature,
     .get = get_temperature,
     .clean = clean_temperature,
     .label = label_temperature,
+    .nb_opt = 1,
+};
+
+Optparse temperature_opt[1] = {
+    {
+        .longname = "cpu-temp",
+        .shortname = 'c',
+        .argtype = OPTPARSE_NONE,
+        .usage_arg = NULL,
+        .usage_msg = "processor temperature"
+    },
 };
-- 
GitLab


From ea44320719bf3b4c74772dc732535ae1e45e214b Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Tue, 31 Jan 2023 13:05:29 +0100
Subject: [PATCH 34/69] update documentation (doc/counter_ex.h)

---
 doc/counter_ex.h | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/doc/counter_ex.h b/doc/counter_ex.h
index 4ab7915..5702adc 100644
--- a/doc/counter_ex.h
+++ b/doc/counter_ex.h
@@ -7,12 +7,20 @@ unsigned int get_acc(uint64_t *results, void *);
 void clean_acc(void *);
 void label_acc(char **labels, void *);
 
-struct optparse_long counters_opt = {"accumulator", 'a', OPTPARSE_NONE};
-struct captor counters = {
-    .usage_arg = NULL,
-    .usage_msg = "dumb accumulator\n"
+Captor rapl = {
     .init = init_acc,
     .get = get_acc,
     .clean = clean_acc,
     .label = label_acc,
+    .nb_opt = 1,
+};
+
+Optparse rapl_opt[1] = {
+    {
+        .longname = "accumulator",
+        .shortname = 'a',
+        .argtype = OPTPARSE_NONE,		/* OPTPARSE_NONE / OPTPARSE_OPTIONAL / OPTPARSE_REQUIRED */
+        .usage_arg = NULL,
+        .usage_msg = "dumb accumulator",
+    },
 };
-- 
GitLab


From 569f527a427531691dee1b9e305cab5d4b6d00f8 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Tue, 31 Jan 2023 17:32:40 +0100
Subject: [PATCH 35/69] Add a generation system for README.md and doc/mojitos.1

- README.md can be updated via `make readme`
- doc/mojitos.1 can be generated via `make man`
- README.md is updated and doc/mojitos.1 generated on `make all`
- correct wrong translation "captor", to "sensor"
- update README.md build instructions
- mv src/optparse.h and src/info_reader.h to ./lib/
- add the possibility to execute an alternative function when parsing
  sensor options (other than `add_source()`)
---
 .gitignore                       |  3 +-
 README.md                        | 75 +++++++++++++-------------
 configure.sh                     | 91 ++++++++++++++++---------------
 doc/counter_ex.h                 |  2 +-
 doc/{mojitos.1 => mojitos.pre.1} | 41 +++-----------
 {src => lib}/info_reader.h       |  0
 {src => lib}/optparse.h          |  1 +
 makefile                         | 18 +++++--
 src/amd_rapl.h                   |  2 +-
 src/counters.c                   |  6 ++-
 src/counters.h                   |  7 +--
 src/infiniband.h                 |  2 +-
 src/load.h                       |  2 +-
 src/mojitos.c                    | 93 +++++++++++++++++++++-----------
 src/network.h                    |  2 +-
 src/rapl.h                       |  2 +-
 src/temperature.h                |  2 +-
 tools/update-readme-usage.sh     | 27 ++++++++++
 18 files changed, 213 insertions(+), 163 deletions(-)
 rename doc/{mojitos.1 => mojitos.pre.1} (69%)
 rename {src => lib}/info_reader.h (100%)
 rename {src => lib}/optparse.h (99%)
 create mode 100755 tools/update-readme-usage.sh

diff --git a/.gitignore b/.gitignore
index 6643912..31260f1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,9 +1,10 @@
 doc/test_main_ex
 doc/info_reader_ex
+doc/mojitos.1
 tests/run
 src/counters_option.h
 src/sensors.h
-captors.mk
+sensors.mk
 bin
 obj
 *.swp
diff --git a/README.md b/README.md
index 6422ce0..10f5aaf 100644
--- a/README.md
+++ b/README.md
@@ -6,51 +6,52 @@ MojitO/S runs on GNU/Linux
 ## Usage
 
 ```bash
-Usage : mojitos [-rsu] [-t time] [-f freq] [-p perf_list]  \
-                [-d network_device] [-o logfile] [-e command arguments...]
-        mojitos [-l]
-
-     -s      Enable overhead statistics (in nanoseconds).
-
-     -u      Enable system-level load monitoring.
-
-     -r      Enable RAPL.
-
-     -p perf_list
-             Enable performance counters.  The argument is a coma separated
-             list of performance counters.
-
-     -d net_device
-             Enable network monitoring.
-
-     -l      List the available performance counters and quit.
-
-     -t time
-             Set duration value (in seconds). If 0, then loops indefinitely.
-
-     -f freq
-             Set amount of measurements per second.
-
-     -e cmd ...
-             Execute a command with optional arguments.  If this option is
-             used, any usage of -t or -f is ignored.
+Usage : ./bin/mojitos [OPTIONS] [SENSOR ...] [-e <cmd> ...]
+
+OPTIONS:
+-f|--freq <freq>
+	set amount of measurements per second.
+-t|--time <time>
+	set duration value (seconds). If 0, then loops infinitely.
+-e|--exec <cmd> ...
+	Execute a command with optional arguments.
+	If this option is used, any usage of -t or -f is ignored.
+-o|--logfile <file>
+	specify a log file.
+-s|--overhead-stats
+	enable overhead statistics (nanoseconds).
+
+SENSORS:
+-p|--perf-list <perf_list>
+	performance counters
+	perf_list is a coma separated list of performance counters.
+	Ex: instructions,cache_misses
+-l|--list
+	list the available performance counters and quit
+-u|--sysload
+	system load
+-d|--net-dev <net_dev>
+	network monitoring (if network_device is X, tries to detect it automatically)
+-r|--rapl
+	RAPL
+-c|--cpu-temp
+	processor temperature
 ```
 
 ## Installation Instructions
 
-Dependencies
-```bash
-sudo apt install libpowercap0 libpowercap-dev powercap-utils python3
-```
 Download the source code
 ```bash
 git clone https://gitlab.irit.fr/sepia-pub/mojitos.git
 ```
-Compile the code
+The quickest way to compile the code is:
 ```bash
 cd mojitos
+./configure.sh
 make
 ```
+You may want to run `./configure.sh --help` to see configuration options.
+
 To execute mojitos without being root to monitor performance counters
 ```bash
 sudo sh -c 'echo 0 >/proc/sys/kernel/perf_event_paranoid'
@@ -65,7 +66,7 @@ sudo chmod a+w /sys/class/powercap/intel-rapl/*/*/*
 
 RAPL values during 2 seconds with a frequency of 2 Hz
 ```bash
-$ ./mojitos -t 2 -f 2 -r
+$ ./bin/mojitos -t 2 -f 2 -r
 #timestamp package-00 core0 dram0
 1036389.135659868 10986 2869 1526
 1036389.500183551 1291440 255736 515562
@@ -75,7 +76,7 @@ $ ./mojitos -t 2 -f 2 -r
 Performance counters (cpu_cycle, cache_ll_r_a and page_faults) during 4 seconds with a frequency of 1Hz. For cache performance counters, _r and _w are respectively read and write, and _a, _m and _p are respectively access, miss, pending.
 
 ```bash
-$ ./mojitos -t 4 -f 1 -p cpu_cycles,cache_ll_r_a,page_faults
+$ ./bin/mojitos -t 4 -f 1 -p cpu_cycles,cache_ll_r_a,page_faults
 #timestamp cpu_cycles cache_ll page_faults
 1036846.351749455 571199 1232 0
 1036847.001098880 348173344 2451387 872
@@ -85,7 +86,7 @@ $ ./mojitos -t 4 -f 1 -p cpu_cycles,cache_ll_r_a,page_faults
 
 Network values with no time limit with a frequency of 1Hz. rxp and txp are the number of received and sent packets, while rxb and txp are the number of received and sent bytes.
 ```bash
-$ ./mojitos -t 0 -f 1 -d enp0s25
+$ ./bin/mojitos -t 0 -f 1 -d enp0s25
 #timestamp rxp rxb txp txb
 1036559.277376027 0 0 0 0
 1036560.000161101 4 581 2 179
@@ -97,7 +98,7 @@ $ ./mojitos -t 0 -f 1 -d enp0s25
 
 Overhead of the monitoring for RAPL and cpu_cycle
 ```bash
-$ ./mojitos -t 5 -f 1 -p cpu_cycles -r -s
+$ ./bin/mojitos -t 5 -f 1 -p cpu_cycles -r -s
 #timestamp cpu_cycles package-00 core0 dram0 overhead
 1036988.197227391 162214 19898 4944 1586 149612
 1036989.000151326 332613664 2513116 379577 1115171 739573
diff --git a/configure.sh b/configure.sh
index 49e1789..62f297a 100755
--- a/configure.sh
+++ b/configure.sh
@@ -20,25 +20,25 @@ decho() {
 }
 
 debug=0
-target_hdr=src/captors.h
-target_mk=captors.mk
+target_hdr=src/sensors.h
+target_mk=sensors.mk
 
-noncaptor='counters_option|optparse|captors|util|info_reader'
+nonsensor='counters_option|optparse|sensors|util|info_reader'
 
-hdr_blacklist=$noncaptor
+hdr_blacklist=$nonsensor
 hdr_whitelist=''
 
 usage() {
-	printf -- 'Usage: %s [-l] [-e <captor>] [-i <captor>] [-u <captor>]\n' "$(basename "$0")" >&2
-	printf -- '-e | --exclude      :   exclude captor, can be called multiple times\n' >&2
-	printf -- '-i | --include      :   include captor, can be called multiple times\n' >&2
-	printf -- '-l | --list-captors :   list all captors and exit\n' >&2
-	printf -- '-u | --unique       :   only include the specified captor\n' >&2
+	printf -- 'Usage: %s [-l] [-e <sensor>] [-i <sensor>] [-u <sensor>]\n' "$(basename "$0")" >&2
+	printf -- '-e | --exclude      :   exclude sensor, can be called multiple times\n' >&2
+	printf -- '-i | --include      :   include sensor, can be called multiple times\n' >&2
+	printf -- '-l | --list-sensors :   list all sensors and exit\n' >&2
+	printf -- '-u | --unique       :   only include the specified sensor\n' >&2
 	printf -- '                        if this option is used, any usage of `-e` or `-i` will be ignored\n' >&2
 	exit 1
 }
 
-ls_captors() {
+ls_sensors() {
 	try cd src
 
 	[ -z "$hdr_whitelist" ] && hdr_whitelist='.*'
@@ -51,49 +51,52 @@ ls_captors() {
 		sed 's/\.h$//'
 }
 
-# gen_captors_h(captors, nb_captors)
-gen_captors_h() {
-	captors=$1
-	nb_captors=$2
-	nb_captor_opts=$(
-		for captor in $captors; do
-			sed -n 's/.*'"${captor}"'_opt\[\([0-9]\+\)\].*/\1/p' "src/${captor}.h"
+# gen_sensors_h(sensor, nb_sensors)
+gen_sensors_h() {
+	sensors=$1
+	nb_sensors=$2
+	nb_sensor_opts=$(
+		for sensor in $sensors; do
+			sed -n 's/.*'"${sensor}"'_opt\[\([0-9]\+\)\].*/\1/p' "src/${sensor}.h"
 		done |
 			paste -s -d '+' |
 			bc
 	)
 
-	dprint captors >&2
-	dprint nb_captor_opts >&2
-	isnum "$nb_captor_opts" || die "could not get total number of captors's command-line options"
+	dprint sensors >&2
+	dprint nb_sensor_opts >&2
+	isnum "$nb_sensor_opts" || die "could not get total number of sensors's command-line options"
 
 	# gen includes
-	for captor in $captors; do
-		printf '#include "%s.h"\n' "$captor"
+	for sensor in $sensors; do
+		printf '#include "%s.h"\n' "$sensor"
 	done
-	printf '\n#define NB_CAPTOR %d\n\n' "$nb_captors"
-	printf '\n#define NB_CAPTOR_OPT %d\n\n' "$nb_captor_opts"
+	printf '\n'
+
+	printf '#define NB_SENSOR %d\n' "$nb_sensors"
+	printf '#define NB_SENSOR_OPT %d\n' "$nb_sensor_opts"
+	printf '\n'
 
-	# gen `init_captors()`
-	printf 'void init_captors(Optparse *longopts, Captor *captors, size_t len, size_t offset, int *nb_defined)\n{\n'
+	# gen `init_sensors()`
+	printf 'void init_sensors(Optparse *opts, Sensor *sensors, size_t len, size_t offset, int *nb_defined)\n{\n'
 	printf '    int opt_idx = offset;\n'
-	for captor in $captors; do
+	for sensor in $sensors; do
 		cat <<-!
-		    for (int i = 0; i < ${captor}.nb_opt; i++) {
-		        longopts[opt_idx++] = ${captor}_opt[i];
+		    for (int i = 0; i < ${sensor}.nb_opt; i++) {
+		        opts[opt_idx++] = ${sensor}_opt[i];
 		    }
-		    captors[(*nb_defined)++] = ${captor};
+		    sensors[(*nb_defined)++] = ${sensor};
 		!
 	done
 	printf '    assert((offset + *nb_defined) <= len);\n'
 	printf '}\n'
 }
 
-gen_captors_mk() {
-	captors=$1
+gen_sensors_mk() {
+	sensors=$1
 	printf 'CAPTOR_OBJ = '
-	for captor in $captors; do
-		printf '$(OBJ_DIR)/%s.o ' "$captor"
+	for sensor in $sensors; do
+		printf '$(OBJ_DIR)/%s.o ' "$sensor"
 	done
 	printf '\n'
 }
@@ -140,8 +143,8 @@ while [ "$1" ]; do
 		shift; [ "$1" ] || usage
 		hdr_blacklist="${hdr_blacklist}|${1}"
 		;;
-	--list-captors|-l)
-		ls_captors
+	--list-sensors|-l)
+		ls_sensors
 		exit 0
 		;;
 	--unique|-u)
@@ -155,20 +158,20 @@ while [ "$1" ]; do
 	shift
 done
 
-captors=$(ls_captors)
-nb_captors=$(echo "$captors" | sed '/^$/d' | wc -l)
+sensors=$(ls_sensors)
+nb_sensors=$(echo "$sensors" | sed '/^$/d' | wc -l)
 
-if [ "$nb_captors" -eq 0 ]; then
-	printf -- '0 captors are selected. cannot build.\n' >&2
+if [ "$nb_sensors" -eq 0 ]; then
+	printf -- '0 sensors are selected. cannot build.\n' >&2
 	exit 1
 fi
 
-try gen_captors_h "$captors" "$nb_captors" > "$target_hdr"
-try gen_captors_mk "$captors" > "$target_mk"
+try gen_sensors_h "$sensors" "$nb_sensors" > "$target_hdr"
+try gen_sensors_mk "$sensors" > "$target_mk"
 
 printf -- 'Run `make` to build `bin/mojitos`.\n' >&2
-printf -- 'The resulting binary will have the %d following captors:\n' "$nb_captors" >&2
-echo "$captors" >&2
+printf -- 'The resulting binary will have the %d following sensors:\n' "$nb_sensors" >&2
+echo "$sensors" >&2
 
 make clean >/dev/null
 
diff --git a/doc/counter_ex.h b/doc/counter_ex.h
index 5702adc..65fabf3 100644
--- a/doc/counter_ex.h
+++ b/doc/counter_ex.h
@@ -7,7 +7,7 @@ unsigned int get_acc(uint64_t *results, void *);
 void clean_acc(void *);
 void label_acc(char **labels, void *);
 
-Captor rapl = {
+Sensor rapl = {
     .init = init_acc,
     .get = get_acc,
     .clean = clean_acc,
diff --git a/doc/mojitos.1 b/doc/mojitos.pre.1
similarity index 69%
rename from doc/mojitos.1
rename to doc/mojitos.pre.1
index a7927e8..af9cb9b 100644
--- a/doc/mojitos.1
+++ b/doc/mojitos.pre.1
@@ -3,47 +3,18 @@
 .Os
 .Sh NAME
 .Nm mojitos
-.Nd An open source system, energy and network monitoring tool.
+.Nd An open source system monitoring tool.
 .Sh SYNOPSIS
 .Nm mojitos
-.Op Fl rsu
-.Op Fl t Ar time
-.Op Fl f Ar freq
-.Op Fl p Ar perf_list
-.Op Fl d Ar net_device
-.Op Fl o Ar logfile
+.Op Ar OPTIONS
+.Op Ar SENSOR ...
 .Op Fl e Ar cmd ...
-.Nm mojitos
-.Op Fl l
 .Sh DESCRIPTION
 .Nm
-enables monitoring the system, its energy comsumption and the network activity, at the OS level.
-It runs on GNU/Linux.
-.Pp
+is a monitoring tool with a multitude of sensors that does measurements at the OS level.
 .Nm
-supports the following options:
-.Bl -tag -width Ds
-.It Fl s
-Enable overhead statistics (in nanoseconds).
-.It Fl u
-Enable system-level load monitoring.
-.It Fl r
-Enable RAPL.
-.It Fl p Ar perf_list
-Enable performance counters.
-The argument is a coma separated list of performance counters.
-.It Fl d Ar net_device
-Enable network monitoring.
-.It Fl l
-List the available performance counters and quit.
-.It Fl t Ar time
-Set duration value (in seconds). If 0, then loops indefinitely.
-.It Fl f Ar freq
-Set amount of measurements per second.
-.It Fl e Ar cmd ...
-Execute a command with optional arguments.
-If this option is used, any usage of -t or -f is ignored.
-.El
+runs on GNU/Linux.
+USAGE
 .Sh EXIT STATUS
 .Ex
 .Sh EXAMPLES
diff --git a/src/info_reader.h b/lib/info_reader.h
similarity index 100%
rename from src/info_reader.h
rename to lib/info_reader.h
diff --git a/src/optparse.h b/lib/optparse.h
similarity index 99%
rename from src/optparse.h
rename to lib/optparse.h
index b1908d4..1925d73 100644
--- a/src/optparse.h
+++ b/lib/optparse.h
@@ -73,6 +73,7 @@ struct optparse_long {
     enum optparse_argtype argtype;
     char *usage_arg;
     char *usage_msg;
+    void *(*fn)(void *, size_t);
 };
 
 /**
diff --git a/makefile b/makefile
index 3f8a70b..d5d2d23 100644
--- a/makefile
+++ b/makefile
@@ -10,21 +10,21 @@ BIN = mojitos
 
 CAPTOR_OBJ =
 
-include ./captors.mk
+include ./sensors.mk
 
 OBJ =  \
 	$(CAPTOR_OBJ) \
 	$(OBJ_DIR)/util.o
 
 CC = gcc
-CPPFLAGS = -std=gnu99 -Wall -Wextra -Wpedantic -Wno-unused-function
+CPPFLAGS = -std=gnu99 -Wall -Wextra -Wpedantic -Wno-unused-function -I./lib
 CFLAGS = $(CPPFLAGS) -O3 -Werror
 LDFLAGS =
 
 ASTYLE = astyle --style=kr -xf -s4 -k3 -n -Z -Q
 
 
-all: $(BIN)
+all: $(BIN) readme man
 
 $(BIN): $(BIN_DIR) $(OBJ) $(OBJ_DIR)/$(BIN).o
 	$(CC) $(LDFLAGS) -o $(BIN_DIR)/$(BIN) $(OBJ) $(OBJ_DIR)/$(BIN).o
@@ -48,7 +48,7 @@ $(BIN_DIR):
 	mkdir -p $(BIN_DIR)
 
 debug: CFLAGS = $(CPPFLAGS) -DDEBUG -g -Og
-debug: all
+debug: $(BIN)
 
 tests:
 	gcc $(CPPFLAGS) $(TESTS_DIR)/main.c $(SRC_DIR)/util.c -o $(TESTS_DIR)/run
@@ -64,4 +64,12 @@ clean:
 	\rm -f $(SRC_DIR)/counters_option.h
 	\rm -f $(TESTS_DIR)/run
 
-.PHONY: all clean mojitos debug format tests
+readme: $(BIN)
+	sh ./tools/update-readme-usage.sh
+
+man: $(BIN)
+	awk -v "usage=$$($(BIN_DIR)/$(BIN) -1)" \
+		'/^USAGE/ { $$0=usage } 1' \
+		doc/mojitos.pre.1 > doc/mojitos.1 2>/dev/null
+
+.PHONY: all clean mojitos debug format tests readme man
diff --git a/src/amd_rapl.h b/src/amd_rapl.h
index 52a7c6c..1a16db8 100644
--- a/src/amd_rapl.h
+++ b/src/amd_rapl.h
@@ -23,7 +23,7 @@ unsigned int get_amd_rapl(uint64_t *results, void *);
 void clean_amd_rapl(void *);
 void label_amd_rapl(char **labels, void *);
 
-Captor amd_rapl = {
+Sensor amd_rapl = {
     .init = init_amd_rapl,
     .get = get_amd_rapl,
     .clean = clean_amd_rapl,
diff --git a/src/counters.c b/src/counters.c
index 874e6fc..d42ceae 100644
--- a/src/counters.c
+++ b/src/counters.c
@@ -44,11 +44,15 @@ typedef struct _counter_t *counter_t;
 
 #include "counters_option.h"
 
-void show_all_counters()
+void *show_all_counters(void *none1, size_t none2)
 {
     for (unsigned int i = 0; i < nb_counter_option; i++) {
         printf("%s\n", perf_static_info[i].name);
     }
+    UNUSED(none1);
+    UNUSED(none2);
+    exit(EXIT_SUCCESS);
+    return NULL;	/* not reached */
 }
 
 void perf_type_key(__u32 **perf_type, __u64 **perf_key, int *indexes, int nb)
diff --git a/src/counters.h b/src/counters.h
index a191e5a..0304a07 100644
--- a/src/counters.h
+++ b/src/counters.h
@@ -22,9 +22,9 @@ unsigned int init_counters(char *, void **);
 unsigned int get_counters(uint64_t *results, void *);
 void clean_counters(void *);
 void label_counters(char **labels, void *);
-void show_all_counters();
+void *show_all_counters(void *, size_t);
 
-Captor counters = {
+Sensor counters = {
     .init = init_counters,
     .get = get_counters,
     .clean = clean_counters,
@@ -47,7 +47,8 @@ Optparse counters_opt[2] = {
         .shortname = 'l',
         .argtype = OPTPARSE_NONE,
         .usage_arg = NULL,
-        .usage_msg = "list the possible performance counters and quit"
+        .usage_msg = "list the available performance counters and quit",
+        .fn = show_all_counters,
     },
 };
 
diff --git a/src/infiniband.h b/src/infiniband.h
index 285b2ba..fac05f8 100644
--- a/src/infiniband.h
+++ b/src/infiniband.h
@@ -21,7 +21,7 @@
 unsigned int init_infiniband(char *infi_path, void **ptr);
 void label_infiniband(char **labels, void *);
 
-Captor infiniband = {
+Sensor infiniband = {
     .init = init_infiniband,
     .get = NULL,
     .clean = NULL,
diff --git a/src/load.h b/src/load.h
index c7c5575..038b263 100644
--- a/src/load.h
+++ b/src/load.h
@@ -23,7 +23,7 @@ unsigned int get_load(uint64_t *results, void *);
 void clean_load(void *);
 void label_load(char **labels, void *);
 
-Captor load = {
+Sensor load = {
     .init = init_load,
     .get = get_load,
     .clean = clean_load,
diff --git a/src/mojitos.c b/src/mojitos.c
index 683bdfa..3ecf111 100644
--- a/src/mojitos.c
+++ b/src/mojitos.c
@@ -38,11 +38,11 @@ typedef unsigned int (*getter_t)(uint64_t *, void *);
 typedef void (*cleaner_t)(void *);
 
 typedef struct Opt Opt;
-typedef struct Captor Captor;
+typedef struct Sensor Sensor;
 /* optparse typedef */
 typedef struct optparse_long Optparse;
 
-struct Captor {
+struct Sensor {
     initializer_t init;
     getter_t get;
     cleaner_t clean;
@@ -50,41 +50,70 @@ struct Captor {
     int nb_opt;
 };
 
-int nb_defined_captors = 0;
+int nb_defined_sensors = 0;
 
-#include "captors.h"
+#include "sensors.h"
 
-Captor captors[NB_CAPTOR];
+Sensor sensors[NB_SENSOR];
 
 #define NB_OPT 5
-Optparse longopts[NB_OPT + NB_CAPTOR_OPT + 1] = {
+Optparse opts[NB_OPT + NB_SENSOR_OPT + 1] = {
     {
         .longname = "freq", .shortname = 'f', .argtype = OPTPARSE_REQUIRED,
         .usage_arg = "<freq>",
-        .usage_msg = "specify frequency",
+        .usage_msg = "set amount of measurements per second.",
     },
     {
         .longname = "time", .shortname = 't', .argtype = OPTPARSE_REQUIRED,
         .usage_arg = "<time>",
-        .usage_msg = "specify time",
+        .usage_msg = "set duration value (seconds). If 0, then loops infinitely.",
     },
     {
         .longname = "exec", .shortname = 'e', .argtype = OPTPARSE_REQUIRED,
-        .usage_arg = "<cmd>",
-        .usage_msg = "specify a command",
+        .usage_arg = "<cmd> ...",
+        .usage_msg = "Execute a command with optional arguments.\n"
+        "\tIf this option is used, any usage of -t or -f is ignored.",
     },
     {
         .longname = "logfile", .shortname = 'o', .argtype = OPTPARSE_REQUIRED,
         .usage_arg = "<file>",
-        .usage_msg = "specify a log file",
+        .usage_msg = "specify a log file.",
     },
     {
         .longname = "overhead-stats", .shortname = 's', .argtype = OPTPARSE_NONE,
         .usage_arg = NULL,
-        .usage_msg = "enable overhead statistics in nanoseconds",
+        .usage_msg = "enable overhead statistics (nanoseconds).",
     },
 };
 
+void dumpopt(Optparse *opt)
+{
+    printf(".It Fl %c | Fl \\-%s", opt->shortname, opt->longname);
+    if (opt->usage_arg != NULL) {
+        printf(" Ar %s", opt->usage_arg);
+    }
+    printf("\n");
+    printf("%s\n", opt->usage_msg);
+}
+
+void dumpopts(Optparse *opts, size_t nb_opt, size_t nb_sensor_opt)
+{
+    size_t i;
+
+    /* options */
+    printf(".Pp\nOPTIONS:\n.Bl -tag -width Ds\n");
+    for (i = 0; i < nb_opt; i++) {
+        dumpopt(&opts[i]);
+    }
+    printf(".El\n");
+
+    /* sensors */
+    printf(".Pp\nSENSORS:\n.Bl -tag -width Ds\n");
+    for (i++; i < nb_opt + nb_sensor_opt; i++) {
+        dumpopt(&opts[i]);
+    }
+    printf(".El\n");
+}
 
 void printopt(Optparse *opt)
 {
@@ -98,23 +127,21 @@ void printopt(Optparse *opt)
 
 void usage(char **argv)
 {
-    printf("Usage : %s [OPTIONS] [CAPTOR ...]\n", argv[0]);
+    printf("Usage : %s [OPTIONS] [SENSOR ...] [-e <cmd> ...]\n", argv[0]);
 
     printf("\nOPTIONS:\n");
     for (int i = 0; i < NB_OPT; i++) {
-        printopt(&longopts[i]);
+        printopt(&opts[i]);
     }
-    printf("if time==0 then loops infinitively\n"
-           "if -e is present, time and freq are not used\n");
 
-    if (nb_defined_captors == 0) {
+    if (nb_defined_sensors == 0) {
         // no captor to show
         exit(EXIT_FAILURE);
     }
 
-    printf("\nCAPTORS:\n");
-    for (int i = 0; i < NB_CAPTOR_OPT; i++) {
-        printopt(&longopts[NB_OPT + i]);
+    printf("\nSENSORS:\n");
+    for (int i = 0; i < NB_SENSOR_OPT; i++) {
+        printopt(&opts[NB_OPT + i]);
     }
 
     exit(EXIT_FAILURE);
@@ -149,7 +176,7 @@ unsigned int nb_sensors = 0;
 char **labels = NULL;
 uint64_t *values = NULL;
 
-void add_source(Captor *cpt, char *arg)
+void add_source(Sensor *cpt, char *arg)
 {
     nb_sources++;
     initializer_t init = cpt->init;
@@ -186,12 +213,17 @@ int main(int argc, char **argv)
     char **application = NULL;
     int stat_mode = -1;
 
-    init_captors(longopts, captors, NB_OPT + NB_CAPTOR_OPT, NB_OPT, &nb_defined_captors);
+    init_sensors(opts, sensors, NB_OPT + NB_SENSOR_OPT, NB_OPT, &nb_defined_sensors);
 
     if (argc == 1) {
         usage(argv);
     }
 
+    if (argc == 2 && argv[1][0] == '-' && argv[1][1] == '1' && argv[1][2] == '\0') {
+        dumpopts(opts, NB_OPT, NB_SENSOR_OPT);
+        exit(EXIT_SUCCESS);
+    }
+
     output = stdout;
 
     atexit(flushexit);
@@ -202,7 +234,7 @@ int main(int argc, char **argv)
     options.permute = 0;
 
     optparse_init(&options, argv);
-    while ((opt = optparse_long(&options, longopts, NULL)) != -1 && application == NULL) {
+    while ((opt = optparse_long(&options, opts, NULL)) != -1 && application == NULL) {
         switch (opt) {
         case 'f':
             frequency = atoi(options.optarg);
@@ -218,9 +250,6 @@ int main(int argc, char **argv)
         case 's':
             stat_mode = 0;
             break;
-        case 'l':
-            show_all_counters();
-            exit(EXIT_SUCCESS);
         case 'o':
             if ((output = fopen(options.optarg, "wb")) == NULL) {
                 perror("fopen");
@@ -234,11 +263,15 @@ int main(int argc, char **argv)
         default: {
             int ismatch = 0;
             int opt_idx = NB_OPT;
-            for (int i = 0; i < nb_defined_captors && !ismatch; i++) {
-                for (int j = 0; j < captors[i].nb_opt; j++) {
-                    if (opt == longopts[opt_idx].shortname) {
+            for (int i = 0; i < nb_defined_sensors && !ismatch; i++) {
+                for (int j = 0; j < sensors[i].nb_opt; j++) {
+                    if (opt == opts[opt_idx].shortname) {
                         ismatch = 1;
-                        add_source(&captors[i], options.optarg);
+                        if (opts[opt_idx].fn != NULL) {
+                            (void) opts[opt_idx].fn(NULL, 0);
+                        } else {
+                            add_source(&sensors[i], options.optarg);
+                        }
                         break;
                     }
                     opt_idx++;
diff --git a/src/network.h b/src/network.h
index 82fcfc3..994651a 100644
--- a/src/network.h
+++ b/src/network.h
@@ -23,7 +23,7 @@ unsigned int get_network(uint64_t *results, void *);
 void clean_network(void *);
 void label_network(char **labels, void *);
 
-Captor network = {
+Sensor network = {
     .init = init_network,
     .get = get_network,
     .clean = clean_network,
diff --git a/src/rapl.h b/src/rapl.h
index 95f9fd4..a02624d 100644
--- a/src/rapl.h
+++ b/src/rapl.h
@@ -23,7 +23,7 @@ unsigned int get_rapl(uint64_t *results, void *);
 void clean_rapl(void *);
 void label_rapl(char **labels, void *);
 
-Captor rapl = {
+Sensor rapl = {
     .init = init_rapl,
     .get = get_rapl,
     .clean = clean_rapl,
diff --git a/src/temperature.h b/src/temperature.h
index ec2faef..8609dba 100644
--- a/src/temperature.h
+++ b/src/temperature.h
@@ -23,7 +23,7 @@ unsigned int get_temperature(uint64_t *results, void *);
 void clean_temperature(void *);
 void label_temperature(char **labels, void *);
 
-Captor temperature = {
+Sensor temperature = {
     .init = init_temperature,
     .get = get_temperature,
     .clean = clean_temperature,
diff --git a/tools/update-readme-usage.sh b/tools/update-readme-usage.sh
new file mode 100755
index 0000000..b9f16de
--- /dev/null
+++ b/tools/update-readme-usage.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+die() { yell "$*"; exit 111; }
+try() { "$@" || die "cannot $*"; }
+yell() { echo "$0: $*" >&2; }
+echo() { printf '%s\n' "$*"; }
+
+usage=$(./bin/mojitos)
+[ -n "$usage" ] || die 'empty usage. try to recompile mojitos.'
+
+try awk -v "usage=$usage" '
+	/^Usage/ {
+		print usage
+		del = 1
+	}
+	{
+		if (del == 1) {
+			if (match($0, "^```")) {
+				del = 0
+				print $0
+			}
+		} else {
+			print $0
+		}
+	}
+' README.md > README.tmp
+try mv README.tmp README.md
-- 
GitLab


From 24f03a059ada281567c9b7a600cd461619865640 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 6 Feb 2023 10:43:08 +0100
Subject: [PATCH 36/69] small changes

---
 lib/optparse.h |  2 +-
 makefile       | 12 ++++++------
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/lib/optparse.h b/lib/optparse.h
index 1925d73..ee7dcb6 100644
--- a/lib/optparse.h
+++ b/lib/optparse.h
@@ -73,7 +73,7 @@ struct optparse_long {
     enum optparse_argtype argtype;
     char *usage_arg;
     char *usage_msg;
-    void *(*fn)(void *, size_t);
+    void *(*fn)(void *, size_t);	/* SUBJECT TO CHANGE */
 };
 
 /**
diff --git a/makefile b/makefile
index d5d2d23..950028c 100644
--- a/makefile
+++ b/makefile
@@ -55,14 +55,14 @@ tests:
 	$(TESTS_DIR)/run
 
 format:
-	$(ASTYLE) $(SRC_DIR)/*.[ch]
-	$(ASTYLE) $(DOC_DIR)/*.[ch]
-	$(ASTYLE) $(TESTS_DIR)/*.[ch]
+	$(ASTYLE) $(SRC_DIR)/*.[ch] \
+		$(DOC_DIR)/*.[ch] \
+		$(TESTS_DIR)/*.[ch]
 
 clean:
-	\rm -f $(OBJ_DIR)/* $(BIN_DIR)/*
-	\rm -f $(SRC_DIR)/counters_option.h
-	\rm -f $(TESTS_DIR)/run
+	\rm -f $(OBJ_DIR)/* $(BIN_DIR)/* \
+		$(SRC_DIR)/counters_option.h \
+		$(TESTS_DIR)/run
 
 readme: $(BIN)
 	sh ./tools/update-readme-usage.sh
-- 
GitLab


From 82dc9a2e4bf08ff775bd255159fb04bb3e7346d5 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 20 Feb 2023 11:50:56 +0100
Subject: [PATCH 37/69] add some error checking

---
 src/network.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/src/network.c b/src/network.c
index aee5659..0f23206 100644
--- a/src/network.c
+++ b/src/network.c
@@ -17,14 +17,17 @@
     along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
 
  *******************************************************/
-#include <unistd.h>
+#include <errno.h>
 #include <fcntl.h>
-#include <stdlib.h>
+#include <stdint.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
-#include <stdint.h>
+#include <unistd.h>
+
 #include "util.h"
 
+#define NB_MAX_DEV 8
 #define NB_SENSOR 4
 
 static char *route = "/proc/net/route";
@@ -39,6 +42,8 @@ struct network_t {
     uint64_t tmp_values[NB_SENSOR];
     int sources[NB_SENSOR];
     char labels[NB_SENSOR][128];
+    char dev[NB_MAX_DEV][128];
+    int ndev;
 };
 
 unsigned int _get_network(uint64_t *results, int *sources)
@@ -103,7 +108,14 @@ unsigned int init_network(char *dev, void **ptr)
     char buffer2[256];
     for (int i = 0; i < NB_SENSOR; i++) {
         snprintf(buffer2, sizeof(buffer2), filenames[i], dev);
-        state->sources[i] = open(buffer2, O_RDONLY);
+        errno = 0;
+        int fd = open(buffer2, O_RDONLY);
+        if (fd < 0) {
+            perror("init_network: open");
+            free(state);
+            return 0;
+        }
+        state->sources[i] = fd;
         snprintf(state->labels[i], sizeof(state->labels[i]), _labels_network[i], dev);
     }
 
-- 
GitLab


From 1cb227e7cd0d3f6562d06f4266017176daca4ecc Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 20 Feb 2023 17:21:13 +0100
Subject: [PATCH 38/69] add MIN() and MAX() macros to util.h

---
 src/util.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/util.h b/src/util.h
index 23978c1..b1fa6e3 100644
--- a/src/util.h
+++ b/src/util.h
@@ -38,6 +38,8 @@
         exit(code);                          \
     } while (0)
 
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
 
 /**
  * @brief Substracts lhs by rhs, assuming that lhs is a cyclic increment from rhs,
-- 
GitLab


From 5b82667289ec077d9ed9c5658b72d572810fed08 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 20 Feb 2023 17:21:22 +0100
Subject: [PATCH 39/69] network sensor can now detect multiple routes from
 /proc/net/route

note that there is a hard limit to the number of devices the sensor can
watch. this limit is defined by "NB_MAX_DEV" (value of 8 for now)
---
 src/network.c | 170 +++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 125 insertions(+), 45 deletions(-)

diff --git a/src/network.c b/src/network.c
index 0f23206..33fdadf 100644
--- a/src/network.c
+++ b/src/network.c
@@ -38,18 +38,18 @@ char *_labels_network[NB_SENSOR] = {
     "%s:txb",
 };
 struct network_t {
-    uint64_t values[NB_SENSOR];
-    uint64_t tmp_values[NB_SENSOR];
-    int sources[NB_SENSOR];
-    char labels[NB_SENSOR][128];
-    char dev[NB_MAX_DEV][128];
+    uint64_t values[NB_MAX_DEV][NB_SENSOR];
+    uint64_t tmp_values[NB_MAX_DEV][NB_SENSOR];
+    int sources[NB_MAX_DEV][NB_SENSOR];
+    char labels[NB_MAX_DEV][NB_SENSOR][128];
+    char devs[NB_MAX_DEV][128];
     int ndev;
 };
 
-unsigned int _get_network(uint64_t *results, int *sources)
+static void _get_network(uint64_t *results, int *sources)
 {
     if (sources == NULL) {
-        return 0;
+        return;
     }
 
     char buffer[128];
@@ -62,16 +62,47 @@ unsigned int _get_network(uint64_t *results, int *sources)
 
         results[i] = strtoull(buffer, NULL, 10);
     }
+}
+
+static int strchr_refill(int fd, char *buf, int len, char **s, char c)
+{
+    *s = strchr(*s, c);
+
+    if (*s == NULL) {
+        int nbytes = read(fd, buf, len - 1);
+        if (nbytes < 0) {
+            perror("read");
+            return -1;
+        }
+        buf[len - 1] = '\0';
+
+        /* whole file read */
+        if (nbytes == 0) {
+            return 0;
+        }
+
+        *s = strchr(buf, c);
+    }
 
-    return NB_SENSOR;
+    return 1;
 }
 
 unsigned int init_network(char *dev, void **ptr)
 {
     if (dev == NULL) {
-        return 0;
+        exit(1);
     }
 
+    char *filenames[] = {
+        "/sys/class/net/%s/statistics/rx_packets",
+        "/sys/class/net/%s/statistics/rx_bytes",
+        "/sys/class/net/%s/statistics/tx_packets",
+        "/sys/class/net/%s/statistics/tx_bytes",
+    };
+
+    struct network_t *state = malloc(sizeof(struct network_t));
+    memset(state, '\0', sizeof(*state));
+
     if (strcmp(dev, "X") == 0) {
         int fd = open(route, O_RDONLY);
 
@@ -83,59 +114,104 @@ unsigned int init_network(char *dev, void **ptr)
 
         char buffer[1000];
 
-        if (read(fd, buffer, 999) < 0 ) {
-            perror("read");
+        /* skip first line */
+        char *s = buffer;
+        int ret = strchr_refill(fd, buffer, sizeof(buffer), &s, '\n');
+        if (ret != 1) {
             close(fd);
+            free(state);
             exit(1);
         }
+        s++;
 
-        char *start_of_dev = strchr(buffer, '\n') + 1;
-        char *end_of_dev = strchr(start_of_dev, '\t');
-        *end_of_dev = '\0';
-        dev = start_of_dev;
-        close(fd);
-    }
+        char *start_of_dev = s;
+        /* jump to the end of the device name */
+        ret = strchr_refill(fd, buffer, sizeof(buffer), &s, '\t');
+        if (ret != 1) {
+            close(fd);
+            free(state);
+            exit(1);
+        }
 
-    char *filenames[] = {
-        "/sys/class/net/%s/statistics/rx_packets",
-        "/sys/class/net/%s/statistics/rx_bytes",
-        "/sys/class/net/%s/statistics/tx_packets",
-        "/sys/class/net/%s/statistics/tx_bytes",
-    };
+        state->ndev++;	// ndev should be equal to 1 at this point
+        memcpy(&(state->devs[state->ndev - 1]), start_of_dev,
+               MIN((size_t)(sizeof(state->devs[0]) - 1), (size_t)(s - start_of_dev)));
+
+        for (;;) {
+            /* jump to the next line */
+            ret = strchr_refill(fd, buffer, sizeof(buffer), &s, '\n');
+            if (ret != 1) {
+                break;
+            }
+            s++;
+
+            start_of_dev = s;
+            ret = strchr_refill(fd, buffer, sizeof(buffer), &s, '\t');
+            if (ret != 1) {
+                break;
+            }
+
+            /* compare dev name to the previously saved one */
+            if (strncmp(start_of_dev, state->devs[state->ndev - 1], s - start_of_dev) != 0) {
+                if (state->ndev >= NB_MAX_DEV) {
+                    fprintf(stderr, "Maximum amount of network devices exceeded (%d).\n", NB_MAX_DEV);
+                    break;
+                }
+                state->ndev++;
+                memcpy(&(state->devs[state->ndev - 1]), start_of_dev,
+                       MIN((size_t)(sizeof(state->devs[0]) - 1), (size_t)(s - start_of_dev)));
+            }
+        }
 
-    struct network_t *state = malloc(sizeof(struct network_t));
+        close(fd);
+    } else {
+        state->ndev = 1;
+        memcpy(&(state->devs[0]), dev, strlen(dev) + 1);
+    }
 
     char buffer2[256];
-    for (int i = 0; i < NB_SENSOR; i++) {
-        snprintf(buffer2, sizeof(buffer2), filenames[i], dev);
-        errno = 0;
-        int fd = open(buffer2, O_RDONLY);
-        if (fd < 0) {
-            perror("init_network: open");
-            free(state);
-            return 0;
+    for (int i = 0; i < state->ndev; i++) {
+        for (int j = 0; j < NB_SENSOR; j++) {
+            snprintf(buffer2, sizeof(buffer2), filenames[j], state->devs[i]);
+            errno = 0;
+            int fd = open(buffer2, O_RDONLY);
+            if (fd < 0) {
+                fprintf(stderr, "init_network: open: %s: %.*s\n", strerror(errno),
+                        (int)sizeof(buffer2), buffer2);
+                free(state);
+                exit(1);
+            }
+            state->sources[i][j] = fd;
+            snprintf(state->labels[i][j], sizeof(state->labels[i][j]), _labels_network[j],
+                     state->devs[i]);
         }
-        state->sources[i] = fd;
-        snprintf(state->labels[i], sizeof(state->labels[i]), _labels_network[i], dev);
     }
 
     *ptr = (void *) state;
-    _get_network(state->values, state->sources);
 
-    return NB_SENSOR;
+    for (int i = 0; i < state->ndev; i++) {
+        _get_network(state->values[i], state->sources[i]);
+    }
+
+    return state->ndev * NB_SENSOR;
 }
 
 unsigned int get_network(uint64_t *results, void *ptr)
 {
     struct network_t *state = (struct network_t *) ptr;
-    _get_network(state->tmp_values, state->sources);
 
-    for (int i = 0; i < NB_SENSOR; i++) {
-        results[i] = modulo_substraction(state->tmp_values[i], state->values[i]);
+    for (int i = 0; i < state->ndev; i++) {
+        _get_network(state->tmp_values[i], state->sources[i]);
+
+        for (int j = 0; j < NB_SENSOR; j++) {
+            results[i*NB_SENSOR + j] = modulo_substraction(state->tmp_values[i][j], state->values[i][j]);
+        }
+
+        memcpy(&(state->values[i]), &(state->tmp_values[i]),
+               NB_SENSOR * sizeof(state->values[i][0]));
     }
 
-    memcpy(state->values, state->tmp_values, NB_SENSOR * sizeof(uint64_t));
-    return NB_SENSOR;
+    return state->ndev * NB_SENSOR;
 }
 
 void clean_network(void *ptr)
@@ -146,8 +222,10 @@ void clean_network(void *ptr)
         return;
     }
 
-    for (int i = 0; i < NB_SENSOR; i++) {
-        close(state->sources[i]);
+    for (int i = 0; i < state->ndev; i++) {
+        for (int j = 0; j < NB_SENSOR; j++) {
+            close(state->sources[i][j]);
+        }
     }
 
     free(state);
@@ -157,7 +235,9 @@ void label_network(char **labels, void *ptr)
 {
     struct network_t *state = (struct network_t *) ptr;
 
-    for (int i = 0; i < NB_SENSOR; i++) {
-        labels[i] = state->labels[i];
+    for (int i = 0; i < state->ndev; i++) {
+        for (int j = 0; j < NB_SENSOR; j++) {
+            labels[i*NB_SENSOR + j] = state->labels[i][j];
+        }
     }
 }
-- 
GitLab


From afec2006a9bab8dfda94ef4ddb05d3c1708792c0 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Tue, 21 Feb 2023 16:03:02 +0100
Subject: [PATCH 40/69] add "install" and "uninstall" make targets

---
 makefile | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/makefile b/makefile
index a197961..dc852f4 100644
--- a/makefile
+++ b/makefile
@@ -7,6 +7,7 @@ BIN_DIR = bin
 TESTS_DIR = tests
 
 BIN = mojitos
+PREFIX = /usr/local
 
 CAPTOR_OBJ =
 
@@ -74,4 +75,16 @@ man: $(BIN)
 		'/^USAGE/ { $$0=usage } 1' \
 		doc/$(BIN).pre.1 > doc/$(BIN).1 2>/dev/null
 
-.PHONY: all clean mojitos debug format tests readme man
+install: $(BIN) man
+	mkdir -p $(PREFIX)/bin
+	cp $(BIN_DIR)/$(BIN) $(PREFIX)/bin/.
+	chmod 755 $(PREFIX)/bin/$(BIN)
+	mkdir -p $(PREFIX)/share/man/man1
+	cp $(DOC_DIR)/$(BIN).1 $(PREFIX)/share/man/man1/.
+	chmod 644 $(PREFIX)/share/man/man1/$(BIN).1
+
+uninstall:
+	rm -f $(PREFIX)/bin/$(BIN)
+	rm -f $(PREFIX)/share/man/man1/$(BIN).1
+
+.PHONY: all clean mojitos debug format tests readme man install uninstall
-- 
GitLab


From 44b132bf26e445016c9bd6fb75373847d0188b03 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Tue, 21 Feb 2023 16:50:00 +0100
Subject: [PATCH 41/69] revise build system (makefile and sensors.mk)

Make it more posix compliant (remove '%.o: %.c %.h' usage, which is
not posix).

Sadly, it appears to not support well separate directories for object and
source files: inference rules do not work, and it recompiles everything
at each invocation even though there is not necessarily any change within
the source files.
---
 configure.sh |  5 +++++
 makefile     | 26 ++++++++++++++++----------
 2 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/configure.sh b/configure.sh
index 21c94ef..747a078 100755
--- a/configure.sh
+++ b/configure.sh
@@ -103,6 +103,11 @@ gen_sensors_mk() {
 		printf '$(OBJ_DIR)/%s.o ' "$sensor"
 	done
 	printf '\n'
+	for sensor in $sensors; do
+		printf '$(OBJ_DIR)/%s.o: $(SRC_DIR)/%s.c $(SRC_DIR)/%s.h $(SRC_DIR)/util.h\n' \
+			"$sensor" "$sensor" "$sensor"
+		printf '\t$(CC) $(CFLAGS) -c $< -o $@\n'
+	done
 }
 
 detect_caps() {
diff --git a/makefile b/makefile
index dc852f4..bd26308 100644
--- a/makefile
+++ b/makefile
@@ -9,14 +9,6 @@ TESTS_DIR = tests
 BIN = mojitos
 PREFIX = /usr/local
 
-CAPTOR_OBJ =
-
-include ./sensors.mk
-
-OBJ =  \
-	$(CAPTOR_OBJ) \
-	$(OBJ_DIR)/util.o
-
 CC = gcc
 CPPFLAGS = -std=gnu99 -Wall -Wextra -Wpedantic -Wno-unused-function -I./lib
 CFLAGS = $(CPPFLAGS) -O3 -Werror
@@ -24,9 +16,23 @@ LDFLAGS =
 
 ASTYLE = astyle --style=kr -xf -s4 -k3 -n -Z -Q
 
-
 all: $(BIN) man
 
+CAPTOR_OBJ =
+
+include ./sensors.mk
+
+OBJ =  \
+	$(CAPTOR_OBJ) \
+	$(OBJ_DIR)/util.o
+
+options:
+	@echo BIN: $(BIN)
+	@echo CC: $(CC)
+	@echo CFLAGS: $(CFLAGS)
+	@echo LDFLAGS: $(LDFLAGS)
+	@echo OBJ: $(OBJ)
+
 $(BIN): $(BIN_DIR) $(OBJ) $(OBJ_DIR)/$(BIN).o
 	$(CC) $(LDFLAGS) -o $(BIN_DIR)/$(BIN) $(OBJ) $(OBJ_DIR)/$(BIN).o
 
@@ -36,7 +42,7 @@ $(OBJ_DIR)/counters.o: $(SRC_DIR)/counters_option.h
 $(OBJ_DIR)/$(BIN).o: $(SRC_DIR)/$(BIN).c $(SRC_DIR)/counters_option.h
 	$(CC) $(CFLAGS) -c $< -o $@
 
-$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(SRC_DIR)/%.h
+$(OBJ_DIR)/util.o: $(SRC_DIR)/util.c $(SRC_DIR)/util.h
 	$(CC) $(CFLAGS) -c $< -o $@
 
 $(SRC_DIR)/counters_option.h: $(SRC_DIR)/counters_option.sh
-- 
GitLab


From 745d90b59eadf5e4072c8a6a3ed86d745a674d2a Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Tue, 21 Feb 2023 18:58:48 +0100
Subject: [PATCH 42/69] unfinished sensor

---
 src/nvidia_gpu.c | 324 +++++++++++++++++++++++++++++++++++++++++++++++
 src/nvidia_gpu.h |   0
 2 files changed, 324 insertions(+)
 create mode 100644 src/nvidia_gpu.c
 create mode 100644 src/nvidia_gpu.h

diff --git a/src/nvidia_gpu.c b/src/nvidia_gpu.c
new file mode 100644
index 0000000..75f0915
--- /dev/null
+++ b/src/nvidia_gpu.c
@@ -0,0 +1,324 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <nvml.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "util.h"
+
+
+// -----------------------------SENSOR_KIND
+typedef enum {
+    CLOCK_SENSOR       = 0,
+    MEMORY_SENSOR      = 1,
+    UTILIZATION_SENSOR = 2,
+
+    COUNT_SENSOR       = 3,
+} SENSOR_KIND;
+
+typedef unsigned int (Initializer) (nvmlDevice_t, void **);
+typedef unsigned int (Getter)      (nvmlDevice_t, uint64_t *, void *);
+typedef void         (Cleaner)     (void *);
+
+typedef struct {
+    void *data;
+
+    Initializer *init;
+    Getter *get;
+    Cleaner *clean;
+} ISensor;
+
+// ----------------------------CLOCK_SENSOR
+// -- All existing clocks
+#if NVML_CLOCK_COUNT != 4
+#error "NVML_CLOCK_COUNT must be equal 4";
+#endif
+
+// -- SM : Streaming Multiprocessor
+static const nvmlClockType_t clocks[NVML_CLOCK_COUNT] = {NVML_CLOCK_GRAPHICS, NVML_CLOCK_SM, NVML_CLOCK_MEM, NVML_CLOCK_VIDEO};
+static const char *clock_names[NVML_CLOCK_COUNT] = {"Graphics", "SM", "Memory", "Video"};
+
+// -- Must contain the clocks compatible with the device
+typedef struct {
+    nvmlClockType_t clocks[NVML_CLOCK_COUNT];
+    unsigned int count;
+} ClockData;
+
+unsigned int init_clock_sensor(nvmlDevice_t device, void** data)
+{
+    ClockData tmp = {0};
+    nvmlReturn_t result;
+    unsigned int clock;
+
+    // -- Test all clocks
+    for (unsigned int i = 0; i < NVML_CLOCK_COUNT; i++) {
+        if ((result = nvmlDeviceGetClockInfo(device, clocks[i], &clock)) == NVML_SUCCESS) {
+            tmp.clocks[tmp.count] = clocks[i];
+            tmp.count += 1;
+        } else {
+            fprintf(stderr, "Failed to get %s clock : %s", clock_names[i], nvmlErrorString(result));
+        }
+    }
+
+    // -- No clock avaible
+    if (tmp.count == 0) {
+        return 0;
+    }
+
+    *data = calloc(1, sizeof(ClockData));
+    memcpy(*data, &tmp, sizeof (ClockData));
+    return tmp.count;
+}
+
+unsigned int get_clock_sensor(nvmlDevice_t device, uint64_t *results, void* data)
+{
+    ClockData *clock_data = (ClockData *) data;
+    nvmlReturn_t err;
+    unsigned int clock;
+
+    for (unsigned int i = 0; i < clock_data->count; i++) {
+        nvmlClockType_t clock_type = clock_data->clocks[i];
+
+        if((err = nvmlDeviceGetClockInfo(device, clock_type, &clock)) != NVML_SUCCESS) {
+            fprintf(stderr, "Failed to get %s clock : %s", clock_names[clock_type], nvmlErrorString(err));
+            exit(99);
+        }
+        results[i] = clock;
+    }
+    return clock_data->count;
+}
+
+void clean_clock_sensor(void* data)
+{
+    free(data);
+}
+
+// ---------------------------MEMORY_SENSOR
+typedef enum {
+    FREE_MEMORY  = 0U,
+    USED_MEMORY  = 1U,
+    TOTAL_MEMORY = 2U,
+ 
+    COUNT_MEMORY = 3U,
+} MemoryKind;
+static const char *memory_names[COUNT_MEMORY] = {"Free", "Used", "Total"};
+
+unsigned int init_memory_sensor(nvmlDevice_t device, void **none)
+{
+    UNUSED(none);
+
+    nvmlMemory_t memory;
+    nvmlReturn_t result;
+    if ((result = nvmlDeviceGetMemoryInfo(device, &memory)) != NVML_SUCCESS) {
+        fprintf(stderr, "Failed to get device memory : %s\n", nvmlErrorString(result));
+        return 0;
+    }
+
+    return COUNT_MEMORY;
+}
+
+unsigned int get_memory_sensor(nvmlDevice_t device, uint64_t *results, void *none)
+{
+    UNUSED(none);
+
+    nvmlMemory_t memory;
+    nvmlReturn_t result;
+    if ((result = nvmlDeviceGetMemoryInfo(device, &memory)) != NVML_SUCCESS) {
+        fprintf(stderr, "Failed to get device memory : %s\n", nvmlErrorString(result));
+        exit(99);
+    }
+
+    results[FREE_MEMORY] = memory.free;
+    results[USED_MEMORY] = memory.used;
+    results[TOTAL_MEMORY] = memory.total;
+    return COUNT_MEMORY;
+}
+
+
+void clean_memory_sensor(void *none)
+{
+    UNUSED(none);
+}
+
+// ----------------------UTILIZATION_SENSOR
+typedef enum {
+    GPU_UTILIZATION    = 0U,
+    MEMORY_UTILIZATION = 1U,
+
+    COUNT_UTILIZATION  = 2U,
+} UtilizationKind;
+
+static const char *utilization_names[COUNT_UTILIZATION] = {"Gpu", "Memory"};
+
+unsigned int init_utilization_sensor(nvmlDevice_t device, void **none);
+{
+    UNUSED(none);
+
+    nvmlReturn_t result;
+    nvmlUtilization_t utilization;
+    if ((result = nvmlDeviceGetUtilizationRates(device, &utilization)) != NVML_SUCCESS) {
+        fprintf(stderr, "Failed to get device utilization: %s\n", nvmlErrorString(result));
+        return 0;
+    }
+
+    return COUNT_UTILIZATION;
+}
+
+unsigned int get_utilization_sensor(nvmlDevice_t device, uint64_t *results, void* none)
+{
+    UNUSED(none);
+
+    nvmlReturn_t result;
+    nvmlUtilization_t utilization;
+    if ((result = nvmlDeviceGetUtilizationRates(device, &utilization)) != NVML_SUCCESS) {
+        fprintf(stderr, "Failed to get device utilization: %s\n", nvmlErrorString(result));
+        exit(99);
+    }
+
+    results[GPU_UTILIZATION] = utilization.gpu;
+    results[MEMORY_UTILIZATION] = utilization.memory;
+    return COUNT_UTILIZATION;
+}
+
+void clean_utilization_sensor(void* none)
+{
+    UNUSED(none);
+}
+
+// ----------------------------ERROR_SENSOR
+// TODO
+
+// ----------------------------------------
+
+typedef struct {
+    char name[NVML_DEVICE_NAME_BUFFER_SIZE];
+    nvmlDevice_t device;
+
+    ISensor sensors[COUNT_SENSOR];
+    unsigned int count;
+} Device;
+
+typedef struct {
+    Device *devices;
+    unsigned int count;
+} NvidiaSensor;
+
+// -------------------------AVAIBLE_SENSORS
+static const ISensor avaible_sensors[COUNT_SENSOR] = {
+    {.init = init_clock_sensor, .get = get_clock_sensor, .clean = clean_memory_sensor, .data = NULL};
+    {.init = init_memory_sensor, .get = get_memory_sensor, .clean = clean_memory_sensor, .data = NULL};
+    {.init = init_utilization_sensor, .get = get_utilization_sensor, .clean = clean_memory_sensor, .data = NULL};
+};
+
+// ------------------------DEVICE_FUNCTIONS
+
+unsigned int init_device(unsigned int device_idx, Device *device) {
+    nvmlReturn_t result;
+    nvmlDevice_t nvml_device;
+    if ((result = nvmlDeviceGetByIndex(i, &nvml_device) != NVML_SUCCESS) {
+        fprintf(stderr, "Failed to get device handle for device %d: %s\n", device_idx, nvmlErrorString(result));
+        return 0;
+    }
+
+    if ((result = nvmlDeviceGetName(nvml_device, device->name, NVML_DEVICE_NAME_BUFFER_SIZE))) {
+        fprintf(stderr, "Failed to get device name for device %d: %s\n", device_idx, nvmlErrorString(result));
+        return 0;
+    }
+
+    unsigned int count = 0;
+    for (unsigned int i = 0; i < COUNT_SENSOR; i++) {
+        void* data;
+        if (avaible_sensors.init(nvml_device, &data) != 0) {
+            ISensor *sensor = &device->sensors[count];
+            memcpy(sensor, &avaible_sensors[i], sizeof(ISensor));
+            sensor->data = data;
+            count += 1;
+        }
+    }
+
+    device->device = nvml_device;
+    device->count = count;
+    return count;
+}
+
+unsigned int get_device(Device *device, uint64_t *results) {
+    unsigned int count;
+    nvmlDevice_t nvml_device = device->device;
+    for (unsigned int i = 0; i < device->count; i++) {
+        unsigned int result = device->sensor.get(nvml_device, &device->sensor.data, results);
+        count += result;
+        results += result;
+    }
+
+    return count;
+}
+void clean_device(Device *device) {
+    for (unsigned int i = 0; i < device->count; i++) {
+        device->sensor.clean(&device->sensor.data);
+    }
+}
+
+// ------------------------NVIDIA_INTERFACE
+
+unsigned int init_nvidia_sensor(char *none, void **ptr)
+{
+    UNUSED(none);
+    UNUSED(ptr);
+
+    nvmlReturn_t result;
+    if ((result = nvmlInit()) != NVML_SUCCESS) {
+        fprintf(stderr, "Failed to initialize NVML: %s\n", nvmlErrorString(result));
+        exit(1);
+    }
+
+    unsigned int avaible_device_count;
+    if ((result = nvmlDeviceGetCount(&avaible_device_count)) != NVML_SUCCESS) {
+        fprintf(stderr, "Failed to get device count : %s\n", nvmlErrorString(result));
+        nvmlShutdown();
+        exit(1);
+    }
+
+    Device* devices = calloc(avaible_device_count, sizeof(Device));
+
+    unsigned int sensor_count = 0;
+    unsigned int device_count = 0;
+    for (unsigned int i = 0; i < avaible_device_count; i++) {
+        unsigned int initialized_count;
+        if ((initialized_count = init_device(&devices[device_count])) != 0) {
+            sensor_count += initialized_count;
+            device_count += 1;
+        }
+    }
+
+    NvidiaSensor *nvidia = (NvidiaSensor*) calloc(1, sizeof(NvidiaSensor));
+    nvidia->devices = devices;
+    nvidia->count = device_count;
+
+    *ptr = (void*) nvidia;
+    return count;
+}
+
+
+unsigned int get_nvidia_sensor(uint64_t *results, void *ptr) {
+    NvidiaSensor *nvidia = (NvidiaSensor *) ptr;
+    unsigned count = 0;
+
+    for (unsigned int i = 0; i < nvidia.count; i++) {
+        unsigned int result = get_device(&nvidia->devices[i], results);
+        results += result;
+        count += result;
+    }
+
+    return count;
+}
+void label_nvidia_sensor(char **labels, void *ptr);
+
+void clean_nvidia_sensor(void *ptr)
+{
+    NvidiaSensor *nvidia = (NvidiaSensor *) ptr;
+
+    for (unsigned int i = 0; i < nvidia->count; i++) {
+        clean_device(&nvidia->device[i]);
+    }
+    nvmlShutdown();
+}
diff --git a/src/nvidia_gpu.h b/src/nvidia_gpu.h
new file mode 100644
index 0000000..e69de29
-- 
GitLab


From 54bba401354dcbfc30804bea721e9a563b50c778 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 6 Mar 2023 15:20:44 +0100
Subject: [PATCH 43/69] working sensor

---
 src/nvidia_gpu.c | 345 ++++++++++++++++++++++++++++++++++++-----------
 src/nvidia_gpu.h |  43 ++++++
 2 files changed, 309 insertions(+), 79 deletions(-)

diff --git a/src/nvidia_gpu.c b/src/nvidia_gpu.c
index 75f0915..22f65a1 100644
--- a/src/nvidia_gpu.c
+++ b/src/nvidia_gpu.c
@@ -1,3 +1,23 @@
+/*******************************************************
+ 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 <stdint.h>
 #include <nvml.h>
@@ -6,7 +26,6 @@
 
 #include "util.h"
 
-
 // -----------------------------SENSOR_KIND
 typedef enum {
     CLOCK_SENSOR       = 0,
@@ -16,47 +35,82 @@ typedef enum {
     COUNT_SENSOR       = 3,
 } SENSOR_KIND;
 
-typedef unsigned int (Initializer) (nvmlDevice_t, void **);
-typedef unsigned int (Getter)      (nvmlDevice_t, uint64_t *, void *);
-typedef void         (Cleaner)     (void *);
+typedef struct Device Device;
+typedef struct NvidiaSensor NvidiaSensor;
+typedef struct ISensor ISensor;
+typedef struct Sensor Sensor;
 
-typedef struct {
-    void *data;
+// -- Sensor interface
+typedef unsigned int (Initializer) (const Device *, void **);
+typedef unsigned int (Getter)      (uint64_t *, const Device *, void *);
+typedef unsigned int (Labeller)    (char **, void *);
+typedef void         (Cleaner)     (void *);
 
+struct ISensor {
     Initializer *init;
     Getter *get;
+    Labeller *label;
     Cleaner *clean;
-} ISensor;
+};
+
+// -- Sensor
+struct Sensor {
+    void *data;
+    const ISensor *fun;
+};
+
+// -- Device: represents a gpu
+struct Device {
+    char name[NVML_DEVICE_NAME_BUFFER_SIZE];
+    nvmlDevice_t device;
+    unsigned int idx;
+
+    Sensor sensors[COUNT_SENSOR];
+    unsigned int count;
+};
+
+// -- NvidiaSensor: represents the devices
+struct NvidiaSensor {
+    Device *devices;
+    unsigned int count;
+};
+
+// -- Label template
+static const char *label_template = "gpu%u_%s_%s";
 
 // ----------------------------CLOCK_SENSOR
-// -- All existing clocks
-#if NVML_CLOCK_COUNT != 4
-#error "NVML_CLOCK_COUNT must be equal 4";
-#endif
 
+#define CLOCK_LABEL_SIZE 25
+
+// -- All existing clocks
 // -- SM : Streaming Multiprocessor
 static const nvmlClockType_t clocks[NVML_CLOCK_COUNT] = {NVML_CLOCK_GRAPHICS, NVML_CLOCK_SM, NVML_CLOCK_MEM, NVML_CLOCK_VIDEO};
-static const char *clock_names[NVML_CLOCK_COUNT] = {"Graphics", "SM", "Memory", "Video"};
+static const char *clock_names[NVML_CLOCK_COUNT] = {"graphics", "sm", "memory", "video"};
+static const char *clock_base_name = "clk";
 
 // -- Must contain the clocks compatible with the device
 typedef struct {
     nvmlClockType_t clocks[NVML_CLOCK_COUNT];
+    char labels[NVML_CLOCK_COUNT][CLOCK_LABEL_SIZE];
     unsigned int count;
 } ClockData;
 
-unsigned int init_clock_sensor(nvmlDevice_t device, void** data)
+unsigned int init_clock_sensor(const Device *device, void **data)
 {
+    const nvmlDevice_t nvml_device = device->device;
+    const unsigned int device_idx = device->idx;
     ClockData tmp = {0};
     nvmlReturn_t result;
     unsigned int clock;
 
     // -- Test all clocks
     for (unsigned int i = 0; i < NVML_CLOCK_COUNT; i++) {
-        if ((result = nvmlDeviceGetClockInfo(device, clocks[i], &clock)) == NVML_SUCCESS) {
+        if ((result = nvmlDeviceGetClockInfo(nvml_device, clocks[i], &clock)) == NVML_SUCCESS) {
+            snprintf(tmp.labels[tmp.count], CLOCK_LABEL_SIZE, label_template, device_idx, clock_base_name, clock_names[i]);
             tmp.clocks[tmp.count] = clocks[i];
             tmp.count += 1;
         } else {
-            fprintf(stderr, "Failed to get %s clock : %s", clock_names[i], nvmlErrorString(result));
+            fprintf(stderr, "Failed to get %s clock : %s\n", clock_names[i], nvmlErrorString(result));
         }
     }
 
@@ -70,8 +124,9 @@ unsigned int init_clock_sensor(nvmlDevice_t device, void** data)
     return tmp.count;
 }
 
-unsigned int get_clock_sensor(nvmlDevice_t device, uint64_t *results, void* data)
+unsigned int get_clock_sensor(uint64_t *results, const Device *device, void *data)
 {
+    const nvmlDevice_t nvml_device = device->device;
     ClockData *clock_data = (ClockData *) data;
     nvmlReturn_t err;
     unsigned int clock;
@@ -79,8 +134,8 @@ unsigned int get_clock_sensor(nvmlDevice_t device, uint64_t *results, void* data
     for (unsigned int i = 0; i < clock_data->count; i++) {
         nvmlClockType_t clock_type = clock_data->clocks[i];
 
-        if((err = nvmlDeviceGetClockInfo(device, clock_type, &clock)) != NVML_SUCCESS) {
-            fprintf(stderr, "Failed to get %s clock : %s", clock_names[clock_type], nvmlErrorString(err));
+        if((err = nvmlDeviceGetClockInfo(nvml_device, clock_type, &clock)) != NVML_SUCCESS) {
+            fprintf(stderr, "Failed to get %s clock : %s\n", clock_names[clock_type], nvmlErrorString(err));
             exit(99);
         }
         results[i] = clock;
@@ -88,42 +143,69 @@ unsigned int get_clock_sensor(nvmlDevice_t device, uint64_t *results, void* data
     return clock_data->count;
 }
 
-void clean_clock_sensor(void* data)
+unsigned int label_clock_sensor(char **labels, void *data)
+{
+    ClockData *clock_data = (ClockData *) data;
+
+    for (unsigned int i = 0; i < clock_data->count; i++) {
+        labels[i] = clock_data->labels[i];
+    }
+
+    return clock_data->count;
+}
+
+void clean_clock_sensor(void *data)
 {
     free(data);
 }
 
 // ---------------------------MEMORY_SENSOR
+#define MEMORY_LABEL_SIZE 25
+
 typedef enum {
     FREE_MEMORY  = 0U,
     USED_MEMORY  = 1U,
     TOTAL_MEMORY = 2U,
- 
+
     COUNT_MEMORY = 3U,
 } MemoryKind;
-static const char *memory_names[COUNT_MEMORY] = {"Free", "Used", "Total"};
 
-unsigned int init_memory_sensor(nvmlDevice_t device, void **none)
+static const char *memory_names[COUNT_MEMORY] = {"free", "used", "total"};
+static const char *memory_base_name = "mem";
+
+typedef struct {
+    char labels[COUNT_MEMORY][MEMORY_LABEL_SIZE];
+} MemoryData;
+
+unsigned int init_memory_sensor(const Device *device, void **data)
 {
-    UNUSED(none);
+    const nvmlDevice_t nvml_device = device->device;
+    const unsigned int device_idx = device->idx;
 
     nvmlMemory_t memory;
     nvmlReturn_t result;
-    if ((result = nvmlDeviceGetMemoryInfo(device, &memory)) != NVML_SUCCESS) {
+    if ((result = nvmlDeviceGetMemoryInfo(nvml_device, &memory)) != NVML_SUCCESS) {
         fprintf(stderr, "Failed to get device memory : %s\n", nvmlErrorString(result));
         return 0;
     }
 
+    MemoryData *memory_data = (MemoryData *) calloc(1, sizeof(MemoryData));
+    for (unsigned int i = 0; i < COUNT_MEMORY; i++) {
+        snprintf(memory_data->labels[i], MEMORY_LABEL_SIZE, label_template, device_idx, memory_base_name, memory_names[i]);
+    }
+
+    *data = (void *) memory_data;
     return COUNT_MEMORY;
 }
 
-unsigned int get_memory_sensor(nvmlDevice_t device, uint64_t *results, void *none)
+unsigned int get_memory_sensor(uint64_t *results, const Device *device, void *none)
 {
     UNUSED(none);
+    const nvmlDevice_t nvml_device = device->device;
 
     nvmlMemory_t memory;
     nvmlReturn_t result;
-    if ((result = nvmlDeviceGetMemoryInfo(device, &memory)) != NVML_SUCCESS) {
+    if ((result = nvmlDeviceGetMemoryInfo(nvml_device, &memory)) != NVML_SUCCESS) {
         fprintf(stderr, "Failed to get device memory : %s\n", nvmlErrorString(result));
         exit(99);
     }
@@ -135,12 +217,23 @@ unsigned int get_memory_sensor(nvmlDevice_t device, uint64_t *results, void *non
 }
 
 
-void clean_memory_sensor(void *none)
+unsigned int label_memory_sensor(char **labels, void* data)
 {
-    UNUSED(none);
+    MemoryData *memory_data = (MemoryData *) data;
+
+    for (unsigned int i = 0; i < COUNT_MEMORY; i++) {
+        labels[i] = memory_data->labels[i];
+    }
+
+    return COUNT_MEMORY;
+}
+void clean_memory_sensor(void *data)
+{
+  free(data);
 }
 
 // ----------------------UTILIZATION_SENSOR
+#define UTILIZATION_LABEL_SIZE 35
 typedef enum {
     GPU_UTILIZATION    = 0U,
     MEMORY_UTILIZATION = 1U,
@@ -148,29 +241,42 @@ typedef enum {
     COUNT_UTILIZATION  = 2U,
 } UtilizationKind;
 
-static const char *utilization_names[COUNT_UTILIZATION] = {"Gpu", "Memory"};
+typedef struct {
+  char labels[COUNT_UTILIZATION][UTILIZATION_LABEL_SIZE];
+} UtilizationData;
+
+static const char *utilization_names[COUNT_UTILIZATION] = {"gpu", "memory"};
+static const char *utilization_base_name = "utilization";
 
-unsigned int init_utilization_sensor(nvmlDevice_t device, void **none);
+unsigned int init_utilization_sensor(const Device *device, void **data)
 {
-    UNUSED(none);
+    const nvmlDevice_t nvml_device = device->device;
+    const unsigned int device_idx = device->idx;
 
     nvmlReturn_t result;
     nvmlUtilization_t utilization;
-    if ((result = nvmlDeviceGetUtilizationRates(device, &utilization)) != NVML_SUCCESS) {
+    if ((result = nvmlDeviceGetUtilizationRates(nvml_device, &utilization)) != NVML_SUCCESS) {
         fprintf(stderr, "Failed to get device utilization: %s\n", nvmlErrorString(result));
         return 0;
     }
 
+    UtilizationData *utilization_data = (UtilizationData *) calloc(1, sizeof(UtilizationData));
+    for (unsigned int i = 0; i < COUNT_UTILIZATION; i++) {
+snprintf(utilization_data->labels[i], UTILIZATION_LABEL_SIZE, label_template, device_idx, utilization_base_name, utilization_names[i]);
+    }
+
+    *data = (void *) utilization_data;
     return COUNT_UTILIZATION;
 }
 
-unsigned int get_utilization_sensor(nvmlDevice_t device, uint64_t *results, void* none)
+unsigned int get_utilization_sensor(uint64_t *results, const Device *device, void *none)
 {
     UNUSED(none);
+    const nvmlDevice_t nvml_device = device->device;
 
     nvmlReturn_t result;
     nvmlUtilization_t utilization;
-    if ((result = nvmlDeviceGetUtilizationRates(device, &utilization)) != NVML_SUCCESS) {
+    if ((result = nvmlDeviceGetUtilizationRates(nvml_device, &utilization)) != NVML_SUCCESS) {
         fprintf(stderr, "Failed to get device utilization: %s\n", nvmlErrorString(result));
         exit(99);
     }
@@ -180,9 +286,19 @@ unsigned int get_utilization_sensor(nvmlDevice_t device, uint64_t *results, void
     return COUNT_UTILIZATION;
 }
 
-void clean_utilization_sensor(void* none)
+unsigned int label_utilization_sensor(char **labels, void* data)
 {
-    UNUSED(none);
+    UtilizationData *utilization_data = (UtilizationData *) data;
+
+    for (unsigned int i = 0; i < COUNT_UTILIZATION; i++) {
+        labels[i] = utilization_data->labels[i];
+    }
+
+    return COUNT_UTILIZATION;
+}
+void clean_utilization_sensor(void *data)
+{
+    free(data);
 }
 
 // ----------------------------ERROR_SENSOR
@@ -190,32 +306,21 @@ void clean_utilization_sensor(void* none)
 
 // ----------------------------------------
 
-typedef struct {
-    char name[NVML_DEVICE_NAME_BUFFER_SIZE];
-    nvmlDevice_t device;
-
-    ISensor sensors[COUNT_SENSOR];
-    unsigned int count;
-} Device;
-
-typedef struct {
-    Device *devices;
-    unsigned int count;
-} NvidiaSensor;
 
 // -------------------------AVAIBLE_SENSORS
 static const ISensor avaible_sensors[COUNT_SENSOR] = {
-    {.init = init_clock_sensor, .get = get_clock_sensor, .clean = clean_memory_sensor, .data = NULL};
-    {.init = init_memory_sensor, .get = get_memory_sensor, .clean = clean_memory_sensor, .data = NULL};
-    {.init = init_utilization_sensor, .get = get_utilization_sensor, .clean = clean_memory_sensor, .data = NULL};
+    {.init = init_clock_sensor, .get = get_clock_sensor, .label = label_clock_sensor, .clean = clean_clock_sensor},
+    {.init = init_memory_sensor, .get = get_memory_sensor, .label = label_memory_sensor, .clean = clean_memory_sensor},
+    {.init = init_utilization_sensor, .get = get_utilization_sensor, .label = label_utilization_sensor, .clean = clean_utilization_sensor},
 };
 
 // ------------------------DEVICE_FUNCTIONS
 
-unsigned int init_device(unsigned int device_idx, Device *device) {
+unsigned int init_device(unsigned int device_idx, Device *device)
+{
     nvmlReturn_t result;
     nvmlDevice_t nvml_device;
-    if ((result = nvmlDeviceGetByIndex(i, &nvml_device) != NVML_SUCCESS) {
+    if ((result = nvmlDeviceGetHandleByIndex(device_idx, &nvml_device)) != NVML_SUCCESS) {
         fprintf(stderr, "Failed to get device handle for device %d: %s\n", device_idx, nvmlErrorString(result));
         return 0;
     }
@@ -225,39 +330,62 @@ unsigned int init_device(unsigned int device_idx, Device *device) {
         return 0;
     }
 
-    unsigned int count = 0;
+    device->device = nvml_device;
+    device->idx = device_idx;
+
+    unsigned int sensor_count = 0;
+    unsigned int total_count = 0;
+
     for (unsigned int i = 0; i < COUNT_SENSOR; i++) {
-        void* data;
-        if (avaible_sensors.init(nvml_device, &data) != 0) {
-            ISensor *sensor = &device->sensors[count];
-            memcpy(sensor, &avaible_sensors[i], sizeof(ISensor));
-            sensor->data = data;
-            count += 1;
+        Sensor *sensor = &device->sensors[sensor_count];
+        sensor->fun = &avaible_sensors[i];
+        unsigned int count;
+
+        if ((count = sensor->fun->init(device, &sensor->data)) != 0) {
+            sensor_count += 1;
+            total_count += count;
         }
     }
 
-    device->device = nvml_device;
-    device->count = count;
-    return count;
+    device->count = sensor_count;
+    return total_count;
 }
 
-unsigned int get_device(Device *device, uint64_t *results) {
-    unsigned int count;
-    nvmlDevice_t nvml_device = device->device;
+unsigned int get_device(uint64_t *results, Device *device)
+{
+    unsigned int count = 0;
     for (unsigned int i = 0; i < device->count; i++) {
-        unsigned int result = device->sensor.get(nvml_device, &device->sensor.data, results);
+        Sensor *sensor = &device->sensors[i];
+        unsigned int result = sensor->fun->get(results, device, sensor->data);
         count += result;
         results += result;
     }
 
     return count;
 }
-void clean_device(Device *device) {
+
+unsigned int label_device(char **labels, Device *device)
+{
+    unsigned int count = 0;
+    for (unsigned int i = 0; i < device->count; i++) {
+        Sensor *sensor = &device->sensors[i];
+        unsigned int result = sensor->fun->label(labels, sensor->data);
+        labels += result;
+        count += result;
+    }
+
+    return count;
+}
+
+void clean_device(Device *device)
+{
     for (unsigned int i = 0; i < device->count; i++) {
-        device->sensor.clean(&device->sensor.data);
+        Sensor *sensor = &device->sensors[i];
+        sensor->fun->clean(sensor->data);
     }
 }
 
+
 // ------------------------NVIDIA_INTERFACE
 
 unsigned int init_nvidia_sensor(char *none, void **ptr)
@@ -278,47 +406,106 @@ unsigned int init_nvidia_sensor(char *none, void **ptr)
         exit(1);
     }
 
-    Device* devices = calloc(avaible_device_count, sizeof(Device));
+    Device *devices = calloc(avaible_device_count, sizeof(Device));
 
     unsigned int sensor_count = 0;
     unsigned int device_count = 0;
     for (unsigned int i = 0; i < avaible_device_count; i++) {
         unsigned int initialized_count;
-        if ((initialized_count = init_device(&devices[device_count])) != 0) {
+        if ((initialized_count = init_device(i, &devices[device_count])) != 0) {
             sensor_count += initialized_count;
             device_count += 1;
         }
     }
 
-    NvidiaSensor *nvidia = (NvidiaSensor*) calloc(1, sizeof(NvidiaSensor));
+    NvidiaSensor *nvidia = (NvidiaSensor *) calloc(1, sizeof(NvidiaSensor));
     nvidia->devices = devices;
     nvidia->count = device_count;
 
-    *ptr = (void*) nvidia;
-    return count;
+    *ptr = (void *) nvidia;
+    return sensor_count;
 }
 
 
-unsigned int get_nvidia_sensor(uint64_t *results, void *ptr) {
+unsigned int get_nvidia_sensor(uint64_t *results, void *ptr)
+{
     NvidiaSensor *nvidia = (NvidiaSensor *) ptr;
     unsigned count = 0;
 
-    for (unsigned int i = 0; i < nvidia.count; i++) {
-        unsigned int result = get_device(&nvidia->devices[i], results);
+    for (unsigned int i = 0; i < nvidia->count; i++) {
+        unsigned int result = get_device(results, &nvidia->devices[i]);
         results += result;
         count += result;
     }
 
     return count;
 }
-void label_nvidia_sensor(char **labels, void *ptr);
+
+unsigned int label_nvidia_sensor(char **labels, void *ptr) {
+    NvidiaSensor *nvidia = (NvidiaSensor *) ptr;
+    unsigned count = 0;
+
+    for (unsigned int i = 0; i < nvidia->count; i++) {
+        unsigned int result = label_device(labels, &nvidia->devices[i]);
+        labels += result;
+        count += result;
+    }
+
+    return count;
+}
 
 void clean_nvidia_sensor(void *ptr)
 {
     NvidiaSensor *nvidia = (NvidiaSensor *) ptr;
 
     for (unsigned int i = 0; i < nvidia->count; i++) {
-        clean_device(&nvidia->device[i]);
+        clean_device(&nvidia->devices[i]);
     }
+
+    free(nvidia->devices);
+    free(nvidia);
     nvmlShutdown();
 }
+
+// -------------------------------TEST_MAIN
+
+#ifdef __NVIDIA__MAIN__TEST
+int main()
+{
+    void *ptr = NULL;
+    char *none = NULL;
+
+    unsigned int sensor_count = init_nvidia_sensor(none, &ptr);
+
+    NvidiaSensor *nvidia = (NvidiaSensor *) ptr;
+    printf("%d\n", nvidia->count);
+    printf("%u\n", sensor_count);
+
+  
+
+    uint64_t results[sensor_count];
+    char *labels[sensor_count];
+
+    memset(results, 0, sensor_count * sizeof(uint64_t));
+    memset(labels, 0, sensor_count * sizeof(char**));
+
+
+    unsigned count_label = label_nvidia_sensor(labels, ptr);
+    unsigned count_get = get_nvidia_sensor(results, ptr);
+    printf("total : %u, get : %u, label : %u\n", sensor_count, count_get, count_label);
+
+    
+    for (unsigned int i = 0; i < sensor_count; i++) {
+        printf("%s ", labels[i]);
+    }
+    printf("\n");
+    for (unsigned int i = 0; i < sensor_count; i++) {
+        printf("%lu ", results[i]);
+    }
+    printf("\n");
+    printf("sensor_count: %d\n", sensor_count);
+
+    clean_nvidia_sensor(ptr);
+}
+#endif
+
diff --git a/src/nvidia_gpu.h b/src/nvidia_gpu.h
index e69de29..6f2419e 100644
--- a/src/nvidia_gpu.h
+++ b/src/nvidia_gpu.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_nvidia_sensor(char *, void **);
+unsigned int get_nvidia_sensor(uint64_t *results, void *);
+void clean_nvidia_sensor(void *);
+void label_nvidia_sensor(char **labels, void *);
+
+
+Sensor nvidia_gpu = {
+    .init = init_nvidia_sensor,
+    .get = get_nvidia_sensor,
+    .clean = clean_nvidia_sensor,
+    .label = label_nvidia_sensor,
+    .nb_opt = 1,
+};
+
+Optparse nvidia_gpu_opt[1] = {
+    {
+        .longname = "nvidia",
+        .shortname = 'n',
+        .argtype = OPTPARSE_NONE,
+        .usage_arg = NULL,
+        .usage_msg = "NVIDIA GPU",
+    },
+};
-- 
GitLab


From 5b6f0ec8b3ac06859e2f5294e1210ddefdb393de Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 6 Mar 2023 15:51:47 +0100
Subject: [PATCH 44/69] pedantic

---
 src/nvidia_gpu.c | 55 ++++++++++++++++++++++++++----------------------
 src/nvidia_gpu.h | 18 ++++++++--------
 2 files changed, 39 insertions(+), 34 deletions(-)

diff --git a/src/nvidia_gpu.c b/src/nvidia_gpu.c
index 22f65a1..479eecb 100644
--- a/src/nvidia_gpu.c
+++ b/src/nvidia_gpu.c
@@ -20,10 +20,14 @@
 
 #include <stdio.h>
 #include <stdint.h>
-#include <nvml.h>
 #include <stdlib.h>
 #include <string.h>
 
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpedantic"
+#include <nvml.h>
+#pragma GCC diagnostic pop
+
 #include "util.h"
 
 // -----------------------------SENSOR_KIND
@@ -36,7 +40,7 @@ typedef enum {
 } SENSOR_KIND;
 
 typedef struct Device Device;
-typedef struct NvidiaSensor NvidiaSensor;
+typedef struct NvidiaGpu NvidiaGpu;
 typedef struct ISensor ISensor;
 typedef struct Sensor Sensor;
 
@@ -69,8 +73,8 @@ struct Device {
     unsigned int count;
 };
 
-// -- NvidiaSensor: represents the devices
-struct NvidiaSensor {
+// -- NvidiaGpu: represents the devices
+struct NvidiaGpu {
     Device *devices;
     unsigned int count;
 };
@@ -217,7 +221,7 @@ unsigned int get_memory_sensor(uint64_t *results, const Device *device, void *no
 }
 
 
-unsigned int label_memory_sensor(char **labels, void* data)
+unsigned int label_memory_sensor(char **labels, void *data)
 {
     MemoryData *memory_data = (MemoryData *) data;
 
@@ -229,7 +233,7 @@ unsigned int label_memory_sensor(char **labels, void* data)
 }
 void clean_memory_sensor(void *data)
 {
-  free(data);
+    free(data);
 }
 
 // ----------------------UTILIZATION_SENSOR
@@ -242,7 +246,7 @@ typedef enum {
 } UtilizationKind;
 
 typedef struct {
-  char labels[COUNT_UTILIZATION][UTILIZATION_LABEL_SIZE];
+    char labels[COUNT_UTILIZATION][UTILIZATION_LABEL_SIZE];
 } UtilizationData;
 
 static const char *utilization_names[COUNT_UTILIZATION] = {"gpu", "memory"};
@@ -262,7 +266,7 @@ unsigned int init_utilization_sensor(const Device *device, void **data)
 
     UtilizationData *utilization_data = (UtilizationData *) calloc(1, sizeof(UtilizationData));
     for (unsigned int i = 0; i < COUNT_UTILIZATION; i++) {
-snprintf(utilization_data->labels[i], UTILIZATION_LABEL_SIZE, label_template, device_idx, utilization_base_name, utilization_names[i]);
+        snprintf(utilization_data->labels[i], UTILIZATION_LABEL_SIZE, label_template, device_idx, utilization_base_name, utilization_names[i]);
     }
 
     *data = (void *) utilization_data;
@@ -286,7 +290,7 @@ unsigned int get_utilization_sensor(uint64_t *results, const Device *device, voi
     return COUNT_UTILIZATION;
 }
 
-unsigned int label_utilization_sensor(char **labels, void* data)
+unsigned int label_utilization_sensor(char **labels, void *data)
 {
     UtilizationData *utilization_data = (UtilizationData *) data;
 
@@ -388,7 +392,7 @@ void clean_device(Device *device)
 
 // ------------------------NVIDIA_INTERFACE
 
-unsigned int init_nvidia_sensor(char *none, void **ptr)
+unsigned int init_nvidia_gpu(char *none, void **ptr)
 {
     UNUSED(none);
     UNUSED(ptr);
@@ -418,7 +422,7 @@ unsigned int init_nvidia_sensor(char *none, void **ptr)
         }
     }
 
-    NvidiaSensor *nvidia = (NvidiaSensor *) calloc(1, sizeof(NvidiaSensor));
+    NvidiaGpu *nvidia = (NvidiaGpu *) calloc(1, sizeof(NvidiaGpu));
     nvidia->devices = devices;
     nvidia->count = device_count;
 
@@ -427,9 +431,9 @@ unsigned int init_nvidia_sensor(char *none, void **ptr)
 }
 
 
-unsigned int get_nvidia_sensor(uint64_t *results, void *ptr)
+unsigned int get_nvidia_gpu(uint64_t *results, void *ptr)
 {
-    NvidiaSensor *nvidia = (NvidiaSensor *) ptr;
+    NvidiaGpu *nvidia = (NvidiaGpu *) ptr;
     unsigned count = 0;
 
     for (unsigned int i = 0; i < nvidia->count; i++) {
@@ -441,8 +445,9 @@ unsigned int get_nvidia_sensor(uint64_t *results, void *ptr)
     return count;
 }
 
-unsigned int label_nvidia_sensor(char **labels, void *ptr) {
-    NvidiaSensor *nvidia = (NvidiaSensor *) ptr;
+unsigned int label_nvidia_gpu(char **labels, void *ptr)
+{
+    NvidiaGpu *nvidia = (NvidiaGpu *) ptr;
     unsigned count = 0;
 
     for (unsigned int i = 0; i < nvidia->count; i++) {
@@ -454,9 +459,9 @@ unsigned int label_nvidia_sensor(char **labels, void *ptr) {
     return count;
 }
 
-void clean_nvidia_sensor(void *ptr)
+void clean_nvidia_gpu(void *ptr)
 {
-    NvidiaSensor *nvidia = (NvidiaSensor *) ptr;
+    NvidiaGpu *nvidia = (NvidiaGpu *) ptr;
 
     for (unsigned int i = 0; i < nvidia->count; i++) {
         clean_device(&nvidia->devices[i]);
@@ -475,26 +480,26 @@ int main()
     void *ptr = NULL;
     char *none = NULL;
 
-    unsigned int sensor_count = init_nvidia_sensor(none, &ptr);
+    unsigned int sensor_count = init_nvidia_gpu(none, &ptr);
 
-    NvidiaSensor *nvidia = (NvidiaSensor *) ptr;
+    NvidiaGpu *nvidia = (NvidiaGpu *) ptr;
     printf("%d\n", nvidia->count);
     printf("%u\n", sensor_count);
 
-  
+
 
     uint64_t results[sensor_count];
     char *labels[sensor_count];
 
     memset(results, 0, sensor_count * sizeof(uint64_t));
-    memset(labels, 0, sensor_count * sizeof(char**));
+    memset(labels, 0, sensor_count * sizeof(char **));
 
 
-    unsigned count_label = label_nvidia_sensor(labels, ptr);
-    unsigned count_get = get_nvidia_sensor(results, ptr);
+    unsigned count_label = label_nvidia_gpu(labels, ptr);
+    unsigned count_get = get_nvidia_gpu(results, ptr);
     printf("total : %u, get : %u, label : %u\n", sensor_count, count_get, count_label);
 
-    
+
     for (unsigned int i = 0; i < sensor_count; i++) {
         printf("%s ", labels[i]);
     }
@@ -505,7 +510,7 @@ int main()
     printf("\n");
     printf("sensor_count: %d\n", sensor_count);
 
-    clean_nvidia_sensor(ptr);
+    clean_nvidia_gpu(ptr);
 }
 #endif
 
diff --git a/src/nvidia_gpu.h b/src/nvidia_gpu.h
index 6f2419e..c741055 100644
--- a/src/nvidia_gpu.h
+++ b/src/nvidia_gpu.h
@@ -18,23 +18,23 @@
 
  *******************************************************/
 
-unsigned int init_nvidia_sensor(char *, void **);
-unsigned int get_nvidia_sensor(uint64_t *results, void *);
-void clean_nvidia_sensor(void *);
-void label_nvidia_sensor(char **labels, void *);
+unsigned int init_nvidia_gpu(char *, void **);
+unsigned int get_nvidia_gpu(uint64_t *results, void *);
+void clean_nvidia_gpu(void *);
+void label_nvidia_gpu(char **labels, void *);
 
 
 Sensor nvidia_gpu = {
-    .init = init_nvidia_sensor,
-    .get = get_nvidia_sensor,
-    .clean = clean_nvidia_sensor,
-    .label = label_nvidia_sensor,
+    .init = init_nvidia_gpu,
+    .get = get_nvidia_gpu,
+    .clean = clean_nvidia_gpu,
+    .label = label_nvidia_gpu,
     .nb_opt = 1,
 };
 
 Optparse nvidia_gpu_opt[1] = {
     {
-        .longname = "nvidia",
+        .longname = "nvidia-gpu",
         .shortname = 'n',
         .argtype = OPTPARSE_NONE,
         .usage_arg = NULL,
-- 
GitLab


From 5c6076ad0729836751c1a1284357d69a9e26bf46 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Tue, 7 Mar 2023 09:04:34 +0100
Subject: [PATCH 45/69] temp change of the make file

---
 makefile | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/makefile b/makefile
index a197961..81a4e41 100644
--- a/makefile
+++ b/makefile
@@ -17,9 +17,9 @@ OBJ =  \
 	$(OBJ_DIR)/util.o
 
 CC = gcc
-CPPFLAGS = -std=gnu99 -Wall -Wextra -Wpedantic -Wno-unused-function -I./lib
+CPPFLAGS = -std=gnu99 -Wall -Wextra -Wpedantic -Wno-unused-function -I./lib -I/usr/local/cuda/include
 CFLAGS = $(CPPFLAGS) -O3 -Werror
-LDFLAGS =
+LDFLAGS = -L/usr/local/cuda/lib64 -lnvidia-ml
 
 ASTYLE = astyle --style=kr -xf -s4 -k3 -n -Z -Q
 
@@ -27,7 +27,7 @@ ASTYLE = astyle --style=kr -xf -s4 -k3 -n -Z -Q
 all: $(BIN) man
 
 $(BIN): $(BIN_DIR) $(OBJ) $(OBJ_DIR)/$(BIN).o
-	$(CC) $(LDFLAGS) -o $(BIN_DIR)/$(BIN) $(OBJ) $(OBJ_DIR)/$(BIN).o
+	$(CC) -o $(BIN_DIR)/$(BIN) $(OBJ) $(OBJ_DIR)/$(BIN).o $(LDFLAGS)
 
 $(OBJ): $(OBJ_DIR)
 $(OBJ_DIR)/counters.o: $(SRC_DIR)/counters_option.h
-- 
GitLab


From 8709019f8d0c1c986ec94ce25792d7942b2ece87 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Tue, 7 Mar 2023 11:36:46 +0100
Subject: [PATCH 46/69] compare new dev name to all saved ones

---
 src/network.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/src/network.c b/src/network.c
index 33fdadf..cea2a89 100644
--- a/src/network.c
+++ b/src/network.c
@@ -64,6 +64,10 @@ static void _get_network(uint64_t *results, int *sources)
     }
 }
 
+/*
+ * read from fd len chars and store them into buf
+ * make *s points to the first occurence of c into buf
+*/
 static int strchr_refill(int fd, char *buf, int len, char **s, char c)
 {
     *s = strchr(*s, c);
@@ -152,7 +156,13 @@ unsigned int init_network(char *dev, void **ptr)
             }
 
             /* compare dev name to the previously saved one */
-            if (strncmp(start_of_dev, state->devs[state->ndev - 1], s - start_of_dev) != 0) {
+            int newdev = 1;
+            for (int i = 0; i < state->ndev && newdev; i++) {
+	            if (strncmp(start_of_dev, state->devs[i], s - start_of_dev) == 0) {
+	            	newdev = 0;
+	            }
+            }
+            if (newdev) {
                 if (state->ndev >= NB_MAX_DEV) {
                     fprintf(stderr, "Maximum amount of network devices exceeded (%d).\n", NB_MAX_DEV);
                     break;
-- 
GitLab


From 38fe56fc0d5de9d32dd906fc261eef2521f62d82 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Tue, 7 Mar 2023 12:56:44 +0100
Subject: [PATCH 47/69] debug help

---
 src/nvidia_gpu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/nvidia_gpu.c b/src/nvidia_gpu.c
index 479eecb..0be83ce 100644
--- a/src/nvidia_gpu.c
+++ b/src/nvidia_gpu.c
@@ -18,6 +18,8 @@
 
  *******************************************************/
 
+// -- test :
+// gcc -std=gnu99 -Wall -Wextra -Wpedantic -fsanitize=address -D__NVIDIA__MAIN__TEST nvidia_gpu.c -I/lib -I/usr/local/cuda/include -L/usr/local/cuda/lib64 -lnvidia-ml
 #include <stdio.h>
 #include <stdint.h>
 #include <stdlib.h>
@@ -300,6 +302,7 @@ unsigned int label_utilization_sensor(char **labels, void *data)
 
     return COUNT_UTILIZATION;
 }
+
 void clean_utilization_sensor(void *data)
 {
     free(data);
-- 
GitLab


From 2622d3c0087d88ec10da2fd87dae8d8fd4624578 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 13 Mar 2023 08:28:36 +0100
Subject: [PATCH 48/69] fix print uint64_t format

---
 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 1e08517..253711f 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -120,7 +120,7 @@ uint64_t read_msr(int fd, uint64_t msr)
 {
     uint64_t data;
     if (pread(fd, &data, sizeof data, msr) != sizeof data) {
-        fprintf(stderr, "read_msr(%ld):", msr);
+        fprintf(stderr, "read_msr(%"PRIu64"):", msr);
         perror("pread");
         exit(127);
     }
@@ -175,7 +175,7 @@ uint64_t raw_to_joule(uint64_t raw, uint64_t unit)
 void debug_print_sensor(CpuSensor *sensor)
 {
     //CASSERT(sizeof(CpuSensor) == 56, amd_rapl_c);
-    printf("cpu_id : %d, package_id : %d, core_id : %d, name : %s, fd: %d,  energy_units : %d, core_energy: %ld\n",
+    printf("cpu_id : %d, package_id : %d, core_id : %d, name : %s, fd: %d,  energy_units : %d, core_energy: %"PRIu64"\n",
            sensor->cpu_id,
            sensor->package_id,
            sensor->core_id,
-- 
GitLab


From 73936d2860b2b91689380450f438b07f2123b04b Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 13 Mar 2023 09:27:42 +0100
Subject: [PATCH 49/69] add msg

---
 src/nvidia_gpu.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/nvidia_gpu.h b/src/nvidia_gpu.h
index c741055..681a028 100644
--- a/src/nvidia_gpu.h
+++ b/src/nvidia_gpu.h
@@ -38,6 +38,6 @@ Optparse nvidia_gpu_opt[1] = {
         .shortname = 'n',
         .argtype = OPTPARSE_NONE,
         .usage_arg = NULL,
-        .usage_msg = "NVIDIA GPU",
+        .usage_msg = "provides basic gpu information",
     },
 };
-- 
GitLab


From d19aa35ecc91d47c143fd503abf5ff776eceaf48 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 13 Mar 2023 09:37:45 +0100
Subject: [PATCH 50/69] fix include

---
 src/amd_rapl.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 253711f..f08c5a7 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -25,6 +25,7 @@
 #include <string.h>
 #include <errno.h>
 #include <stdlib.h>
+#include <inttypes.h>
 
 #include "info_reader.h"
 #include "util.h"
-- 
GitLab


From bfb4c16b6334e029f1871396a200615d248004b4 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 13 Mar 2023 10:02:36 +0100
Subject: [PATCH 51/69] add the detection of nvidia

---
 configure.sh | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/configure.sh b/configure.sh
index 21c94ef..24a379d 100755
--- a/configure.sh
+++ b/configure.sh
@@ -115,6 +115,10 @@ detect_caps() {
 		[ -e "/sys/class/net/$dev" ] && hdr_whitelist="${hdr_whitelist}|network"
 	fi
 
+	if [ -e /usr/local/cuda/lib64 ] && [ -e /usr/local/cuda/include ]; then
+		hdr_whitelist="${hdr_whitelist}|nvidia_gpu"
+	fi
+
 	vendor=$(awk '/vendor_id/ {print $3; exit}' /proc/cpuinfo)
 	vendor_lc=$(echo "$vendor" | tr 'A-Z' 'a-z')
 	case $vendor_lc in
-- 
GitLab


From 1a5443e32e004050a96ad27dddfd0bfcef66d05e Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 13 Mar 2023 13:11:27 +0100
Subject: [PATCH 52/69] temperature/power

---
 src/nvidia_gpu.c | 155 +++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 137 insertions(+), 18 deletions(-)

diff --git a/src/nvidia_gpu.c b/src/nvidia_gpu.c
index 0be83ce..5f4a460 100644
--- a/src/nvidia_gpu.c
+++ b/src/nvidia_gpu.c
@@ -37,8 +37,10 @@ typedef enum {
     CLOCK_SENSOR       = 0,
     MEMORY_SENSOR      = 1,
     UTILIZATION_SENSOR = 2,
+    POWER_SENSOR       = 3,
+    TEMPERATURE_SENSOR = 4,
 
-    COUNT_SENSOR       = 3,
+    COUNT_SENSOR       = 5,
 } SENSOR_KIND;
 
 typedef struct Device Device;
@@ -83,6 +85,7 @@ struct NvidiaGpu {
 
 // -- Label template
 static const char *label_template = "gpu%u_%s_%s";
+static const char *short_label_template = "gpu%u_%s";
 
 // ----------------------------CLOCK_SENSOR
 
@@ -106,17 +109,17 @@ unsigned int init_clock_sensor(const Device *device, void **data)
     const nvmlDevice_t nvml_device = device->device;
     const unsigned int device_idx = device->idx;
     ClockData tmp = {0};
-    nvmlReturn_t result;
+    nvmlReturn_t err;
     unsigned int clock;
 
     // -- Test all clocks
     for (unsigned int i = 0; i < NVML_CLOCK_COUNT; i++) {
-        if ((result = nvmlDeviceGetClockInfo(nvml_device, clocks[i], &clock)) == NVML_SUCCESS) {
+        if ((err = nvmlDeviceGetClockInfo(nvml_device, clocks[i], &clock)) == NVML_SUCCESS) {
             snprintf(tmp.labels[tmp.count], CLOCK_LABEL_SIZE, label_template, device_idx, clock_base_name, clock_names[i]);
             tmp.clocks[tmp.count] = clocks[i];
             tmp.count += 1;
         } else {
-            fprintf(stderr, "Failed to get %s clock : %s\n", clock_names[i], nvmlErrorString(result));
+            fprintf(stderr, "Failed to get %s clock : %s\n", clock_names[i], nvmlErrorString(err));
         }
     }
 
@@ -189,9 +192,9 @@ unsigned int init_memory_sensor(const Device *device, void **data)
     const unsigned int device_idx = device->idx;
 
     nvmlMemory_t memory;
-    nvmlReturn_t result;
-    if ((result = nvmlDeviceGetMemoryInfo(nvml_device, &memory)) != NVML_SUCCESS) {
-        fprintf(stderr, "Failed to get device memory : %s\n", nvmlErrorString(result));
+    nvmlReturn_t err;
+    if ((err = nvmlDeviceGetMemoryInfo(nvml_device, &memory)) != NVML_SUCCESS) {
+        fprintf(stderr, "Failed to get device memory : %s\n", nvmlErrorString(err));
         return 0;
     }
 
@@ -210,9 +213,9 @@ unsigned int get_memory_sensor(uint64_t *results, const Device *device, void *no
     const nvmlDevice_t nvml_device = device->device;
 
     nvmlMemory_t memory;
-    nvmlReturn_t result;
-    if ((result = nvmlDeviceGetMemoryInfo(nvml_device, &memory)) != NVML_SUCCESS) {
-        fprintf(stderr, "Failed to get device memory : %s\n", nvmlErrorString(result));
+    nvmlReturn_t err;
+    if ((err = nvmlDeviceGetMemoryInfo(nvml_device, &memory)) != NVML_SUCCESS) {
+        fprintf(stderr, "Failed to get device memory : %s\n", nvmlErrorString(err));
         exit(99);
     }
 
@@ -259,10 +262,10 @@ unsigned int init_utilization_sensor(const Device *device, void **data)
     const nvmlDevice_t nvml_device = device->device;
     const unsigned int device_idx = device->idx;
 
-    nvmlReturn_t result;
+    nvmlReturn_t err;
     nvmlUtilization_t utilization;
-    if ((result = nvmlDeviceGetUtilizationRates(nvml_device, &utilization)) != NVML_SUCCESS) {
-        fprintf(stderr, "Failed to get device utilization: %s\n", nvmlErrorString(result));
+    if ((err = nvmlDeviceGetUtilizationRates(nvml_device, &utilization)) != NVML_SUCCESS) {
+        fprintf(stderr, "Failed to get device utilization: %s\n", nvmlErrorString(err));
         return 0;
     }
 
@@ -280,10 +283,10 @@ unsigned int get_utilization_sensor(uint64_t *results, const Device *device, voi
     UNUSED(none);
     const nvmlDevice_t nvml_device = device->device;
 
-    nvmlReturn_t result;
+    nvmlReturn_t err;
     nvmlUtilization_t utilization;
-    if ((result = nvmlDeviceGetUtilizationRates(nvml_device, &utilization)) != NVML_SUCCESS) {
-        fprintf(stderr, "Failed to get device utilization: %s\n", nvmlErrorString(result));
+    if ((err = nvmlDeviceGetUtilizationRates(nvml_device, &utilization)) != NVML_SUCCESS) {
+        fprintf(stderr, "Failed to get device utilization: %s\n", nvmlErrorString(err));
         exit(99);
     }
 
@@ -308,8 +311,122 @@ void clean_utilization_sensor(void *data)
     free(data);
 }
 
-// ----------------------------ERROR_SENSOR
-// TODO
+// ----------------------------POWER_SENSOR
+
+#define POWER_LABEL_SIZE 25
+#define COUNT_POWER 1
+
+static const char *power_base_name = "power";
+
+typedef struct {
+  char label[POWER_LABEL_SIZE];
+} PowerData;
+
+
+unsigned int init_power_sensor(const Device *device, void** data) {
+    const nvmlDevice_t nvml_device = device->device;
+    const unsigned int device_idx = device->idx;
+
+    unsigned int power;
+    nvmlReturn_t err;
+    if ((err = nvmlDeviceGetPowerUsage(nvml_device, &power)) != NVML_SUCCESS) {
+      printf("Failed to get the device power consumption: %s\n", nvmlErrorString(err));
+      return 0;
+    }
+
+    PowerData *power_data = (PowerData *) calloc(1, sizeof(PowerData));
+    snprintf(power_data->label, POWER_LABEL_SIZE, short_label_template, device_idx, power_base_name);
+
+    *data = (void *) power_data;
+    return COUNT_POWER;
+}
+
+unsigned int get_power_sensor(uint64_t *results, const Device *device, void *none) {
+    UNUSED(none);
+    const nvmlDevice_t nvml_device = device->device;
+
+    unsigned int power;
+    nvmlReturn_t err;
+    if ((err = nvmlDeviceGetPowerUsage(nvml_device, &power)) != NVML_SUCCESS) {
+      printf("Failed to get the device power consumption: %s\n", nvmlErrorString(err));
+      exit(99);
+    }
+
+    *results = power;
+    return COUNT_POWER;
+}
+
+unsigned int label_power_sensor(char** labels, void *data) {
+    PowerData *power_data = (PowerData *) data;
+    *labels = power_data->label;
+    return COUNT_POWER;
+}
+
+void clean_power_sensor(void *data) {
+    free(data);
+}
+
+// ----------------------TEMPERATURE_SENSOR
+
+
+#define TEMPERATURE_LABEL_SIZE 35
+#define COUNT_TEMPERATURE 1
+
+static const char *temperature_base_name = "temperature";
+
+typedef struct {
+  char label[TEMPERATURE_LABEL_SIZE];
+} TemperatureData;
+
+unsigned int init_temperature_sensor(const Device *device, void** data) {
+    const nvmlDevice_t nvml_device = device->device;
+    const unsigned int device_idx = device->idx;
+
+    unsigned int temperature;
+    nvmlReturn_t err;
+    if ((err = nvmlDeviceGetTemperature(nvml_device, NVML_TEMPERATURE_GPU, &temperature)) != NVML_SUCCESS) {
+        printf("Failed to get the device temperature: %s\n", nvmlErrorString(err));
+        return 0;
+    }
+
+    TemperatureData *temperature_data = (TemperatureData *) calloc(1, sizeof(TemperatureData));
+    snprintf(temperature_data->label, TEMPERATURE_LABEL_SIZE, short_label_template, device_idx, temperature_base_name);
+
+    *data = (void *) temperature_data;
+    return COUNT_TEMPERATURE;
+}
+
+unsigned int get_temperature_sensor(uint64_t *results, const Device *device, void *none) {
+    UNUSED(none);
+    const nvmlDevice_t nvml_device = device->device;
+
+    unsigned int temperature;
+    nvmlReturn_t err;
+    if ((err = nvmlDeviceGetTemperature(nvml_device, NVML_TEMPERATURE_GPU, &temperature)) != NVML_SUCCESS) {
+        printf("Failed to get the device temperature: %s\n", nvmlErrorString(err));
+        exit(99);
+    }
+
+    *results = temperature;
+    return COUNT_TEMPERATURE;
+}
+
+unsigned int label_temperature_sensor(char** labels, void *data) {
+    TemperatureData *temperature_data = (TemperatureData *) data;
+    *labels = temperature_data->label;
+    return COUNT_TEMPERATURE;
+}
+
+void clean_temperature_sensor(void *data) {
+    free(data);
+}
+// // Get the temperature
+// result = nvmlDeviceGetTemperature(device, NVML_TEMPERATURE_GPU, &temperature);
+// if (NVML_SUCCESS != result) {
+//   printf("Failed to get temperature for device %d: %s\n", i, nvmlErrorString(result));
+//   continue;
+// }
+// printf("\t - temperature: %u\n", temperature);
 
 // ----------------------------------------
 
@@ -319,6 +436,8 @@ static const ISensor avaible_sensors[COUNT_SENSOR] = {
     {.init = init_clock_sensor, .get = get_clock_sensor, .label = label_clock_sensor, .clean = clean_clock_sensor},
     {.init = init_memory_sensor, .get = get_memory_sensor, .label = label_memory_sensor, .clean = clean_memory_sensor},
     {.init = init_utilization_sensor, .get = get_utilization_sensor, .label = label_utilization_sensor, .clean = clean_utilization_sensor},
+    {.init = init_power_sensor, .get = get_power_sensor, .label = label_power_sensor, .clean = clean_power_sensor},
+    {.init = init_temperature_sensor, .get = get_temperature_sensor, .label = label_temperature_sensor, .clean = clean_temperature_sensor},
 };
 
 // ------------------------DEVICE_FUNCTIONS
-- 
GitLab


From 73e90167bb968cee8a90b903c829fed3da0bf812 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 13 Mar 2023 13:11:56 +0100
Subject: [PATCH 53/69] doc nvidia

---
 doc/nvidia-gpu.md | 58 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)
 create mode 100644 doc/nvidia-gpu.md

diff --git a/doc/nvidia-gpu.md b/doc/nvidia-gpu.md
new file mode 100644
index 0000000..8c54afd
--- /dev/null
+++ b/doc/nvidia-gpu.md
@@ -0,0 +1,58 @@
+# Nvidia Gpu
+
+The `nvidia-gpu` sensor provides basic information about the gpu. Depending on
+the driver version it is possible that not all sensors are supported, so an
+error message will be written to `stderr` but the execution will continue.
+
+For more information you can consult the [nvidia nvml api](https://docs.nvidia.com/deploy/index.html).
+
+## [Clock](https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceEnumvs.html#group__nvmlDeviceEnumvs_1g805c0647be9996589fc5e3f6ff680c64)
+
+All speeds are in Mhz.
+
+|Output  |Description                    |
+|--------|-------------------------------|
+|graphics|Graphics clock                 |
+|sm      |Streaming Multiprocessor clock |
+|memory  |Memory clock                   |
+|video   |Video encoder/decoder clock    |
+
+## [Memory](https://docs.nvidia.com/deploy/nvml-api/structnvmlMemory__t.html#structnvmlMemory__t)
+
+All values are in bytes.
+
+|Output  |Description                          |
+|--------|-------------------------------------|
+|free    |Unallocated device memory            |
+|used    |Sum of Reserved and Allocated memory |
+|total   |Total physical device memory         |
+
+
+## [Utilization](https://docs.nvidia.com/deploy/nvml-api/structnvmlUtilization__t.html#structnvmlUtilization__t)
+
+Utilization information for a device. Each sample period may be between 1
+second and 1/6 second, depending on the product being queried.
+
+All values are a percent of time over the past sample period.
+
+|Output  |Description          |
+|--------|---------------------|
+|gpu     | Usage of the GPU    |
+|memory  | Usage of the Memory |
+
+## [Power](https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceQueries.html#group__nvmlDeviceQueries_1g7ef7dff0ff14238d08a19ad7fb23fc87)
+
+Retrieves power usage for this GPU in milliwatts and its associated circuitry (e.g. memory)
+
+|Output  |Description              |
+|--------|-------------------------|
+|power   | Power consumption in mW |
+
+## [Temperature](https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceEnumvs.html#group__nvmlDeviceEnumvs_1g2650b526841fa38b8f293c2d509a1de0)
+
+Temperature of the GPU.
+
+|Output      |Description                 |
+|------------|----------------------------|
+|temperature | Temperature of the GPU die |
+
-- 
GitLab


From 7a99793661194c32f5b366aca7f9e2289dc7dde7 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 13 Mar 2023 13:18:49 +0100
Subject: [PATCH 54/69] fix line

---
 doc/nvidia-gpu.md | 1 -
 1 file changed, 1 deletion(-)

diff --git a/doc/nvidia-gpu.md b/doc/nvidia-gpu.md
index 8c54afd..5a5cebc 100644
--- a/doc/nvidia-gpu.md
+++ b/doc/nvidia-gpu.md
@@ -49,7 +49,6 @@ Retrieves power usage for this GPU in milliwatts and its associated circuitry (e
 |power   | Power consumption in mW |
 
 ## [Temperature](https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceEnumvs.html#group__nvmlDeviceEnumvs_1g2650b526841fa38b8f293c2d509a1de0)
-
 Temperature of the GPU.
 
 |Output      |Description                 |
-- 
GitLab


From 8e1a6b567cd3270e38f74a8290112b71da6c9feb Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 13 Mar 2023 14:08:11 +0100
Subject: [PATCH 55/69] fix name

---
 doc/{nvidia-gpu.md => nvidia_gpu.md} | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
 rename doc/{nvidia-gpu.md => nvidia_gpu.md} (97%)

diff --git a/doc/nvidia-gpu.md b/doc/nvidia_gpu.md
similarity index 97%
rename from doc/nvidia-gpu.md
rename to doc/nvidia_gpu.md
index 5a5cebc..15cc8aa 100644
--- a/doc/nvidia-gpu.md
+++ b/doc/nvidia_gpu.md
@@ -1,6 +1,6 @@
 # Nvidia Gpu
 
-The `nvidia-gpu` sensor provides basic information about the gpu. Depending on
+The `nvidia_gpu` sensor provides basic information about the gpu. Depending on
 the driver version it is possible that not all sensors are supported, so an
 error message will be written to `stderr` but the execution will continue.
 
-- 
GitLab


From 22721bfe5886ec3159ca34091e593a172511ce05 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 13 Mar 2023 14:09:41 +0100
Subject: [PATCH 56/69] format

---
 src/nvidia_gpu.c | 36 ++++++++++++++++++++++--------------
 1 file changed, 22 insertions(+), 14 deletions(-)

diff --git a/src/nvidia_gpu.c b/src/nvidia_gpu.c
index 5f4a460..17d77f5 100644
--- a/src/nvidia_gpu.c
+++ b/src/nvidia_gpu.c
@@ -319,19 +319,20 @@ void clean_utilization_sensor(void *data)
 static const char *power_base_name = "power";
 
 typedef struct {
-  char label[POWER_LABEL_SIZE];
+    char label[POWER_LABEL_SIZE];
 } PowerData;
 
 
-unsigned int init_power_sensor(const Device *device, void** data) {
+unsigned int init_power_sensor(const Device *device, void **data)
+{
     const nvmlDevice_t nvml_device = device->device;
     const unsigned int device_idx = device->idx;
 
     unsigned int power;
     nvmlReturn_t err;
     if ((err = nvmlDeviceGetPowerUsage(nvml_device, &power)) != NVML_SUCCESS) {
-      printf("Failed to get the device power consumption: %s\n", nvmlErrorString(err));
-      return 0;
+        printf("Failed to get the device power consumption: %s\n", nvmlErrorString(err));
+        return 0;
     }
 
     PowerData *power_data = (PowerData *) calloc(1, sizeof(PowerData));
@@ -341,28 +342,31 @@ unsigned int init_power_sensor(const Device *device, void** data) {
     return COUNT_POWER;
 }
 
-unsigned int get_power_sensor(uint64_t *results, const Device *device, void *none) {
+unsigned int get_power_sensor(uint64_t *results, const Device *device, void *none)
+{
     UNUSED(none);
     const nvmlDevice_t nvml_device = device->device;
 
     unsigned int power;
     nvmlReturn_t err;
     if ((err = nvmlDeviceGetPowerUsage(nvml_device, &power)) != NVML_SUCCESS) {
-      printf("Failed to get the device power consumption: %s\n", nvmlErrorString(err));
-      exit(99);
+        printf("Failed to get the device power consumption: %s\n", nvmlErrorString(err));
+        exit(99);
     }
 
     *results = power;
     return COUNT_POWER;
 }
 
-unsigned int label_power_sensor(char** labels, void *data) {
+unsigned int label_power_sensor(char **labels, void *data)
+{
     PowerData *power_data = (PowerData *) data;
     *labels = power_data->label;
     return COUNT_POWER;
 }
 
-void clean_power_sensor(void *data) {
+void clean_power_sensor(void *data)
+{
     free(data);
 }
 
@@ -375,10 +379,11 @@ void clean_power_sensor(void *data) {
 static const char *temperature_base_name = "temperature";
 
 typedef struct {
-  char label[TEMPERATURE_LABEL_SIZE];
+    char label[TEMPERATURE_LABEL_SIZE];
 } TemperatureData;
 
-unsigned int init_temperature_sensor(const Device *device, void** data) {
+unsigned int init_temperature_sensor(const Device *device, void **data)
+{
     const nvmlDevice_t nvml_device = device->device;
     const unsigned int device_idx = device->idx;
 
@@ -396,7 +401,8 @@ unsigned int init_temperature_sensor(const Device *device, void** data) {
     return COUNT_TEMPERATURE;
 }
 
-unsigned int get_temperature_sensor(uint64_t *results, const Device *device, void *none) {
+unsigned int get_temperature_sensor(uint64_t *results, const Device *device, void *none)
+{
     UNUSED(none);
     const nvmlDevice_t nvml_device = device->device;
 
@@ -411,13 +417,15 @@ unsigned int get_temperature_sensor(uint64_t *results, const Device *device, voi
     return COUNT_TEMPERATURE;
 }
 
-unsigned int label_temperature_sensor(char** labels, void *data) {
+unsigned int label_temperature_sensor(char **labels, void *data)
+{
     TemperatureData *temperature_data = (TemperatureData *) data;
     *labels = temperature_data->label;
     return COUNT_TEMPERATURE;
 }
 
-void clean_temperature_sensor(void *data) {
+void clean_temperature_sensor(void *data)
+{
     free(data);
 }
 // // Get the temperature
-- 
GitLab


From 6ac893561fca6e5b433a3b9ab779a61c11b13744 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 13 Mar 2023 14:17:48 +0100
Subject: [PATCH 57/69] add doc to "network" sensor explaining #interfaces
 hard-limit in use

---
 doc/network.md | 8 ++++++++
 1 file changed, 8 insertions(+)
 create mode 100644 doc/network.md

diff --git a/doc/network.md b/doc/network.md
new file mode 100644
index 0000000..b5d1e68
--- /dev/null
+++ b/doc/network.md
@@ -0,0 +1,8 @@
+This sensor can autodetect interfaces in use by giving the special
+interface name "X".  But the total number of interfaces it can autodetect
+is currently under a hard-limit.  This hard-limit can be changed by
+modifying this line in `src/network.c`:
+
+```c
+#define NB_MAX_DEV 8
+```
-- 
GitLab


From 1e6746bee0c8e7f867c778f50369e3a17d3f5ddb Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 13 Mar 2023 15:36:34 +0100
Subject: [PATCH 58/69] configure.sh: avoid cd(1) and ls(1) in ls_sensors()

---
 configure.sh | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/configure.sh b/configure.sh
index 747a078..203fd04 100755
--- a/configure.sh
+++ b/configure.sh
@@ -43,16 +43,16 @@ usage() {
 }
 
 ls_sensors() {
-	try cd src
+	[ -d src ] || die 'fatal: the "src" directory does not exit.'
 
 	[ -z "$hdr_whitelist" ] && hdr_whitelist='.*'
 	dprint hdr_blacklist >&2
 	dprint hdr_whitelist >&2
 
-	ls -1 *.h |
-		grep -xEv "($hdr_blacklist)\.h" |
-		grep -xE  "($hdr_whitelist)\.h" |
-		sed 's/\.h$//'
+	try find src -type f -name '*.h' |
+		sed 's,src/\(.*\)\.h,\1,' |
+		grep -xEv "($hdr_blacklist)" |
+		grep -xE  "($hdr_whitelist)"
 }
 
 # gen_sensors_h(sensor, nb_sensors)
-- 
GitLab


From 856c5a6e577428882179c3dceba4aeaf1bb7192d Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 20 Mar 2023 08:56:20 +0100
Subject: [PATCH 59/69] auto config nvidia

---
 configure.sh | 79 +++++++++++++++++++++++++++++-----------------------
 makefile     |  6 ++--
 2 files changed, 48 insertions(+), 37 deletions(-)

diff --git a/configure.sh b/configure.sh
index 24a379d..207cf07 100755
--- a/configure.sh
+++ b/configure.sh
@@ -4,12 +4,15 @@
 # Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
 try() { "$@" || die "cannot $*"; }
-die() { yell "$*"; exit 111; }
+die() {
+	yell "$*"
+	exit 111
+}
 yell() { echo "$0: $*" >&2; }
 echo() { printf '%s\n' "$*"; }
 isnum() {
 	case "${1#[+-]}" in
-	*[!0-9]*|'') return 1 ;;
+	*[!0-9]* | '') return 1 ;;
 	*) return 0 ;;
 	esac
 }
@@ -51,7 +54,7 @@ ls_sensors() {
 
 	ls -1 *.h |
 		grep -xEv "($hdr_blacklist)\.h" |
-		grep -xE  "($hdr_whitelist)\.h" |
+		grep -xE "($hdr_whitelist)\.h" |
 		sed 's/\.h$//'
 }
 
@@ -86,10 +89,10 @@ gen_sensors_h() {
 	printf '    int opt_idx = offset;\n'
 	for sensor in $sensors; do
 		cat <<-!
-		    for (int i = 0; i < ${sensor}.nb_opt; i++) {
-		        opts[opt_idx++] = ${sensor}_opt[i];
-		    }
-		    sensors[(*nb_defined)++] = ${sensor};
+			    for (int i = 0; i < ${sensor}.nb_opt; i++) {
+			        opts[opt_idx++] = ${sensor}_opt[i];
+			    }
+			    sensors[(*nb_defined)++] = ${sensor};
 		!
 	done
 	printf '    assert((offset + *nb_defined) <= len);\n'
@@ -117,6 +120,8 @@ detect_caps() {
 
 	if [ -e /usr/local/cuda/lib64 ] && [ -e /usr/local/cuda/include ]; then
 		hdr_whitelist="${hdr_whitelist}|nvidia_gpu"
+		NVML_LDFLAGS="-L/usr/local/cuda/lib64 -lnvidia-ml"
+		NVML_IFLAGS="-I/usr/local/cuda/include"
 	fi
 
 	vendor=$(awk '/vendor_id/ {print $3; exit}' /proc/cpuinfo)
@@ -140,7 +145,7 @@ detect_caps() {
 }
 
 case $1 in
---all|-a)
+--all | -a)
 	all=1
 	;;
 esac
@@ -148,30 +153,33 @@ esac
 [ "$all" ] || detect_caps
 
 [ "$all" ] ||
-while [ "$1" ]; do
-	case $1 in
-	--include|-i)
-		shift; [ "$1" ] || usage
-		hdr_whitelist="${hdr_whitelist}|${1}"
-		;;
-	--exclude|-e)
-		shift; [ "$1" ] || usage
-		hdr_blacklist="${hdr_blacklist}|${1}"
-		;;
-	--list-sensors|-l)
-		ls_sensors
-		exit 0
-		;;
-	--unique|-u)
-		shift; [ "$1" ] || usage
-		hdr_whitelist=$1
-		;;
-	--help|-h)
-		usage
-		;;
-	esac
-	shift
-done
+	while [ "$1" ]; do
+		case $1 in
+		--include | -i)
+			shift
+			[ "$1" ] || usage
+			hdr_whitelist="${hdr_whitelist}|${1}"
+			;;
+		--exclude | -e)
+			shift
+			[ "$1" ] || usage
+			hdr_blacklist="${hdr_blacklist}|${1}"
+			;;
+		--list-sensors | -l)
+			ls_sensors
+			exit 0
+			;;
+		--unique | -u)
+			shift
+			[ "$1" ] || usage
+			hdr_whitelist=$1
+			;;
+		--help | -h)
+			usage
+			;;
+		esac
+		shift
+	done
 
 sensors=$(ls_sensors)
 nb_sensors=$(echo "$sensors" | sed '/^$/d' | wc -l)
@@ -181,12 +189,13 @@ if [ "$nb_sensors" -eq 0 ]; then
 	exit 1
 fi
 
-try gen_sensors_h "$sensors" "$nb_sensors" > "$target_hdr"
-try gen_sensors_mk "$sensors" > "$target_mk"
+try gen_sensors_h "$sensors" "$nb_sensors" >"$target_hdr"
+try gen_sensors_mk "$sensors" >"$target_mk"
+try printf "LDFLAGS += %s\n" "$NVML_LDFLAGS" >>"$target_mk"
+try printf "IFLAGS += %s\n" "$NVML_IFLAGS" >>"$target_mk"
 
 printf -- 'Run `make` to build `bin/mojitos`.\n' >&2
 printf -- 'The resulting binary will have the %d following sensors:\n' "$nb_sensors" >&2
 echo "$sensors" >&2
 
 make clean >/dev/null
-
diff --git a/makefile b/makefile
index 81a4e41..1b636c4 100644
--- a/makefile
+++ b/makefile
@@ -9,6 +9,8 @@ TESTS_DIR = tests
 BIN = mojitos
 
 CAPTOR_OBJ =
+IFLAGS =
+LDFLAGS =
 
 include ./sensors.mk
 
@@ -17,9 +19,9 @@ OBJ =  \
 	$(OBJ_DIR)/util.o
 
 CC = gcc
-CPPFLAGS = -std=gnu99 -Wall -Wextra -Wpedantic -Wno-unused-function -I./lib -I/usr/local/cuda/include
+CPPFLAGS = -std=gnu99 -Wall -Wextra -Wpedantic -Wno-unused-function -I./lib $(IFLAGS)
 CFLAGS = $(CPPFLAGS) -O3 -Werror
-LDFLAGS = -L/usr/local/cuda/lib64 -lnvidia-ml
+LDFLAGS +=
 
 ASTYLE = astyle --style=kr -xf -s4 -k3 -n -Z -Q
 
-- 
GitLab


From ddbe21e68e58bc5923b17d59d64d08ae9fc45cee Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 20 Mar 2023 09:19:06 +0100
Subject: [PATCH 60/69] fix: Readme

---
 README.md | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 8c6d591..9fee622 100644
--- a/README.md
+++ b/README.md
@@ -59,11 +59,15 @@ make
 ```
 You may want to run `./configure.sh --help` to see configuration options.
 
+To use `amd_rapl` you have to load the module `msr`
+```bash
+sudo modprobe msr
+```
 To execute mojitos without being root to monitor performance counters
 ```bash
 sudo sh -c 'echo 0 >/proc/sys/kernel/perf_event_paranoid'
 ```
-To execute mohitos without being root for accessing RAPL
+To execute mojitos without being root for accessing RAPL
 ```bash
 sudo chmod a+w /sys/class/powercap/intel-rapl/*/*
 sudo chmod a+w /sys/class/powercap/intel-rapl/*/*/*
-- 
GitLab


From bd68a69a55783fe7985910fe0e3e359de7102e3c Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 20 Mar 2023 11:36:10 +0100
Subject: [PATCH 61/69] auto configure nvml

---
 configure.sh | 5 +++--
 makefile     | 8 ++++----
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/configure.sh b/configure.sh
index 207cf07..ebf6881 100755
--- a/configure.sh
+++ b/configure.sh
@@ -191,8 +191,9 @@ fi
 
 try gen_sensors_h "$sensors" "$nb_sensors" >"$target_hdr"
 try gen_sensors_mk "$sensors" >"$target_mk"
-try printf "LDFLAGS += %s\n" "$NVML_LDFLAGS" >>"$target_mk"
-try printf "IFLAGS += %s\n" "$NVML_IFLAGS" >>"$target_mk"
+
+try printf "NVML_LDFLAGS = %s\n" "$NVML_LDFLAGS" >>"$target_mk"
+try printf "NVML_IFLAGS = %s\n" "$NVML_IFLAGS" >>"$target_mk"
 
 printf -- 'Run `make` to build `bin/mojitos`.\n' >&2
 printf -- 'The resulting binary will have the %d following sensors:\n' "$nb_sensors" >&2
diff --git a/makefile b/makefile
index 1b636c4..8a3c129 100644
--- a/makefile
+++ b/makefile
@@ -9,8 +9,8 @@ TESTS_DIR = tests
 BIN = mojitos
 
 CAPTOR_OBJ =
-IFLAGS =
-LDFLAGS =
+NVML_LDFLAGS =
+NVML_IFLAGS =
 
 include ./sensors.mk
 
@@ -19,9 +19,9 @@ OBJ =  \
 	$(OBJ_DIR)/util.o
 
 CC = gcc
-CPPFLAGS = -std=gnu99 -Wall -Wextra -Wpedantic -Wno-unused-function -I./lib $(IFLAGS)
+CPPFLAGS = -std=gnu99 -Wall -Wextra -Wpedantic -Wno-unused-function -I./lib $(NVML_IFLAGS)
 CFLAGS = $(CPPFLAGS) -O3 -Werror
-LDFLAGS +=
+LDFLAGS = $(NVML_LDFLAGS)
 
 ASTYLE = astyle --style=kr -xf -s4 -k3 -n -Z -Q
 
-- 
GitLab


From a7ae9dc8fc367af447a1a76c1ba72630e893e2b4 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 20 Mar 2023 12:00:11 +0100
Subject: [PATCH 62/69] clean up

---
 src/nvidia_gpu.c | 55 +-----------------------------------------------
 1 file changed, 1 insertion(+), 54 deletions(-)

diff --git a/src/nvidia_gpu.c b/src/nvidia_gpu.c
index 17d77f5..4078002 100644
--- a/src/nvidia_gpu.c
+++ b/src/nvidia_gpu.c
@@ -18,13 +18,12 @@
 
  *******************************************************/
 
-// -- test :
-// gcc -std=gnu99 -Wall -Wextra -Wpedantic -fsanitize=address -D__NVIDIA__MAIN__TEST nvidia_gpu.c -I/lib -I/usr/local/cuda/include -L/usr/local/cuda/lib64 -lnvidia-ml
 #include <stdio.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 
+// Pedantic throws a warning in the nvml library
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wpedantic"
 #include <nvml.h>
@@ -428,16 +427,6 @@ void clean_temperature_sensor(void *data)
 {
     free(data);
 }
-// // Get the temperature
-// result = nvmlDeviceGetTemperature(device, NVML_TEMPERATURE_GPU, &temperature);
-// if (NVML_SUCCESS != result) {
-//   printf("Failed to get temperature for device %d: %s\n", i, nvmlErrorString(result));
-//   continue;
-// }
-// printf("\t - temperature: %u\n", temperature);
-
-// ----------------------------------------
-
 
 // -------------------------AVAIBLE_SENSORS
 static const ISensor avaible_sensors[COUNT_SENSOR] = {
@@ -602,45 +591,3 @@ void clean_nvidia_gpu(void *ptr)
     nvmlShutdown();
 }
 
-// -------------------------------TEST_MAIN
-
-#ifdef __NVIDIA__MAIN__TEST
-int main()
-{
-    void *ptr = NULL;
-    char *none = NULL;
-
-    unsigned int sensor_count = init_nvidia_gpu(none, &ptr);
-
-    NvidiaGpu *nvidia = (NvidiaGpu *) ptr;
-    printf("%d\n", nvidia->count);
-    printf("%u\n", sensor_count);
-
-
-
-    uint64_t results[sensor_count];
-    char *labels[sensor_count];
-
-    memset(results, 0, sensor_count * sizeof(uint64_t));
-    memset(labels, 0, sensor_count * sizeof(char **));
-
-
-    unsigned count_label = label_nvidia_gpu(labels, ptr);
-    unsigned count_get = get_nvidia_gpu(results, ptr);
-    printf("total : %u, get : %u, label : %u\n", sensor_count, count_get, count_label);
-
-
-    for (unsigned int i = 0; i < sensor_count; i++) {
-        printf("%s ", labels[i]);
-    }
-    printf("\n");
-    for (unsigned int i = 0; i < sensor_count; i++) {
-        printf("%lu ", results[i]);
-    }
-    printf("\n");
-    printf("sensor_count: %d\n", sensor_count);
-
-    clean_nvidia_gpu(ptr);
-}
-#endif
-
-- 
GitLab


From 82224cf547220db437b09b720285141c575c2982 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 20 Mar 2023 12:08:10 +0100
Subject: [PATCH 63/69] fix: usage msg

---
 src/nvidia_gpu.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/nvidia_gpu.h b/src/nvidia_gpu.h
index 681a028..1f3d053 100644
--- a/src/nvidia_gpu.h
+++ b/src/nvidia_gpu.h
@@ -38,6 +38,6 @@ Optparse nvidia_gpu_opt[1] = {
         .shortname = 'n',
         .argtype = OPTPARSE_NONE,
         .usage_arg = NULL,
-        .usage_msg = "provides basic gpu information",
+        .usage_msg = "provides basic gpu information [clocks, memory, utilization, power, temperature].",
     },
 };
-- 
GitLab


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 64/69] 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 65/69] 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 66/69] 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 67/69] 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 68/69] 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 69/69] 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