mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2025-12-31 20:36:25 +00:00
If we were skipping due to no matching read delegate, then we can just ignore any checks on that frame and move to the next.
209 lines
5.5 KiB
C
209 lines
5.5 KiB
C
/* sp-capture-cursor.c
|
|
*
|
|
* Copyright (C) 2016 Christian Hergert <chergert@redhat.com>
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#define G_LOG_DOMAIN "sp-capture-cursor"
|
|
|
|
#include "sp-capture-condition.h"
|
|
#include "sp-capture-cursor.h"
|
|
#include "sp-capture-reader.h"
|
|
|
|
#define READ_DELEGATE(f) ((ReadDelegate)(f))
|
|
|
|
typedef const SpCaptureFrame *(*ReadDelegate) (SpCaptureReader *);
|
|
|
|
struct _SpCaptureCursor
|
|
{
|
|
GObject parent_instance;
|
|
GPtrArray *conditions;
|
|
SpCaptureReader *reader;
|
|
guint reversed : 1;
|
|
};
|
|
|
|
G_DEFINE_TYPE (SpCaptureCursor, sp_capture_cursor, G_TYPE_OBJECT)
|
|
|
|
static void
|
|
destroy_condition (gpointer data)
|
|
{
|
|
g_boxed_free (SP_TYPE_CAPTURE_CONDITION, data);
|
|
}
|
|
|
|
static void
|
|
sp_capture_cursor_finalize (GObject *object)
|
|
{
|
|
SpCaptureCursor *self = (SpCaptureCursor *)object;
|
|
|
|
g_clear_pointer (&self->conditions, g_ptr_array_unref);
|
|
g_clear_pointer (&self->reader, sp_capture_reader_unref);
|
|
|
|
G_OBJECT_CLASS (sp_capture_cursor_parent_class)->finalize (object);
|
|
}
|
|
|
|
static void
|
|
sp_capture_cursor_class_init (SpCaptureCursorClass *klass)
|
|
{
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
object_class->finalize = sp_capture_cursor_finalize;
|
|
}
|
|
|
|
static void
|
|
sp_capture_cursor_init (SpCaptureCursor *self)
|
|
{
|
|
self->conditions = g_ptr_array_new_with_free_func (destroy_condition);
|
|
}
|
|
|
|
void
|
|
sp_capture_cursor_foreach (SpCaptureCursor *self,
|
|
SpCaptureCursorCallback callback,
|
|
gpointer user_data)
|
|
{
|
|
g_return_if_fail (SP_IS_CAPTURE_CURSOR (self));
|
|
g_return_if_fail (self->reader != NULL);
|
|
g_return_if_fail (callback != NULL);
|
|
|
|
for (;;)
|
|
{
|
|
const SpCaptureFrame *frame;
|
|
SpCaptureFrameType type = 0;
|
|
ReadDelegate delegate = NULL;
|
|
|
|
if (!sp_capture_reader_peek_type (self->reader, &type))
|
|
return;
|
|
|
|
switch (type)
|
|
{
|
|
case SP_CAPTURE_FRAME_TIMESTAMP:
|
|
delegate = READ_DELEGATE (sp_capture_reader_read_timestamp);
|
|
break;
|
|
|
|
case SP_CAPTURE_FRAME_SAMPLE:
|
|
delegate = READ_DELEGATE (sp_capture_reader_read_sample);
|
|
break;
|
|
|
|
case SP_CAPTURE_FRAME_MAP:
|
|
delegate = READ_DELEGATE (sp_capture_reader_read_map);
|
|
break;
|
|
|
|
case SP_CAPTURE_FRAME_PROCESS:
|
|
delegate = READ_DELEGATE (sp_capture_reader_read_process);
|
|
break;
|
|
|
|
case SP_CAPTURE_FRAME_FORK:
|
|
delegate = READ_DELEGATE (sp_capture_reader_read_fork);
|
|
break;
|
|
|
|
case SP_CAPTURE_FRAME_EXIT:
|
|
delegate = READ_DELEGATE (sp_capture_reader_read_exit);
|
|
break;
|
|
|
|
case SP_CAPTURE_FRAME_JITMAP:
|
|
delegate = READ_DELEGATE (sp_capture_reader_read_jitmap);
|
|
break;
|
|
|
|
case SP_CAPTURE_FRAME_CTRDEF:
|
|
delegate = READ_DELEGATE (sp_capture_reader_read_counter_define);
|
|
break;
|
|
|
|
case SP_CAPTURE_FRAME_CTRSET:
|
|
delegate = READ_DELEGATE (sp_capture_reader_read_counter_set);
|
|
break;
|
|
|
|
default:
|
|
if (!sp_capture_reader_skip (self->reader))
|
|
return;
|
|
delegate = NULL;
|
|
break;
|
|
}
|
|
|
|
if (delegate == NULL)
|
|
continue;
|
|
|
|
if (NULL == (frame = delegate (self->reader)))
|
|
return;
|
|
|
|
if (self->conditions->len == 0)
|
|
{
|
|
if (!callback (frame, user_data))
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
for (guint i = 0; i < self->conditions->len; i++)
|
|
{
|
|
SpCaptureCondition *condition = g_ptr_array_index (self->conditions, i);
|
|
|
|
if (sp_capture_condition_match (condition, frame))
|
|
{
|
|
if (!callback (frame, user_data))
|
|
return;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
sp_capture_cursor_reset (SpCaptureCursor *self)
|
|
{
|
|
g_return_if_fail (SP_IS_CAPTURE_CURSOR (self));
|
|
g_return_if_fail (self->reader != NULL);
|
|
|
|
sp_capture_reader_reset (self->reader);
|
|
}
|
|
|
|
void
|
|
sp_capture_cursor_reverse (SpCaptureCursor *self)
|
|
{
|
|
g_return_if_fail (SP_IS_CAPTURE_CURSOR (self));
|
|
|
|
self->reversed = !self->reversed;
|
|
}
|
|
|
|
/**
|
|
* sp_capture_cursor_add_condition:
|
|
* @self: An #SpCaptureCursor
|
|
* @condition: (transfer full): An #SpCaptureCondition
|
|
*
|
|
* Adds the condition to the cursor. This condition must evaluate to
|
|
* true or a given #SpCapureFrame will not be matched.
|
|
*/
|
|
void
|
|
sp_capture_cursor_add_condition (SpCaptureCursor *self,
|
|
SpCaptureCondition *condition)
|
|
{
|
|
g_return_if_fail (SP_IS_CAPTURE_CURSOR (self));
|
|
g_return_if_fail (condition != NULL);
|
|
|
|
g_ptr_array_add (self->conditions, condition);
|
|
}
|
|
|
|
SpCaptureCursor *
|
|
sp_capture_cursor_new (SpCaptureReader *reader)
|
|
{
|
|
SpCaptureCursor *self;
|
|
|
|
g_return_val_if_fail (reader != NULL, NULL);
|
|
|
|
self = g_object_new (SP_TYPE_CAPTURE_CURSOR, NULL);
|
|
self->reader = sp_capture_reader_copy (reader);
|
|
sp_capture_reader_reset (self->reader);
|
|
|
|
return self;
|
|
}
|