Skip to content
Snippets Groups Projects
Commit 4c313748 authored by Georges Da Costa's avatar Georges Da Costa
Browse files

Merge branch 'pr_memory' into 'pr_nvidia'

Simple memory sensor

See merge request !6
parents 019f3add b4a463d6
No related branches found
No related tags found
3 merge requests!9fix sensor example (doc),!6Simple memory sensor,!5Add dev name to labels
Pipeline #5436 failed
......@@ -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"
......
......@@ -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 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");
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\n");
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)) {
......
/*******************************************************
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;
}
/*******************************************************
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)'.",
},
};
......@@ -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);
})
/*******************************************************
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);
})
......@@ -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);
......
......@@ -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);
})
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment