[sysprof] libsysprof-capture: add metadata frame type



commit db9aea95eaf92acdf2dc87d888da7a8754c48364
Author: Christian Hergert <chergert redhat com>
Date:   Sun May 19 21:57:52 2019 -0700

    libsysprof-capture: add metadata frame type
    
    This will allow sources and aids to discover information about what was
    done between capture loading and saving.

 src/libsysprof-capture/sysprof-capture-cursor.c |  4 +++
 src/libsysprof-capture/sysprof-capture-reader.c | 39 ++++++++++++++++++++
 src/libsysprof-capture/sysprof-capture-reader.h |  2 ++
 src/libsysprof-capture/sysprof-capture-types.h  | 11 ++++++
 src/libsysprof-capture/sysprof-capture-writer.c | 45 +++++++++++++++++++++++
 src/libsysprof-capture/sysprof-capture-writer.h |  8 +++++
 src/tests/test-capture.c                        | 47 +++++++++++++++++++++++++
 src/tools/sysprof-cat.c                         | 17 +++++++++
 src/tools/sysprof-dump.c                        | 18 ++++++++--
 9 files changed, 189 insertions(+), 2 deletions(-)
---
diff --git a/src/libsysprof-capture/sysprof-capture-cursor.c b/src/libsysprof-capture/sysprof-capture-cursor.c
index 4fe7889..9cb1e31 100644
--- a/src/libsysprof-capture/sysprof-capture-cursor.c
+++ b/src/libsysprof-capture/sysprof-capture-cursor.c
@@ -159,6 +159,10 @@ sysprof_capture_cursor_foreach (SysprofCaptureCursor         *self,
           delegate = READ_DELEGATE (sysprof_capture_reader_read_counter_set);
           break;
 
+        case SYSPROF_CAPTURE_FRAME_METADATA:
+          delegate = READ_DELEGATE (sysprof_capture_reader_read_metadata);
+          break;
+
         default:
           if (!sysprof_capture_reader_skip (self->reader))
             return;
diff --git a/src/libsysprof-capture/sysprof-capture-reader.c b/src/libsysprof-capture/sysprof-capture-reader.c
index 5f609e2..e2aed4f 100644
--- a/src/libsysprof-capture/sysprof-capture-reader.c
+++ b/src/libsysprof-capture/sysprof-capture-reader.c
@@ -532,6 +532,45 @@ sysprof_capture_reader_read_mark (SysprofCaptureReader *self)
   return mark;
 }
 
+const SysprofCaptureMetadata *
+sysprof_capture_reader_read_metadata (SysprofCaptureReader *self)
+{
+  SysprofCaptureMetadata *metadata;
+
+  g_assert (self != NULL);
+  g_assert ((self->pos % SYSPROF_CAPTURE_ALIGN) == 0);
+  g_assert (self->pos <= self->bufsz);
+
+  if (!sysprof_capture_reader_ensure_space_for (self, sizeof *metadata))
+    return NULL;
+
+  metadata = (SysprofCaptureMetadata *)(gpointer)&self->buf[self->pos];
+
+  sysprof_capture_reader_bswap_frame (self, &metadata->frame);
+
+  if (metadata->frame.type != SYSPROF_CAPTURE_FRAME_METADATA)
+    return NULL;
+
+  if (metadata->frame.len < (sizeof *metadata + 1))
+    return NULL;
+
+  if (!sysprof_capture_reader_ensure_space_for (self, metadata->frame.len))
+    return NULL;
+
+  metadata = (SysprofCaptureMetadata *)(gpointer)&self->buf[self->pos];
+
+  self->pos += metadata->frame.len;
+
+  if ((self->pos % SYSPROF_CAPTURE_ALIGN) != 0)
+    return NULL;
+
+  /* Ensure trailing \0 in .id and .metadata */
+  metadata->id[sizeof metadata->id - 1] = 0;
+  self->buf[self->pos + metadata->frame.len - 1] = 0;
+
+  return metadata;
+}
+
 const SysprofCaptureProcess *
 sysprof_capture_reader_read_process (SysprofCaptureReader *self)
 {
diff --git a/src/libsysprof-capture/sysprof-capture-reader.h b/src/libsysprof-capture/sysprof-capture-reader.h
index c0c8392..5f47848 100644
--- a/src/libsysprof-capture/sysprof-capture-reader.h
+++ b/src/libsysprof-capture/sysprof-capture-reader.h
@@ -60,6 +60,8 @@ const SysprofCaptureMap                *sysprof_capture_reader_read_map
 SYSPROF_AVAILABLE_IN_ALL
 const SysprofCaptureMark               *sysprof_capture_reader_read_mark           (SysprofCaptureReader     
*self);
 SYSPROF_AVAILABLE_IN_ALL
+const SysprofCaptureMetadata           *sysprof_capture_reader_read_metadata       (SysprofCaptureReader     
*self);
+SYSPROF_AVAILABLE_IN_ALL
 const SysprofCaptureExit               *sysprof_capture_reader_read_exit           (SysprofCaptureReader     
*self);
 SYSPROF_AVAILABLE_IN_ALL
 const SysprofCaptureFork               *sysprof_capture_reader_read_fork           (SysprofCaptureReader     
*self);
diff --git a/src/libsysprof-capture/sysprof-capture-types.h b/src/libsysprof-capture/sysprof-capture-types.h
index 0608e1c..582e9f9 100644
--- a/src/libsysprof-capture/sysprof-capture-types.h
+++ b/src/libsysprof-capture/sysprof-capture-types.h
@@ -89,6 +89,7 @@ typedef enum
   SYSPROF_CAPTURE_FRAME_CTRDEF    = 8,
   SYSPROF_CAPTURE_FRAME_CTRSET    = 9,
   SYSPROF_CAPTURE_FRAME_MARK      = 10,
+  SYSPROF_CAPTURE_FRAME_METADATA  = 11,
 } SysprofCaptureFrameType;
 
 SYSPROF_ALIGNED_BEGIN(1)
@@ -239,6 +240,15 @@ typedef struct
 } SysprofCaptureMark
 SYSPROF_ALIGNED_END(1);
 
+SYSPROF_ALIGNED_BEGIN(1)
+typedef struct
+{
+  SysprofCaptureFrame frame;
+  gchar               id[40];
+  gchar               metadata[0];
+} SysprofCaptureMetadata
+SYSPROF_ALIGNED_END(1);
+
 G_STATIC_ASSERT (sizeof (SysprofCaptureFileHeader) == 256);
 G_STATIC_ASSERT (sizeof (SysprofCaptureFrame) == 24);
 G_STATIC_ASSERT (sizeof (SysprofCaptureMap) == 56);
@@ -253,6 +263,7 @@ G_STATIC_ASSERT (sizeof (SysprofCaptureCounterValues) == 96);
 G_STATIC_ASSERT (sizeof (SysprofCaptureFrameCounterDefine) == 32);
 G_STATIC_ASSERT (sizeof (SysprofCaptureFrameCounterSet) == 32);
 G_STATIC_ASSERT (sizeof (SysprofCaptureMark) == 96);
+G_STATIC_ASSERT (sizeof (SysprofCaptureMetadata) == 64);
 
 static inline gint
 sysprof_capture_address_compare (SysprofCaptureAddress a,
diff --git a/src/libsysprof-capture/sysprof-capture-writer.c b/src/libsysprof-capture/sysprof-capture-writer.c
index 6939cc8..f73895c 100644
--- a/src/libsysprof-capture/sysprof-capture-writer.c
+++ b/src/libsysprof-capture/sysprof-capture-writer.c
@@ -587,6 +587,51 @@ sysprof_capture_writer_add_mark (SysprofCaptureWriter *self,
   return TRUE;
 }
 
+gboolean
+sysprof_capture_writer_add_metadata (SysprofCaptureWriter *self,
+                                     gint64                time,
+                                     gint                  cpu,
+                                     gint32                pid,
+                                     const gchar          *id,
+                                     const gchar          *metadata,
+                                     gssize                metadata_len)
+{
+  SysprofCaptureMetadata *ev;
+  gsize len;
+
+  g_assert (self != NULL);
+  g_assert (id != NULL);
+
+  if (metadata == NULL)
+    {
+      metadata = "";
+      len = 0;
+    }
+
+  if (metadata_len < 0)
+    metadata_len = strlen (metadata);
+
+  len = sizeof *ev + metadata_len + 1;
+  ev = (SysprofCaptureMetadata *)sysprof_capture_writer_allocate (self, &len);
+  if (!ev)
+    return FALSE;
+
+  sysprof_capture_writer_frame_init (&ev->frame,
+                                     len,
+                                     cpu,
+                                     pid,
+                                     time,
+                                     SYSPROF_CAPTURE_FRAME_METADATA);
+
+  g_strlcpy (ev->id, id, sizeof ev->id);
+  memcpy (ev->metadata, metadata, metadata_len);
+  ev->metadata[metadata_len] = 0;
+
+  self->stat.frame_count[SYSPROF_CAPTURE_FRAME_METADATA]++;
+
+  return TRUE;
+}
+
 SysprofCaptureAddress
 sysprof_capture_writer_add_jitmap (SysprofCaptureWriter *self,
                                    const gchar          *name)
diff --git a/src/libsysprof-capture/sysprof-capture-writer.h b/src/libsysprof-capture/sysprof-capture-writer.h
index 47b3e3a..ebb2b8d 100644
--- a/src/libsysprof-capture/sysprof-capture-writer.h
+++ b/src/libsysprof-capture/sysprof-capture-writer.h
@@ -62,6 +62,14 @@ gboolean              sysprof_capture_writer_add_mark        (SysprofCaptureWrit
                                                               const gchar                       *name,
                                                               const gchar                       *message);
 SYSPROF_AVAILABLE_IN_ALL
+gboolean              sysprof_capture_writer_add_metadata    (SysprofCaptureWriter              *self,
+                                                              gint64                             time,
+                                                              gint                               cpu,
+                                                              gint32                             pid,
+                                                              const gchar                       *id,
+                                                              const gchar                       *metadata,
+                                                              gssize                             
metadata_len);
+SYSPROF_AVAILABLE_IN_ALL
 guint64               sysprof_capture_writer_add_jitmap      (SysprofCaptureWriter              *self,
                                                               const gchar                       *name);
 SYSPROF_AVAILABLE_IN_ALL
diff --git a/src/tests/test-capture.c b/src/tests/test-capture.c
index 5af92ba..daa25c1 100644
--- a/src/tests/test-capture.c
+++ b/src/tests/test-capture.c
@@ -607,6 +607,52 @@ test_reader_writer_mark (void)
   g_unlink ("mark1.syscap");
 }
 
+static void
+test_reader_writer_metadata (void)
+{
+  SysprofCaptureWriter *writer;
+  SysprofCaptureReader *reader;
+  const SysprofCaptureMetadata *metadata;
+  SysprofCaptureFrameType type;
+  GError *error = NULL;
+  gint r;
+
+  writer = sysprof_capture_writer_new ("metadata1.syscap", 0);
+
+#define STR1 "[Something]\nhere=1\n"
+#define STR2 "[and]\nthere=2\n"
+
+  sysprof_capture_writer_add_metadata (writer, SYSPROF_CAPTURE_CURRENT_TIME, -1, -1, "aid.cpu", STR1, -1);
+  sysprof_capture_writer_add_metadata (writer, SYSPROF_CAPTURE_CURRENT_TIME, -1, -1, "aid.mem", STR2, strlen 
(STR2));
+
+  g_clear_pointer (&writer, sysprof_capture_writer_unref);
+
+  reader = sysprof_capture_reader_new ("metadata1.syscap", &error);
+  g_assert_no_error (error);
+  g_assert (reader != NULL);
+
+  metadata = sysprof_capture_reader_read_metadata (reader);
+  g_assert_nonnull (metadata);
+  g_assert_cmpstr (metadata->id, ==, "aid.cpu");
+  g_assert_cmpstr (metadata->metadata, ==, STR1);
+  g_assert_cmpint (metadata->frame.time, >, 0);
+  g_assert_cmpint (metadata->frame.cpu, ==, -1);
+
+  metadata = sysprof_capture_reader_read_metadata (reader);
+  g_assert_nonnull (metadata);
+  g_assert_cmpstr (metadata->id, ==, "aid.mem");
+  g_assert_cmpstr (metadata->metadata, ==, STR2);
+  g_assert_cmpint (metadata->frame.time, >, 0);
+  g_assert_cmpint (metadata->frame.cpu, ==, -1);
+
+  r = sysprof_capture_reader_peek_type (reader, &type);
+  g_assert_cmpint (r, ==, FALSE);
+
+  g_clear_pointer (&reader, sysprof_capture_reader_unref);
+
+  g_unlink ("metadata1.syscap");
+}
+
 int
 main (int argc,
       char *argv[])
@@ -617,5 +663,6 @@ main (int argc,
   g_test_add_func ("/SysprofCapture/Writer/splice", test_writer_splice);
   g_test_add_func ("/SysprofCapture/Reader/splice", test_reader_splice);
   g_test_add_func ("/SysprofCapture/ReaderWriter/mark", test_reader_writer_mark);
+  g_test_add_func ("/SysprofCapture/ReaderWriter/metadata", test_reader_writer_metadata);
   return g_test_run ();
 }
diff --git a/src/tools/sysprof-cat.c b/src/tools/sysprof-cat.c
index f72718d..e236990 100644
--- a/src/tools/sysprof-cat.c
+++ b/src/tools/sysprof-cat.c
@@ -272,6 +272,23 @@ main (gint   argc,
                 break;
               }
 
+            case SYSPROF_CAPTURE_FRAME_METADATA:
+              {
+                const SysprofCaptureMetadata *frame;
+
+                if (!(frame = sysprof_capture_reader_read_metadata (reader)))
+                  goto panic;
+
+                sysprof_capture_writer_add_metadata (writer,
+                                                     frame->frame.time,
+                                                     frame->frame.cpu,
+                                                     frame->frame.pid,
+                                                     frame->id,
+                                                     frame->metadata,
+                                                     frame->frame.len - G_STRUCT_OFFSET 
(SysprofCaptureMetadata, metadata));
+                break;
+              }
+
             case SYSPROF_CAPTURE_FRAME_JITMAP:
               {
                 GHashTable *jitmap;
diff --git a/src/tools/sysprof-dump.c b/src/tools/sysprof-dump.c
index 1e81bb0..270bf65 100644
--- a/src/tools/sysprof-dump.c
+++ b/src/tools/sysprof-dump.c
@@ -130,8 +130,8 @@ main (gint argc,
             gdouble ptime = (mark->frame.time - begin_time) / (gdouble)NSEC_PER_SEC;
 
             g_print ("MARK: pid=%d time=%"G_GINT64_FORMAT" (%lf)\n"
-                     "   group  = %s\n"
-                     "    name  = %s\n"
+                     "    group = %s\n"
+                     "     name = %s\n"
                      " duration = %"G_GUINT64_FORMAT"\n"
                      "  message = %s\n",
                      mark->frame.pid, mark->frame.time, ptime,
@@ -140,6 +140,20 @@ main (gint argc,
             break;
           }
 
+        case SYSPROF_CAPTURE_FRAME_METADATA:
+          {
+            const SysprofCaptureMetadata *metadata = sysprof_capture_reader_read_metadata (reader);
+            gdouble ptime = (metadata->frame.time - begin_time) / (gdouble)NSEC_PER_SEC;
+
+            g_print ("METADATA: pid=%d time=%"G_GINT64_FORMAT" (%lf)\n"
+                     "       id = %s\n"
+                     "\"\"\"\n%s\n\"\"\"",
+                     metadata->frame.pid, metadata->frame.time, ptime,
+                     metadata->id, metadata->metadata);
+
+            break;
+          }
+
         case SYSPROF_CAPTURE_FRAME_PROCESS:
           {
             const SysprofCaptureProcess *pr = sysprof_capture_reader_read_process (reader);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]