libsysprof-analyze: track relative offset for frame

This is handy so that we don't have to keep multiple objects around to
handle this request. Otherwise we'd need to keep references to the
document and that is a bit annoying.

This of course has a limit of about an hour (in tv_nsec), but that is
far longer than we can realistically record anyway.
This commit is contained in:
Christian Hergert
2023-06-12 15:41:29 -07:00
parent 0529cfb2f0
commit 63b42c2319
4 changed files with 34 additions and 7 deletions

View File

@ -34,6 +34,7 @@ struct _SysprofDocumentFrame
guint32 frame_len : 16;
guint32 needs_swap : 1;
guint32 padding : 15;
guint32 time_offset;
};
struct _SysprofDocumentFrameClass
@ -44,7 +45,8 @@ struct _SysprofDocumentFrameClass
SysprofDocumentFrame *_sysprof_document_frame_new (GMappedFile *mapped,
const SysprofCaptureFrame *frame,
guint16 frame_len,
gboolean needs_swap);
gboolean needs_swap,
gint64 clock_at_start);
#define SYSPROF_DOCUMENT_FRAME_ENDPTR(obj) \
(&((const guint8 *)SYSPROF_DOCUMENT_FRAME(obj)->frame)[SYSPROF_DOCUMENT_FRAME(obj)->frame_len])

View File

@ -43,6 +43,7 @@ enum {
PROP_CPU,
PROP_PID,
PROP_TIME,
PROP_TIME_OFFSET,
N_PROPS
};
@ -83,6 +84,10 @@ sysprof_document_frame_get_property (GObject *object,
g_value_set_int64 (value, sysprof_document_frame_get_time (self));
break;
case PROP_TIME_OFFSET:
g_value_set_int64 (value, sysprof_document_frame_get_time_offset (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@ -117,6 +122,13 @@ sysprof_document_frame_class_init (SysprofDocumentFrameClass *klass)
0,
(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
properties[PROP_TIME_OFFSET] =
g_param_spec_int64 ("time-offset", NULL, NULL,
G_MININT64,
G_MAXINT64,
0,
(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_properties (object_class, N_PROPS, properties);
}
@ -129,7 +141,8 @@ SysprofDocumentFrame *
_sysprof_document_frame_new (GMappedFile *mapped_file,
const SysprofCaptureFrame *frame,
guint16 frame_len,
gboolean needs_swap)
gboolean needs_swap,
gint64 begin_time)
{
SysprofDocumentFrame *self;
GType gtype;
@ -198,6 +211,7 @@ _sysprof_document_frame_new (GMappedFile *mapped_file,
self->frame = frame;
self->frame_len = frame_len;
self->needs_swap = !!needs_swap;
self->time_offset = CLAMP (sysprof_document_frame_get_time (self) - begin_time, 0, G_MAXINT64);
return self;
}
@ -225,3 +239,11 @@ sysprof_document_frame_get_time (SysprofDocumentFrame *self)
return SYSPROF_DOCUMENT_FRAME_INT64 (self, self->frame->time);
}
gint64
sysprof_document_frame_get_time_offset (SysprofDocumentFrame *self)
{
g_return_val_if_fail (SYSPROF_IS_DOCUMENT_FRAME (self), 0);
return self->time_offset;
}

View File

@ -35,13 +35,15 @@ typedef struct _SysprofDocumentFrame SysprofDocumentFrame;
typedef struct _SysprofDocumentFrameClass SysprofDocumentFrameClass;
SYSPROF_AVAILABLE_IN_ALL
GType sysprof_document_frame_get_type (void) G_GNUC_CONST;
GType sysprof_document_frame_get_type (void) G_GNUC_CONST;
SYSPROF_AVAILABLE_IN_ALL
int sysprof_document_frame_get_cpu (SysprofDocumentFrame *self);
int sysprof_document_frame_get_cpu (SysprofDocumentFrame *self);
SYSPROF_AVAILABLE_IN_ALL
int sysprof_document_frame_get_pid (SysprofDocumentFrame *self);
int sysprof_document_frame_get_pid (SysprofDocumentFrame *self);
SYSPROF_AVAILABLE_IN_ALL
gint64 sysprof_document_frame_get_time (SysprofDocumentFrame *self);
gint64 sysprof_document_frame_get_time (SysprofDocumentFrame *self);
SYSPROF_AVAILABLE_IN_ALL
gint64 sysprof_document_frame_get_time_offset (SysprofDocumentFrame *self);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (SysprofDocumentFrame, g_object_unref)

View File

@ -118,7 +118,8 @@ sysprof_document_get_item (GListModel *model,
ret = _sysprof_document_frame_new (self->mapped_file,
(gconstpointer)&self->base[ptr->offset],
ptr->length,
self->needs_swap);
self->needs_swap,
self->header.time);
/* Annotate processes with pre-calculated info */
if (SYSPROF_IS_DOCUMENT_PROCESS (ret))