vppinfra: add unformat_init_path 30/39330/3
authorDamjan Marion <damarion@cisco.com>
Sun, 6 Aug 2023 18:39:38 +0000 (20:39 +0200)
committerFlorin Coras <florin.coras@gmail.com>
Mon, 7 Aug 2023 17:33:09 +0000 (17:33 +0000)
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 <damarion@cisco.com>
src/vppinfra/cpu.c
src/vppinfra/format.h
src/vppinfra/time.c
src/vppinfra/unformat.c

index 735a183..b66dd49 100644 (file)
@@ -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)\
index 7254031..cf5e1f6 100644 (file)
@@ -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);
index 3377828..5a6aaf1 100644 (file)
@@ -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;
 }
 
index a07f4e0..cea5b67 100644 (file)
@@ -36,6 +36,7 @@
 */
 
 #include <vppinfra/format.h>
+#include <fcntl.h>
 
 /* 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)