mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2025-12-31 20:36:25 +00:00
capture: add simple mark support
The goal here is to have an API that allows us to record things like frame timing data. We might iterate on this API a bit, but this gets us started. A SpCaptureMark with a zero duration should be treated like an epoch mark once a visualizer is created. SpCaptureMark with a non-zero duration should be treated like a begin/end of operation. This may be useful in generating something like a flame graph.
This commit is contained in:
@ -99,6 +99,10 @@ sp_capture_cursor_foreach (SpCaptureCursor *self,
|
||||
delegate = READ_DELEGATE (sp_capture_reader_read_map);
|
||||
break;
|
||||
|
||||
case SP_CAPTURE_FRAME_MARK:
|
||||
delegate = READ_DELEGATE (sp_capture_reader_read_mark);
|
||||
break;
|
||||
|
||||
case SP_CAPTURE_FRAME_PROCESS:
|
||||
delegate = READ_DELEGATE (sp_capture_reader_read_process);
|
||||
break;
|
||||
|
||||
@ -198,6 +198,17 @@ sp_capture_reader_bswap_map (SpCaptureReader *self,
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
sp_capture_reader_bswap_mark (SpCaptureReader *self,
|
||||
SpCaptureMark *mark)
|
||||
{
|
||||
g_assert (self != NULL);
|
||||
g_assert (mark != NULL);
|
||||
|
||||
if (G_UNLIKELY (self->endian != G_BYTE_ORDER))
|
||||
mark->duration = GUINT64_SWAP_LE_BE (mark->duration);
|
||||
}
|
||||
|
||||
static inline void
|
||||
sp_capture_reader_bswap_jitmap (SpCaptureReader *self,
|
||||
SpCaptureJitmap *jitmap)
|
||||
@ -426,6 +437,47 @@ sp_capture_reader_read_map (SpCaptureReader *self)
|
||||
return map;
|
||||
}
|
||||
|
||||
const SpCaptureMark *
|
||||
sp_capture_reader_read_mark (SpCaptureReader *self)
|
||||
{
|
||||
SpCaptureMark *mark;
|
||||
|
||||
g_assert (self != NULL);
|
||||
g_assert ((self->pos % SP_CAPTURE_ALIGN) == 0);
|
||||
g_assert (self->pos <= self->bufsz);
|
||||
|
||||
if (!sp_capture_reader_ensure_space_for (self, sizeof *mark))
|
||||
return NULL;
|
||||
|
||||
mark = (SpCaptureMark *)(gpointer)&self->buf[self->pos];
|
||||
|
||||
sp_capture_reader_bswap_frame (self, &mark->frame);
|
||||
|
||||
if (mark->frame.type != SP_CAPTURE_FRAME_MARK)
|
||||
return NULL;
|
||||
|
||||
if (mark->frame.len < (sizeof *mark + 1))
|
||||
return NULL;
|
||||
|
||||
if (!sp_capture_reader_ensure_space_for (self, mark->frame.len))
|
||||
return NULL;
|
||||
|
||||
mark = (SpCaptureMark *)(gpointer)&self->buf[self->pos];
|
||||
|
||||
sp_capture_reader_bswap_mark (self, mark);
|
||||
|
||||
self->pos += mark->frame.len;
|
||||
|
||||
if ((self->pos % SP_CAPTURE_ALIGN) != 0)
|
||||
return NULL;
|
||||
|
||||
/* Ensure trailing \0 in name and message */
|
||||
mark->name[sizeof mark->name - 1] = 0;
|
||||
self->buf[self->pos + mark->frame.len - 1] = 0;
|
||||
|
||||
return mark;
|
||||
}
|
||||
|
||||
const SpCaptureProcess *
|
||||
sp_capture_reader_read_process (SpCaptureReader *self)
|
||||
{
|
||||
|
||||
@ -42,6 +42,7 @@ gboolean sp_capture_reader_peek_type (SpCapt
|
||||
gboolean sp_capture_reader_peek_frame (SpCaptureReader *self,
|
||||
SpCaptureFrame *frame);
|
||||
const SpCaptureMap *sp_capture_reader_read_map (SpCaptureReader *self);
|
||||
const SpCaptureMark *sp_capture_reader_read_mark (SpCaptureReader *self);
|
||||
const SpCaptureExit *sp_capture_reader_read_exit (SpCaptureReader *self);
|
||||
const SpCaptureFork *sp_capture_reader_read_fork (SpCaptureReader *self);
|
||||
const SpCaptureTimestamp *sp_capture_reader_read_timestamp (SpCaptureReader *self);
|
||||
|
||||
@ -68,6 +68,7 @@ typedef enum
|
||||
SP_CAPTURE_FRAME_JITMAP = 7,
|
||||
SP_CAPTURE_FRAME_CTRDEF = 8,
|
||||
SP_CAPTURE_FRAME_CTRSET = 9,
|
||||
SP_CAPTURE_FRAME_MARK = 10,
|
||||
} SpCaptureFrameType;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
@ -179,6 +180,14 @@ typedef struct
|
||||
SpCaptureCounterValues values[0];
|
||||
} SpCaptureFrameCounterSet;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SpCaptureFrame frame;
|
||||
gint64 duration;
|
||||
gchar name[32];
|
||||
gchar message[0];
|
||||
} SpCaptureMark;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
G_STATIC_ASSERT (sizeof (SpCaptureFileHeader) == 256);
|
||||
@ -194,6 +203,7 @@ G_STATIC_ASSERT (sizeof (SpCaptureCounter) == 128);
|
||||
G_STATIC_ASSERT (sizeof (SpCaptureCounterValues) == 96);
|
||||
G_STATIC_ASSERT (sizeof (SpCaptureFrameCounterDefine) == 32);
|
||||
G_STATIC_ASSERT (sizeof (SpCaptureFrameCounterSet) == 32);
|
||||
G_STATIC_ASSERT (sizeof (SpCaptureMark) == 64);
|
||||
|
||||
static inline gint
|
||||
sp_capture_address_compare (SpCaptureAddress a,
|
||||
|
||||
@ -536,6 +536,45 @@ sp_capture_writer_add_map (SpCaptureWriter *self,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
sp_capture_writer_add_mark (SpCaptureWriter *self,
|
||||
gint64 time,
|
||||
gint cpu,
|
||||
GPid pid,
|
||||
guint64 duration,
|
||||
const gchar *name,
|
||||
const gchar *message)
|
||||
{
|
||||
SpCaptureMark *ev;
|
||||
gsize message_len;
|
||||
gsize len;
|
||||
|
||||
g_assert (self != NULL);
|
||||
g_assert (name != NULL);
|
||||
|
||||
if (message == NULL)
|
||||
message = "";
|
||||
message_len = strlen (message) + 1;
|
||||
|
||||
len = sizeof *ev + message_len;
|
||||
ev = (SpCaptureMark *)sp_capture_writer_allocate (self, &len);
|
||||
if (!ev)
|
||||
return FALSE;
|
||||
|
||||
sp_capture_writer_frame_init (&ev->frame,
|
||||
len,
|
||||
cpu,
|
||||
pid,
|
||||
time,
|
||||
SP_CAPTURE_FRAME_MARK);
|
||||
|
||||
ev->duration = duration;
|
||||
memcpy (ev->name, name, sizeof ev->name);
|
||||
memcpy (ev->message, message, message_len);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
SpCaptureAddress
|
||||
sp_capture_writer_add_jitmap (SpCaptureWriter *self,
|
||||
const gchar *name)
|
||||
|
||||
@ -55,6 +55,13 @@ gboolean sp_capture_writer_add_map (SpCaptureWriter *
|
||||
guint64 offset,
|
||||
guint64 inode,
|
||||
const gchar *filename);
|
||||
gboolean sp_capture_writer_add_mark (SpCaptureWriter *self,
|
||||
gint64 time,
|
||||
gint cpu,
|
||||
GPid pid,
|
||||
guint64 duration,
|
||||
const gchar *name,
|
||||
const gchar *message);
|
||||
guint64 sp_capture_writer_add_jitmap (SpCaptureWriter *self,
|
||||
const gchar *name);
|
||||
gboolean sp_capture_writer_add_process (SpCaptureWriter *self,
|
||||
|
||||
Reference in New Issue
Block a user