From 8d0c0c68215a2972053ba7fd8fa0f82aa14f8624 Mon Sep 17 00:00:00 2001 From: Damjan Marion Date: Sun, 6 Aug 2023 20:39:38 +0200 Subject: vppinfra: add unformat_init_path More conveninet way to unformat file by providing filesystem path. Takes format string for easier constuction of path... Type: improvement Change-Id: I433204fa20dc98e2b11c53914883d047a7fc62c6 Signed-off-by: Damjan Marion --- src/vppinfra/cpu.c | 36 +++++++++++++++++----------------- src/vppinfra/format.h | 12 ++++++++++-- src/vppinfra/time.c | 51 ++++++++++++++++++++++--------------------------- src/vppinfra/unformat.c | 33 ++++++++++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 49 deletions(-) diff --git a/src/vppinfra/cpu.c b/src/vppinfra/cpu.c index 735a1830a48..b66dd4968ad 100644 --- a/src/vppinfra/cpu.c +++ b/src/vppinfra/cpu.c @@ -129,30 +129,28 @@ format(s, "[0x%x] %s ([0x%02x] %s) stepping 0x%x", f, a, m, c, stepping); return format (s, "unknown (family 0x%02x model 0x%02x)", family, model); #elif __aarch64__ - int fd; unformat_input_t input; u32 implementer, primary_part_number, variant, revision; - fd = open ("/proc/cpuinfo", 0); - if (fd < 0) - return format (s, "unknown"); - - unformat_init_clib_file (&input, fd); - while (unformat_check_input (&input) != UNFORMAT_END_OF_INPUT) + if (unformat_init_file (&input, "/proc/cpuinfo")) { - if (unformat (&input, "CPU implementer%_: 0x%x", &implementer)) - ; - else if (unformat (&input, "CPU part%_: 0x%x", &primary_part_number)) - ; - else if (unformat (&input, "CPU variant%_: 0x%x", &variant)) - ; - else if (unformat (&input, "CPU revision%_: %u", &revision)) - ; - else - unformat_skip_line (&input); + while (unformat_check_input (&input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (&input, "CPU implementer%_: 0x%x", &implementer)) + ; + else if (unformat (&input, "CPU part%_: 0x%x", &primary_part_number)) + ; + else if (unformat (&input, "CPU variant%_: 0x%x", &variant)) + ; + else if (unformat (&input, "CPU revision%_: %u", &revision)) + ; + else + unformat_skip_line (&input); + } + unformat_free (&input); } - unformat_free (&input); - close (fd); + else + return format (s, "unknown"); #define _(i,p,a,c,_format) if ((implementer == i) && (primary_part_number == p)){ \ if (_format)\ diff --git a/src/vppinfra/format.h b/src/vppinfra/format.h index 7254031a0ea..cf5e1f6dcce 100644 --- a/src/vppinfra/format.h +++ b/src/vppinfra/format.h @@ -133,8 +133,11 @@ typedef struct _unformat_input_t (and argument). */ uword (*fill_buffer) (struct _unformat_input_t * i); - /* Return values for fill buffer function which indicate whether not - input has been exhausted. */ + /* User's function to be called on input_free */ + void (*free) (struct _unformat_input_t *i); + + /* Return values for fill buffer function which indicate whether not + input has been exhausted. */ #define UNFORMAT_END_OF_INPUT (~0) #define UNFORMAT_MORE_INPUT 0 @@ -155,6 +158,8 @@ unformat_init (unformat_input_t * i, always_inline void unformat_free (unformat_input_t * i) { + if (i->free) + i->free (i); vec_free (i->buffer); vec_free (i->buffer_marks); clib_memset (i, 0, sizeof (i[0])); @@ -336,6 +341,9 @@ u8 *format_uword_bitmap (u8 *s, va_list *va); /* Setup input from Unix file. */ void unformat_init_clib_file (unformat_input_t * input, int file_descriptor); +/* Setup input from flesystem path. */ +uword unformat_init_file (unformat_input_t *input, char *fmt, ...); + /* Take input from Unix environment variable; returns 1 if variable exists zero otherwise. */ uword unformat_init_unix_env (unformat_input_t * input, char *var); diff --git a/src/vppinfra/time.c b/src/vppinfra/time.c index 3377828bbc5..5a6aaf182e4 100644 --- a/src/vppinfra/time.c +++ b/src/vppinfra/time.c @@ -74,7 +74,6 @@ clock_frequency_from_proc_filesystem (void) { f64 cpu_freq = 1e9; /* better than 40... */ f64 ppc_timebase = 0; /* warnings be gone */ - int fd; unformat_input_t input; /* $$$$ aarch64 kernel doesn't report "cpu MHz" */ @@ -83,26 +82,24 @@ clock_frequency_from_proc_filesystem (void) #endif cpu_freq = 0; - fd = open ("/proc/cpuinfo", 0); - if (fd < 0) - return cpu_freq; - - unformat_init_clib_file (&input, fd); ppc_timebase = 0; - while (unformat_check_input (&input) != UNFORMAT_END_OF_INPUT) + if (unformat_init_file (&input, "/proc/cpuinfo")) { - if (unformat (&input, "cpu MHz : %f", &cpu_freq)) - cpu_freq *= 1e6; - else if (unformat (&input, "timebase : %f", &ppc_timebase)) - ; - else - unformat_skip_line (&input); - } - - unformat_free (&input); + while (unformat_check_input (&input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (&input, "cpu MHz : %f", &cpu_freq)) + cpu_freq *= 1e6; + else if (unformat (&input, "timebase : %f", &ppc_timebase)) + ; + else + unformat_skip_line (&input); + } - close (fd); + unformat_free (&input); + } + else + return cpu_freq; /* Override CPU frequency with time base for PPC. */ if (ppc_timebase != 0) @@ -117,21 +114,19 @@ static f64 clock_frequency_from_sys_filesystem (void) { f64 cpu_freq = 0.0; - int fd; unformat_input_t input; /* Time stamp always runs at max frequency. */ cpu_freq = 0; - fd = open ("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", 0); - if (fd < 0) - goto done; - - unformat_init_clib_file (&input, fd); - (void) unformat (&input, "%f", &cpu_freq); - cpu_freq *= 1e3; /* measured in kHz */ - unformat_free (&input); - close (fd); -done: + + if (unformat_init_file ( + &input, "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq")) + { + if (unformat (&input, "%f", &cpu_freq)) + cpu_freq *= 1e3; /* measured in kHz */ + unformat_free (&input); + } + return cpu_freq; } diff --git a/src/vppinfra/unformat.c b/src/vppinfra/unformat.c index a07f4e06df5..cea5b677dec 100644 --- a/src/vppinfra/unformat.c +++ b/src/vppinfra/unformat.c @@ -36,6 +36,7 @@ */ #include +#include /* Call user's function to fill input buffer. */ __clib_export uword @@ -1045,6 +1046,13 @@ clib_file_fill_buffer (unformat_input_t * input) return input->index; } +static void +unformat_close_fd (unformat_input_t *input) +{ + int fd = pointer_to_uword (input->fill_buffer_arg); + close (fd); +} + __clib_export void unformat_init_clib_file (unformat_input_t * input, int file_descriptor) { @@ -1052,6 +1060,31 @@ unformat_init_clib_file (unformat_input_t * input, int file_descriptor) uword_to_pointer (file_descriptor, void *)); } +__clib_export uword +unformat_init_file (unformat_input_t *input, char *fmt, ...) +{ + va_list va; + u8 *path; + int fd; + + va_start (va, fmt); + path = va_format (0, fmt, &va); + va_end (va); + vec_add1 (path, 0); + + fd = open ((char *) path, 0); + vec_free (path); + + if (fd >= 0) + { + unformat_init (input, clib_file_fill_buffer, + uword_to_pointer (fd, void *)); + input->free = unformat_close_fd; + return 1; + } + return 0; +} + /* Take input from Unix environment variable. */ uword unformat_init_unix_env (unformat_input_t * input, char *var) -- cgit 1.2.3-korg