mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2026-03-17 18:51:27 +00:00
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.
This commit is contained in:
@ -39,6 +39,7 @@ struct _SpCaptureReader
|
|||||||
int fd;
|
int fd;
|
||||||
gint endian;
|
gint endian;
|
||||||
SpCaptureFileHeader header;
|
SpCaptureFileHeader header;
|
||||||
|
gint64 end_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef SP_DISABLE_GOBJECT
|
#ifndef SP_DISABLE_GOBJECT
|
||||||
@ -297,6 +298,9 @@ sp_capture_reader_peek_frame (SpCaptureReader *self,
|
|||||||
|
|
||||||
sp_capture_reader_bswap_frame (self, frame);
|
sp_capture_reader_bswap_frame (self, frame);
|
||||||
|
|
||||||
|
if (frame->time > self->end_time)
|
||||||
|
self->end_time = frame->time;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -813,6 +817,36 @@ sp_capture_reader_get_start_time (SpCaptureReader *self)
|
|||||||
return self->header.time;
|
return self->header.time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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:
|
* sp_capture_reader_copy:
|
||||||
*
|
*
|
||||||
|
|||||||
@ -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_filename (SpCaptureReader *self);
|
||||||
const gchar *sp_capture_reader_get_time (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_start_time (SpCaptureReader *self);
|
||||||
|
gint64 sp_capture_reader_get_end_time (SpCaptureReader *self);
|
||||||
gboolean sp_capture_reader_skip (SpCaptureReader *self);
|
gboolean sp_capture_reader_skip (SpCaptureReader *self);
|
||||||
gboolean sp_capture_reader_peek_type (SpCaptureReader *self,
|
gboolean sp_capture_reader_peek_type (SpCaptureReader *self,
|
||||||
SpCaptureFrameType *type);
|
SpCaptureFrameType *type);
|
||||||
|
|||||||
@ -78,7 +78,8 @@ typedef struct
|
|||||||
guint32 padding : 23;
|
guint32 padding : 23;
|
||||||
gchar capture_time[64];
|
gchar capture_time[64];
|
||||||
gint64 time;
|
gint64 time;
|
||||||
gchar suffix[176];
|
gint64 end_time;
|
||||||
|
gchar suffix[168];
|
||||||
} SpCaptureFileHeader;
|
} SpCaptureFileHeader;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|||||||
@ -62,7 +62,6 @@ struct _SpCaptureWriter
|
|||||||
* alinged for the write buffer. This improves the performance of large
|
* alinged for the write buffer. This improves the performance of large
|
||||||
* writes to the target file-descriptor.
|
* writes to the target file-descriptor.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
volatile gint ref_count;
|
volatile gint ref_count;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -397,6 +396,7 @@ sp_capture_writer_new_from_fd (int fd,
|
|||||||
header->padding = 0;
|
header->padding = 0;
|
||||||
g_strlcpy (header->capture_time, nowstr, sizeof header->capture_time);
|
g_strlcpy (header->capture_time, nowstr, sizeof header->capture_time);
|
||||||
header->time = SP_CAPTURE_CURRENT_TIME;
|
header->time = SP_CAPTURE_CURRENT_TIME;
|
||||||
|
header->end_time = 0;
|
||||||
memset (header->suffix, 0, sizeof header->suffix);
|
memset (header->suffix, 0, sizeof header->suffix);
|
||||||
|
|
||||||
self->pos += sizeof *header;
|
self->pos += sizeof *header;
|
||||||
@ -710,13 +710,31 @@ sp_capture_writer_add_timestamp (SpCaptureWriter *self,
|
|||||||
return TRUE;
|
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
|
gboolean
|
||||||
sp_capture_writer_flush (SpCaptureWriter *self)
|
sp_capture_writer_flush (SpCaptureWriter *self)
|
||||||
{
|
{
|
||||||
g_assert (self != NULL);
|
g_assert (self != NULL);
|
||||||
|
|
||||||
return (sp_capture_writer_flush_jitmap (self) &&
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -50,6 +50,9 @@ test_reader_basic (void)
|
|||||||
|
|
||||||
sp_capture_writer_flush (writer);
|
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++)
|
for (i = 0; i < 100; i++)
|
||||||
{
|
{
|
||||||
SpCaptureFrameType type = -1;
|
SpCaptureFrameType type = -1;
|
||||||
@ -75,6 +78,11 @@ test_reader_basic (void)
|
|||||||
g_assert_cmpstr (map->filename, ==, str);
|
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++)
|
for (i = 0; i < 100; i++)
|
||||||
{
|
{
|
||||||
r = sp_capture_writer_add_timestamp (writer, t, i, -1);
|
r = sp_capture_writer_add_timestamp (writer, t, i, -1);
|
||||||
|
|||||||
Reference in New Issue
Block a user