From a7c3287ae184633e49b732938eaf4d6ecfd0dd56 Mon Sep 17 00:00:00 2001 From: FlorealRISSO <floreal.risso@univ-tlse3.fr> Date: Thu, 20 Apr 2023 10:05:05 +0200 Subject: [PATCH] fix make --- README.md | 14 ++- configure.sh | 4 +- lib/info_reader.c | 146 ++++++++++++++++++++++++++ lib/info_reader.h | 236 ++++++++++-------------------------------- makefile | 15 ++- src/memory_counters.c | 180 +++++++++++++++----------------- 6 files changed, 313 insertions(+), 282 deletions(-) create mode 100644 lib/info_reader.c diff --git a/README.md b/README.md index 9fee622..4c0b186 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ The following is an exhaustive list of all the sensors (it is very likely that one will not have all the sensors activated in his build): ```bash SENSORS: --a|--amd-rapl +-r|--amd-rapl AMD RAPL -p|--perf-list <perf_list> performance counters @@ -41,8 +41,20 @@ SENSORS: system load -d|--net-dev <net_dev> network monitoring (if network_device is X, tries to detect it automatically) +-n|--nvidia-gpu + provides basic gpu information [clocks, memory, utilization, power, temperature]. -r|--intel-rapl INTEL RAPL +-c|--cpu-temp + processor temperature +-m|--memory + Retrieves information about the memory via the syscall 'sysinfo(2)'. +-M|--memory-counters <memory_list> + memory counters + memory_list is a coma separated list of memory counters. + Ex: Zswap,Zswapped +-L|--memory-list + list the available memory counters and quit ``` ## Installation Instructions diff --git a/configure.sh b/configure.sh index 56abf93..1246b0c 100755 --- a/configure.sh +++ b/configure.sh @@ -29,7 +29,7 @@ debug=0 target_hdr=src/sensors.h target_mk=sensors.mk -nonsensor='counters_option|sensors|util' +nonsensor='counters_option|memory_option|sensors|util' hdr_blacklist=$nonsensor hdr_whitelist='' @@ -157,6 +157,8 @@ detect_caps() { case $1 in --all | -a) all=1 + NVML_LDFLAGS="-L/usr/local/cuda/lib64 -lnvidia-ml" + NVML_IFLAGS="-I/usr/local/cuda/include" ;; esac diff --git a/lib/info_reader.c b/lib/info_reader.c new file mode 100644 index 0000000..d23f554 --- /dev/null +++ b/lib/info_reader.c @@ -0,0 +1,146 @@ +#include <info_reader.h> + + void set_value(Parser *parser, KeyFinder *key_finder, char *raw_value) +{ + GenericPointer address = parser->storage + (parser->storage_struct_size * parser->nb_stored); + GenericPointer value = key_finder->copy(raw_value); + key_finder->set(address, value); +} + + unsigned int match(Parser *parser, char *line, KeyFinder **key_finder, char **raw_value) +{ + for (unsigned int i = 0; i < parser->nb_keys; i++) { + KeyFinder *finder = &parser->keys[i]; + + if (start_with(finder->key, line)) { + char *value = NULL; + char *key = NULL; + + split_on_delimiter(line, finder->delimiter, &key, &value); + if ( key == NULL || value == NULL) { + return 0; + } + *key_finder = finder; + *raw_value = value; + return 1; + } + } + return 0; +} + + unsigned int move_to_next(Parser *parser) +{ + parser->nb_stored += 1; + if (parser->nb_stored >= parser->capacity) { + return 0; + } + return 1; +} + + +#define PAGE_SIZE 4096 +ssize_t buffer_getline(char **lineptr, FILE *stream) { + ssize_t num_chars_read = 0; + static char buffer[PAGE_SIZE] = {0}; + + if (!lineptr || !stream) { + return -1; + } + + while (1) { + int ch = fgetc(stream); + if (ch == EOF) { + if (num_chars_read == 0) { + return -1; + } else { + break; + } + } + + if (num_chars_read == PAGE_SIZE - 1) { + return -1; + } + + buffer[num_chars_read++] = ch; + if (ch == '\n') { + break; + } + } + + buffer[num_chars_read] = '\0'; + *lineptr = buffer; + + return num_chars_read; +} + + + unsigned int parse(Parser *parser) +{ + char *line = NULL; + ssize_t read; + unsigned int key_assigned = 0; + + while ((read = buffer_getline(&line, parser->file)) != -1) { + if (key_assigned == parser->nb_keys && read > 1) { + continue; + } else if (read == 1) { + if (!move_to_next(parser)) { + return 0; + } + key_assigned = 0; + } else { + KeyFinder *key_finder = NULL; + char *raw_value = NULL; + replace_first(line, '\n', '\0'); + if (match(parser, line, &key_finder, &raw_value)) { + set_value(parser, key_finder, raw_value); + ++key_assigned; + } + } + } + if (key_assigned > 0) { + parser->nb_stored++; + } + return 1; +} + + + + void replace_first(char *string, char from, char to) +{ + for (int i = 0; string[i] != '\0'; i++) { + if (string[i] == from) { + string[i] = to; + break; + } + } +} + + void split_on_delimiter(char *string, const char *delimiter, char **key, char **value) +{ + *key = NULL; + *value = NULL; + size_t delimiter_len = strlen(delimiter); + char *start_delimiter = strstr(string, delimiter); + if (start_delimiter != NULL) { + *start_delimiter = '\0'; + *key = string; + *value = start_delimiter + delimiter_len; + } +} + +bool start_with(const char *prefix, const char *string) +{ + if (prefix == NULL || string == NULL) { + return false; + } + + size_t prefix_len = strlen(prefix); + size_t string_len = strlen(string); + + if (string_len < prefix_len) { + return false; + } else { + return memcmp(prefix, string, prefix_len) == 0; + } +} diff --git a/lib/info_reader.h b/lib/info_reader.h index 15a077c..403bb19 100644 --- a/lib/info_reader.h +++ b/lib/info_reader.h @@ -21,36 +21,42 @@ #ifndef _INFO_READER_H #define _INFO_READER_H -#include <string.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> /** * @struct Parser * @brief The parser struct - * The struct containing all the necessary informations and functions to parse a file + * The struct containing all the necessary informations and functions to parse a + * file * - * @var storage : GenericPointer : pointer to the storage where the parsed data will be stored + * @var storage : GenericPointer : pointer to the storage where the parsed data + * will be stored * @var nb_stored : unsigned int : the number of struct stored - * @var capacity : unsigned int : the maximum number of struct that can be stored - * @var storage_struct_size : size_t : the size of the struct stored in the storage - * @var keys : KeyFinder* : pointer to an array of KeyFinder containing the possible keys + * @var capacity : unsigned int : the maximum number of struct that can be + * stored + * @var storage_struct_size : size_t : the size of the struct stored in the + * storage + * @var keys : KeyFinder* : pointer to an array of KeyFinder containing the + * possible keys * @var nb_keys : unsigned int : number of key finders * @var file : FILE* : pointer to the file that will be parsed -*/ + */ typedef struct Parser Parser; /** * @struct KeyFinder * @brief The key finder struct - * The struct containing all the necessary informations and functions to find a key in a line of text + * The struct containing all the necessary informations and functions to find a + * key in a line of text * * @var key : char* : the key to be found * @var delimiter : char* : the delimiter between the key and the value * @var copy : CopyAllocator*: the function to use to make a copy of the value * @var set : Setter*: the function to use to store the value in the storage -*/ + */ typedef struct KeyFinder KeyFinder; /** @@ -68,20 +74,24 @@ typedef struct KeyFinder KeyFinder; * @param[out] value A pointer to a char pointer where the value will be stored. * @return None. */ -static void split_on_delimiter(char *string, const char *delimiter, char **key, char **value); +void split_on_delimiter(char *string, const char *delimiter, char **key, + char **value); /** - * @brief Replace the first occurrence of a character in a string with another character. + * @brief Replace the first occurrence of a character in a string with another + * character. * - * The function takes a string and two characters as input, and replaces the first - * occurrence of the first character in the string with the second character. + * The function takes a string and two characters as input, and replaces the + * first occurrence of the first character in the string with the second + * character. * - * @param[in,out] string The input string where the replacement should take place. + * @param[in,out] string The input string where the replacement should take + * place. * @param[in] from The character to be replaced. * @param[in] to The character to replace with. * @return None. */ -static void replace_first(char *string, char from, char to); +void replace_first(char *string, char from, char to); /** * @brief Check if a string starts with a prefix. @@ -89,21 +99,25 @@ static void replace_first(char *string, char from, char to); * @param[in] prefix The prefix to check. * @param[in] string The string to check. * @return true The string starts with the prefix. - * @return false The string does not start with the prefix or one of the input pointers is NULL. + * @return false The string does not start with the prefix or one of the input + * pointers is NULL. */ -static bool start_with(const char *prefix, const char *string); +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[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. + * @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. */ -static unsigned int match(Parser *parser, char *line, KeyFinder **key_finder, char **raw_value); +unsigned int match(Parser *parser, char *line, KeyFinder **key_finder, + char **raw_value); /** * @brief Reads a line of text from a file stream and stores it in a static @@ -111,7 +125,8 @@ static unsigned int match(Parser *parser, char *line, KeyFinder **key_finder, ch * This function reads a line of text from the input stream pointed to by * 'stream'. The line of text is stored in a static buffer with a maximum size of -* PAGE_SIZE. The function updates the pointer pointed to by 'lineptr' to point to +* PAGE_SIZE. The function updates the pointer pointed to by 'lineptr' to point +to * the buffer containing the line of text. If the line of text is longer than the * buffer, the function returns -1. If an error occurs, @@ -123,174 +138,35 @@ static unsigned int match(Parser *parser, char *line, KeyFinder **key_finder, ch */ ssize_t buffer_getline(char **lineptr, FILE *stream); +/** + * @brief Parse with the configured parser. + * + * @param parser the parser. + */ +unsigned int parse(Parser *parser); + typedef size_t GenericPointer; -typedef GenericPointer (CopyAllocator) (char *string); -typedef void (Setter) (GenericPointer storage, GenericPointer value); +typedef GenericPointer(CopyAllocator)(char *string); +typedef void(Setter)(GenericPointer storage, GenericPointer value); struct KeyFinder { - char *key; - char *delimiter; + char *key; + char *delimiter; - CopyAllocator *copy; - Setter *set; + CopyAllocator *copy; + Setter *set; }; struct Parser { - GenericPointer storage; - unsigned int nb_stored; - unsigned int capacity; - size_t storage_struct_size; + GenericPointer storage; + unsigned int nb_stored; + unsigned int capacity; + size_t storage_struct_size; - KeyFinder *keys; - unsigned int nb_keys; + KeyFinder *keys; + unsigned int nb_keys; - FILE *file; + FILE *file; }; -static void set_value(Parser *parser, KeyFinder *key_finder, char *raw_value) -{ - GenericPointer address = parser->storage + (parser->storage_struct_size * parser->nb_stored); - GenericPointer value = key_finder->copy(raw_value); - key_finder->set(address, value); -} - -static unsigned int match(Parser *parser, char *line, KeyFinder **key_finder, char **raw_value) -{ - for (unsigned int i = 0; i < parser->nb_keys; i++) { - KeyFinder *finder = &parser->keys[i]; - - if (start_with(finder->key, line)) { - char *value = NULL; - char *key = NULL; - - split_on_delimiter(line, finder->delimiter, &key, &value); - if ( key == NULL || value == NULL) { - return 0; - } - *key_finder = finder; - *raw_value = value; - return 1; - } - } - return 0; -} - -static unsigned int move_to_next(Parser *parser) -{ - parser->nb_stored += 1; - if (parser->nb_stored >= parser->capacity) { - return 0; - } - return 1; -} - - -#define PAGE_SIZE 4096 -ssize_t buffer_getline(char **lineptr, FILE *stream) { - ssize_t num_chars_read = 0; - static char buffer[PAGE_SIZE] = {0}; - - if (!lineptr || !stream) { - return -1; - } - - while (1) { - int ch = fgetc(stream); - if (ch == EOF) { - if (num_chars_read == 0) { - return -1; - } else { - break; - } - } - - if (num_chars_read == PAGE_SIZE - 1) { - return -1; - } - - buffer[num_chars_read++] = ch; - if (ch == '\n') { - break; - } - } - - buffer[num_chars_read] = '\0'; - *lineptr = buffer; - - return num_chars_read; -} - - -static unsigned int parse(Parser *parser) -{ - char *line = NULL; - ssize_t read; - unsigned int key_assigned = 0; - - while ((read = buffer_getline(&line, parser->file)) != -1) { - if (key_assigned == parser->nb_keys && read > 1) { - continue; - } else if (read == 1) { - if (!move_to_next(parser)) { - return 0; - } - key_assigned = 0; - } else { - KeyFinder *key_finder = NULL; - char *raw_value = NULL; - replace_first(line, '\n', '\0'); - if (match(parser, line, &key_finder, &raw_value)) { - set_value(parser, key_finder, raw_value); - ++key_assigned; - } - } - } - if (key_assigned > 0) { - parser->nb_stored++; - } - return 1; -} - - - -static void replace_first(char *string, char from, char to) -{ - for (int i = 0; string[i] != '\0'; i++) { - if (string[i] == from) { - string[i] = to; - break; - } - } -} - -static void split_on_delimiter(char *string, const char *delimiter, char **key, char **value) -{ - *key = NULL; - *value = NULL; - size_t delimiter_len = strlen(delimiter); - char *start_delimiter = strstr(string, delimiter); - if (start_delimiter != NULL) { - *start_delimiter = '\0'; - *key = string; - *value = start_delimiter + delimiter_len; - } -} - -static bool start_with(const char *prefix, const char *string) -{ - if (prefix == NULL || string == NULL) { - return false; - } - - size_t prefix_len = strlen(prefix); - size_t string_len = strlen(string); - - if (string_len < prefix_len) { - return false; - } else { - return memcmp(prefix, string, prefix_len) == 0; - } -} - #endif - diff --git a/makefile b/makefile index 3997f40..4dcbce4 100644 --- a/makefile +++ b/makefile @@ -3,6 +3,7 @@ SRC_DIR = src DOC_DIR = doc OBJ_DIR = obj +LIB_DIR = lib BIN_DIR = bin TESTS_DIR = tests @@ -25,8 +26,9 @@ NVML_IFLAGS = include ./sensors.mk OBJ = \ - $(CAPTOR_OBJ) \ - $(OBJ_DIR)/util.o + $(OBJ_DIR)/util.o \ + $(OBJ_DIR)/info_reader.o \ + $(CAPTOR_OBJ) options: @echo BIN: $(BIN) @@ -48,6 +50,9 @@ $(OBJ_DIR)/$(BIN).o: $(SRC_DIR)/$(BIN).c $(OBJ_DIR)/util.o: $(SRC_DIR)/util.c $(SRC_DIR)/util.h $(CC) $(CFLAGS) -c $< -o $@ +$(OBJ_DIR)/info_reader.o: $(LIB_DIR)/info_reader.c + $(CC) $(CFLAGS) -c $< -o $@ + $(SRC_DIR)/counters_option.h: $(SRC_DIR)/counters_option.sh sh ./$(SRC_DIR)/counters_option.sh > $(SRC_DIR)/counters_option.h @@ -63,8 +68,8 @@ $(BIN_DIR): debug: CFLAGS = $(CPPFLAGS) -DDEBUG -g -Og debug: $(BIN) -tests: - $(CC) $(CPPFLAGS) $(TESTS_DIR)/main.c $(SRC_DIR)/util.c -o $(TESTS_DIR)/run +tests: $(OBJ_DIR)/util.o $(OBJ_DIR)/info_reader.o + $(CC) $(CPPFLAGS) $(OBJ_DIR)/util.o $(OBJ_DIR)/info_reader.o $(TESTS_DIR)/main.c -o $(TESTS_DIR)/run $(TESTS_DIR)/run format: @@ -80,7 +85,7 @@ clean: $(DOC_DIR)/test_main_ex \ $(DOC_DIR)/info_reader_ex -readme: $(BIN) +readme: sh ./tools/update-readme-usage.sh man: $(BIN) diff --git a/src/memory_counters.c b/src/memory_counters.c index 185f454..8e8e916 100644 --- a/src/memory_counters.c +++ b/src/memory_counters.c @@ -10,121 +10,111 @@ static const char *path = "/proc/meminfo"; typedef struct { - KeyFinder *keys; - unsigned int count; - FILE *file; + KeyFinder *keys; + unsigned int count; + FILE *file; } MemoryCounters; -GenericPointer long_allocator(char *s) -{ - long value = atol(s); - return (GenericPointer)value; +GenericPointer long_allocator(char *s) { + long value = atol(s); + return (GenericPointer)value; } -KeyFinder *build_keyfinder(unsigned int count, unsigned int *indexes) -{ - KeyFinder *keys = (KeyFinder *)calloc(count, sizeof(KeyFinder)); - for (unsigned int i = 0; i < count; i++) { - unsigned int idx = indexes[i]; - KeyFinder key = {.key = memory_counters[idx], - .delimiter = ":", - .copy = long_allocator, - .set = setter_functions[i] - }; - memcpy(&keys[i], &key, sizeof(KeyFinder)); - } - return keys; +KeyFinder *build_keyfinder(unsigned int count, unsigned int *indexes) { + KeyFinder *keys = (KeyFinder *)calloc(count, sizeof(KeyFinder)); + for (unsigned int i = 0; i < count; i++) { + unsigned int idx = indexes[i]; + KeyFinder key = {.key = memory_counters[idx], + .delimiter = ":", + .copy = long_allocator, + .set = setter_functions[i]}; + memcpy(&keys[i], &key, sizeof(KeyFinder)); + } + return keys; } void memory_list(char *memory_string, unsigned int *count, - unsigned int *indexes) -{ - char *token; - *count = 0; - - while ((token = strtok(memory_string, ",")) != NULL) { - memory_string = NULL; - - unsigned int i; - for (i = 0; i < NB_COUNTERS; i++) { - if (strcmp(memory_counters[i], token) == 0) { - (*count)++; - indexes[*count - 1] = i; - break; - } - } - - if (i == NB_COUNTERS) { - fprintf(stderr, "Unknown memory counter: %s\n", token); - exit(EXIT_FAILURE); - } - - if ((*count) > NB_COUNTERS) { - fprintf(stderr, "Too much counters, there are probably duplicates\n"); - exit(EXIT_FAILURE); - } + unsigned int *indexes) { + char *token; + *count = 0; + + while ((token = strtok(memory_string, ",")) != NULL) { + memory_string = NULL; + + unsigned int i; + for (i = 0; i < NB_COUNTERS; i++) { + if (strcmp(memory_counters[i], token) == 0) { + (*count)++; + indexes[*count - 1] = i; + break; + } + } + + if (i == NB_COUNTERS) { + fprintf(stderr, "Unknown memory counter: %s\n", token); + exit(EXIT_FAILURE); } + + if ((*count) > NB_COUNTERS) { + fprintf(stderr, "Too much counters, there are probably duplicates\n"); + exit(EXIT_FAILURE); + } + } } -unsigned int init_memory_counters(char *args, void **ptr) -{ - unsigned int indexes[NB_COUNTERS]; - unsigned int count = 0; - memory_list(args, &count, indexes); +unsigned int init_memory_counters(char *args, void **ptr) { + unsigned int indexes[NB_COUNTERS]; + unsigned int count = 0; + memory_list(args, &count, indexes); - KeyFinder *keys = build_keyfinder(count, indexes); - FILE *file = fopen(path, "r"); + KeyFinder *keys = build_keyfinder(count, indexes); + FILE *file = fopen(path, "r"); - MemoryCounters *counters = calloc(1, sizeof(MemoryCounters)); - counters->keys = keys; - counters->count = count; - counters->file = file; + MemoryCounters *counters = calloc(1, sizeof(MemoryCounters)); + counters->keys = keys; + counters->count = count; + counters->file = file; - *ptr = (void *)counters; - return count; + *ptr = (void *)counters; + return count; } -unsigned int get_memory_counters(uint64_t *results, void *ptr) -{ - MemoryCounters *counters = (MemoryCounters *)ptr; - fseek(counters->file, 0, SEEK_SET); - Parser parser = {.storage = (GenericPointer)results, - .capacity = 1, - .nb_stored = 0, - .storage_struct_size = sizeof(uint64_t) * counters->count, - .keys = counters->keys, - .nb_keys = counters->count, - .file = counters->file - }; - - parse(&parser); - return counters->count; +unsigned int get_memory_counters(uint64_t *results, void *ptr) { + MemoryCounters *counters = (MemoryCounters *)ptr; + fseek(counters->file, 0, SEEK_SET); + Parser parser = {.storage = (GenericPointer)results, + .capacity = 1, + .nb_stored = 0, + .storage_struct_size = sizeof(uint64_t) * counters->count, + .keys = counters->keys, + .nb_keys = counters->count, + .file = counters->file}; + + parse(&parser); + return counters->count; } -void label_memory_counters(char **labels, void *ptr) -{ - MemoryCounters *counters = (MemoryCounters *)ptr; - for (unsigned int i = 0; i < counters->count; i++) { - labels[i] = counters->keys[i].key; - } +void label_memory_counters(char **labels, void *ptr) { + MemoryCounters *counters = (MemoryCounters *)ptr; + for (unsigned int i = 0; i < counters->count; i++) { + labels[i] = counters->keys[i].key; + } } -void clean_memory_counters(void *ptr) -{ - MemoryCounters *counters = (MemoryCounters *)ptr; - fclose(counters->file); - free(counters->keys); - free(ptr); +void clean_memory_counters(void *ptr) { + MemoryCounters *counters = (MemoryCounters *)ptr; + fclose(counters->file); + free(counters->keys); + free(ptr); } -void *show_all_memory_counters(void *none1, size_t none2) -{ - for (unsigned int i = 0; i < NB_COUNTERS; i++) { - printf("%s\n", memory_counters[i]); - } +void *show_all_memory_counters(void *none1, size_t none2) { + for (unsigned int i = 0; i < NB_COUNTERS; i++) { + printf("%s\n", memory_counters[i]); + } - UNUSED(none1); - UNUSED(none2); - exit(EXIT_SUCCESS); - return NULL; /* not reached */ + UNUSED(none1); + UNUSED(none2); + exit(EXIT_SUCCESS); + return NULL; /* not reached */ } -- GitLab