[sysprof/wip/visualizers] capture: add end time for captures



commit 2197a0c02e5d7f7193e93f4688acf26606e28f88
Author: Christian Hergert <chergert redhat com>
Date:   Tue Sep 27 21:24:33 2016 -0700

    capture: add end time for captures
    
    Update the end time when we flush the buffer to disk. Also add
    a way to either incrementally get the end time or rely on the
    header when possible.

 lib/sp-capture-reader.c |   34 ++++++++++++++++++++++++++++++++++
 lib/sp-capture-reader.h |    1 +
 lib/sp-capture-types.h  |    3 ++-
 lib/sp-capture-writer.c |   22 ++++++++++++++++++++--
 tests/test-capture.c    |    8 ++++++++
 5 files changed, 65 insertions(+), 3 deletions(-)
---
diff --git a/lib/sp-capture-reader.c b/lib/sp-capture-reader.c
index 3c845d5..e50971f 100644
--- a/lib/sp-capture-reader.c
+++ b/lib/sp-capture-reader.c
@@ -39,6 +39,7 @@ struct _SpCaptureReader
   int                  fd;
   gint                 endian;
   SpCaptureFileHeader  header;
+  gint64               end_time;
 };
 
 #ifndef SP_DISABLE_GOBJECT
@@ -297,6 +298,9 @@ sp_capture_reader_peek_frame (SpCaptureReader *self,
 
   sp_capture_reader_bswap_frame (self, frame);
 
+  if (frame->time > self->end_time)
+    self->end_time = frame->time;
+
   return TRUE;
 }
 
@@ -814,6 +818,36 @@ sp_capture_reader_get_start_time (SpCaptureReader *self)
 }
 
 /**
+ * sp_capture_reader_get_end_time:
+ *
+ * This function will return the end time for the capture, which is the
+ * same as the last event added to the capture.
+ *
+ * If the end time has been stored in the capture header, that will be used.
+ * Otherwise, the time is discovered from the last capture frame and therefore
+ * the caller must have read all frames to ensure this value is accurate.
+ *
+ * Captures created by sysprof versions containing this API will have the
+ * end time set if the output capture file-descriptor supports seeking.
+ *
+ * Since: 3.22.1
+ */
+gint64
+sp_capture_reader_get_end_time (SpCaptureReader *self)
+{
+  g_return_val_if_fail (self != NULL, 0);
+
+  if (self->header.end_time != 0)
+    {
+      if (self->endian != G_BYTE_ORDER)
+        return GUINT64_SWAP_LE_BE (self->header.end_time);
+      return self->header.end_time;
+    }
+
+  return self->end_time;
+}
+
+/**
  * sp_capture_reader_copy:
  *
  * This function makes a copy of the reader. Since readers use
diff --git a/lib/sp-capture-reader.h b/lib/sp-capture-reader.h
index bf1d152..8bf096e 100644
--- a/lib/sp-capture-reader.h
+++ b/lib/sp-capture-reader.h
@@ -35,6 +35,7 @@ void                               sp_capture_reader_unref               (SpCapt
 const gchar                       *sp_capture_reader_get_filename        (SpCaptureReader     *self);
 const gchar                       *sp_capture_reader_get_time            (SpCaptureReader     *self);
 gint64                             sp_capture_reader_get_start_time      (SpCaptureReader     *self);
+gint64                             sp_capture_reader_get_end_time        (SpCaptureReader     *self);
 gboolean                           sp_capture_reader_skip                (SpCaptureReader     *self);
 gboolean                           sp_capture_reader_peek_type           (SpCaptureReader     *self,
                                                                           SpCaptureFrameType  *type);
diff --git a/lib/sp-capture-types.h b/lib/sp-capture-types.h
index 65d6b69..94ed1ec 100644
--- a/lib/sp-capture-types.h
+++ b/lib/sp-capture-types.h
@@ -78,7 +78,8 @@ typedef struct
   guint32 padding : 23;
   gchar   capture_time[64];
   gint64  time;
-  gchar   suffix[176];
+  gint64  end_time;
+  gchar   suffix[168];
 } SpCaptureFileHeader;
 
 typedef struct
diff --git a/lib/sp-capture-writer.c b/lib/sp-capture-writer.c
index 4570aea..087d67b 100644
--- a/lib/sp-capture-writer.c
+++ b/lib/sp-capture-writer.c
@@ -62,7 +62,6 @@ struct _SpCaptureWriter
    * alinged for the write buffer. This improves the performance of large
    * writes to the target file-descriptor.
    */
-
   volatile gint ref_count;
 
   /*
@@ -397,6 +396,7 @@ sp_capture_writer_new_from_fd (int   fd,
   header->padding = 0;
   g_strlcpy (header->capture_time, nowstr, sizeof header->capture_time);
   header->time = SP_CAPTURE_CURRENT_TIME;
+  header->end_time = 0;
   memset (header->suffix, 0, sizeof header->suffix);
 
   self->pos += sizeof *header;
@@ -710,13 +710,31 @@ sp_capture_writer_add_timestamp (SpCaptureWriter *self,
   return TRUE;
 }
 
+static gboolean
+sp_capture_writer_flush_end_time (SpCaptureWriter *self)
+{
+  gint64 end_time = SP_CAPTURE_CURRENT_TIME;
+
+  g_assert (self != NULL);
+
+  /* This field is opportunistic, so a failure is okay. */
+
+  pwrite (self->fd,
+          &end_time,
+          sizeof (end_time),
+          G_STRUCT_OFFSET (SpCaptureFileHeader, end_time));
+
+  return TRUE;
+}
+
 gboolean
 sp_capture_writer_flush (SpCaptureWriter *self)
 {
   g_assert (self != NULL);
 
   return (sp_capture_writer_flush_jitmap (self) &&
-          sp_capture_writer_flush_data (self));
+          sp_capture_writer_flush_data (self) &&
+          sp_capture_writer_flush_end_time (self));
 }
 
 /**
diff --git a/tests/test-capture.c b/tests/test-capture.c
index 635dde1..80739c6 100644
--- a/tests/test-capture.c
+++ b/tests/test-capture.c
@@ -50,6 +50,9 @@ test_reader_basic (void)
 
   sp_capture_writer_flush (writer);
 
+  /* We should have an old header (without end time) */
+  g_assert_cmpint (0, ==, sp_capture_reader_get_end_time (reader));
+
   for (i = 0; i < 100; i++)
     {
       SpCaptureFrameType type = -1;
@@ -75,6 +78,11 @@ test_reader_basic (void)
       g_assert_cmpstr (map->filename, ==, str);
     }
 
+  /* Now that we have read a frame, we should start having updated
+   * end times with each incoming frame.
+   */
+  g_assert_cmpint (0, !=, sp_capture_reader_get_end_time (reader));
+
   for (i = 0; i < 100; i++)
     {
       r = sp_capture_writer_add_timestamp (writer, t, i, -1);


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