Messages in this thread Patch in this message | | | From | "Yordan Karadzhov (VMware)" <> | Subject | [PATCH v2 3/4] kernelshark: Adding gui_event_handlers for View and Graph | Date | Fri, 10 Nov 2017 14:29:14 +0200 |
| |
gui_event_handlers are added to trace_view_store and graph_info. The handlers are used to execute plugin-specific actions during the processing of the trace data.
Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com> --- kshark-plugin.h | 3 +++ trace-graph.c | 41 +++++++++++++++++++++++++++++++++++++++++ trace-graph.h | 7 +++++++ trace-plot-task.c | 17 +++++++++++++---- trace-view-store.c | 16 ++++++++++++++++ trace-view-store.h | 5 +++++ 6 files changed, 85 insertions(+), 4 deletions(-)
diff --git a/kshark-plugin.h b/kshark-plugin.h index d65ee02..42fb40c 100644 --- a/kshark-plugin.h +++ b/kshark-plugin.h @@ -48,6 +48,9 @@ enum gui_plugin_actions { KSHARK_PLUGIN_LOAD, KSHARK_PLUGIN_RELOAD, KSHARK_PLUGIN_UNLOAD, + KSHARK_PLUGIN_GET_PID, + KSHARK_PLUGIN_GET_PREV_STATE, + KSHARK_PLUGIN_GET_COMMAND, }; enum gui_event_types { diff --git a/trace-graph.c b/trace-graph.c index 1db342f..a79aacf 100644 --- a/trace-graph.c +++ b/trace-graph.c @@ -129,6 +129,12 @@ static void free_task_hash(struct graph_info *ginfo) } } +void trace_graph_register_gui_handler(struct graph_info *info, + struct gui_event_handler *handler) { + handler->next = info->event_handlers; + info->event_handlers = handler; +} + /** * trace_graph_task_list - return an allocated list of all found tasks * @ginfo: The graph info structure @@ -1021,6 +1027,7 @@ int trace_graph_check_sched_wakeup(struct graph_info *ginfo, gint *pid) { struct event_format *event; + struct gui_event_handler *handler; unsigned long long val; gboolean found; gint id; @@ -1079,6 +1086,20 @@ int trace_graph_check_sched_wakeup(struct graph_info *ginfo, return 1; } + handler = find_gui_event_handler(ginfo->event_handlers, id); + + if (handler) { + if (handler->type == KSHARK_PLUGIN_WAKEUP_EVENT) { + if (!handler->event_func(record, KSHARK_PLUGIN_GET_PID, &val)) + return 0; + + if (pid) + *pid = val; + + return 1; + } + } + return 0; } @@ -1088,6 +1109,7 @@ int trace_graph_check_sched_switch(struct graph_info *ginfo, { unsigned long long val; struct event_format *event; + struct gui_event_handler *handler; gint this_pid; gint id; int ret = 1; @@ -1118,7 +1140,9 @@ int trace_graph_check_sched_switch(struct graph_info *ginfo, } } + id = pevent_data_type(ginfo->pevent, record); + if (id == ginfo->event_sched_switch_id) { pevent_read_number_field(ginfo->event_pid_field, record->data, &val); if (comm) @@ -1139,6 +1163,20 @@ int trace_graph_check_sched_switch(struct graph_info *ginfo, goto out; } + handler = find_gui_event_handler(ginfo->event_handlers, id); + + if (handler) { + if (handler->type == KSHARK_PLUGIN_SWITCH_EVENT) { + if (handler->event_func(record, KSHARK_PLUGIN_GET_PID, &val)) { + if (pid) + *pid = val; + if(comm) + handler->event_func(record, KSHARK_PLUGIN_GET_COMMAND, &comm); + goto out; + } + } + } + ret = 0; out: if (ret && comm && ginfo->read_comms) { @@ -1285,6 +1323,7 @@ static void draw_info_box(struct graph_info *ginfo, const gchar *buffer, view_start = gtk_adjustment_get_value(ginfo->hadj); view_width = gtk_adjustment_get_page_size(ginfo->hadj); + if (x > view_start + width) x -= width; @@ -2781,6 +2820,8 @@ trace_graph_create_with_callbacks(struct tracecmd_input *handle, ginfo->callbacks = cbs; + ginfo->event_handlers = NULL; + ginfo->task_filter = filter_task_hash_alloc(); ginfo->hide_tasks = filter_task_hash_alloc(); diff --git a/trace-graph.h b/trace-graph.h index 7e66838..21e8feb 100644 --- a/trace-graph.h +++ b/trace-graph.h @@ -24,6 +24,7 @@ #include "trace-cmd.h" #include "trace-filter-hash.h" #include "trace-xml.h" +#include "kshark-plugin.h" struct graph_info; @@ -258,6 +259,8 @@ struct graph_info { gint plot_data_y; gint plot_data_w; gint plot_data_h; + + struct gui_event_handler *event_handlers; }; @@ -266,6 +269,10 @@ trace_graph_create(struct tracecmd_input *handle); struct graph_info * trace_graph_create_with_callbacks(struct tracecmd_input *handle, struct graph_callbacks *cbs); + +void trace_graph_register_gui_handler(struct graph_info *info, + struct gui_event_handler *handler); + void trace_graph_select_by_time(struct graph_info *ginfo, guint64 time); void trace_graph_event_filter_callback(gboolean accept, diff --git a/trace-plot-task.c b/trace-plot-task.c index 3b7e81f..56c3e96 100644 --- a/trace-plot-task.c +++ b/trace-plot-task.c @@ -68,11 +68,20 @@ static gboolean is_running(struct graph_info *ginfo, struct pevent_record *recor int id; id = pevent_data_type(ginfo->pevent, record); - if (id != ginfo->event_sched_switch_id) - return FALSE; - pevent_read_number_field(ginfo->event_prev_state, record->data, &val); - return val & ((1 << 11) - 1)? FALSE : TRUE; + if (id == ginfo->event_sched_switch_id) { + pevent_read_number_field(ginfo->event_prev_state, record->data, &val); + return val & ((1 << 11) - 1)? FALSE : TRUE; + } + + struct gui_event_handler *handler = + find_gui_event_handler(ginfo->event_handlers, id); + if (handler) { + if (handler->type == KSHARK_PLUGIN_SWITCH_EVENT) + return handler->event_func(record, KSHARK_PLUGIN_GET_PREV_STATE, NULL); + } + + return FALSE; } static gboolean record_matches_pid(struct graph_info *ginfo, diff --git a/trace-view-store.c b/trace-view-store.c index f5d0a04..39d0c74 100644 --- a/trace-view-store.c +++ b/trace-view-store.c @@ -70,6 +70,12 @@ static gboolean trace_view_store_iter_parent (GtkTreeModel *tree_model, static GObjectClass *parent_class = NULL; /* GObject stuff - nothing to worry about */ +void trace_view_store_register_gui_handler(TraceViewStore *store, struct gui_event_handler *handler) +{ + handler->next = store->event_handlers; + store->event_handlers = handler; +} + /***************************************************************************** * * trace_view_store_get_type: here we register our new type and its interfaces @@ -866,6 +872,7 @@ trace_view_store_new (struct tracecmd_input *handle) g_assert( newstore != NULL ); + newstore->event_handlers = NULL; newstore->handle = handle; newstore->cpus = tracecmd_cpus(handle); tracecmd_ref(handle); @@ -1194,6 +1201,7 @@ static gboolean show_task(TraceViewStore *store, struct pevent *pevent, struct pevent_record *record, gint pid) { gint event_id; + struct gui_event_handler *ge_handler; if (view_task(store, pid)) return TRUE; @@ -1224,6 +1232,14 @@ static gboolean show_task(TraceViewStore *store, struct pevent *pevent, return TRUE; } + ge_handler = find_gui_event_handler(store->event_handlers, event_id); + + if (ge_handler) { + if (ge_handler->event_func(record, KSHARK_PLUGIN_GET_PID, &pid)) + if (view_task(store, pid)) + return TRUE; + } + return FALSE; } diff --git a/trace-view-store.h b/trace-view-store.h index 03141b1..333116c 100644 --- a/trace-view-store.h +++ b/trace-view-store.h @@ -23,6 +23,7 @@ #include <gtk/gtk.h> #include "trace-cmd.h" #include "trace-filter-hash.h" +#include "kshark-plugin.h" /* Some boilerplate GObject defines. 'klass' is used * instead of 'class', because 'class' is a C++ keyword */ @@ -125,8 +126,12 @@ struct trace_view_store guint64 *cpu_mask; /* cpus that are enabled */ gint stamp; /* Random integer to check whether an iter belongs to our model */ + + struct gui_event_handler *event_handlers; }; +void trace_view_store_register_gui_handler(TraceViewStore *store, struct gui_event_handler *handler); + gboolean trace_view_store_cpu_isset(TraceViewStore *store, gint cpu); void trace_view_store_set_all_cpus(TraceViewStore *store); -- 2.15.0.rc0
| |