blob: 7e6683817e15b13b87e2f3153c9626beceaacdb7 [file] [log] [blame]
/*
* Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@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; version 2 of the License (not later!)
*
* 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>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#ifndef _TRACE_GRAPH_H
#define _TRACE_GRAPH_H
#include <gtk/gtk.h>
#include "trace-cmd.h"
#include "trace-filter-hash.h"
#include "trace-xml.h"
struct graph_info;
typedef void (graph_select_cb)(struct graph_info *ginfo, guint64 time);
typedef void (graph_filter_cb)(struct graph_info *ginfo,
struct filter_task *task_filter,
struct filter_task *hide_tasks);
/* Used for quereing what plots are defined */
enum graph_plot_type {
PLOT_TYPE_OTHER,
PLOT_TYPE_CPU,
PLOT_TYPE_TASK,
};
enum graph_irq_type {
GRAPH_IRQ_NONE,
GRAPH_HARDIRQ_ENTRY,
GRAPH_HARDIRQ_EXIT,
GRAPH_SOFTIRQ_ENTRY,
GRAPH_SOFTIRQ_EXIT
};
struct graph_plot;
struct plot_info {
gboolean line;
int lcolor;
unsigned long long ltime;
gboolean box;
int bcolor;
unsigned long long bstart;
unsigned long long bend;
gboolean bfill;
gint last_box_x;
gint last_line_x;
};
/*
* match_time:
* Return true if a selected time should expose plot.
* Should only return true if an event has the exact time that
* is passed in.
*
* start:
* Initialize for plotting. This is called with the start time
* to start plotting.
*
* plot_event:
* This is called by the plotter.
* color returns the color that should be printed.
* line returns 1 or 0 if a line should be drawn.
* ltime returns the time that the line should be drawn at
* (ignored if line is 0)
* box returns 1 or 0 if a box should be drawn
* bstart is the time the box starts at
* bend is the time the box ends at
* (bstart and bend are ignored if box is 0)
* bfill whether or not to fill the box (default TRUE)
* time is the time of the current event
*
* end:
* called at the end of the plotting in case the plotter needs to
* release any resourses.
* display_last_event:
* If enough space between the event before and the event after
* a event, the plot may ask to display that event.
* The time will be given to find the event, the time may be before
* the given event.
*
* find_record:
* return a tracecmd record for a given time.
*
* display_info:
* display information about a given time. A resolution is
* passed in to show how much time is in 1 pixel.
*
* destroy:
* destructor routine. Cleans up all resourses that the plot allocated.
*/
struct plot_callbacks {
int (*match_time)(struct graph_info *, struct graph_plot *,
unsigned long long time);
void (*start)(struct graph_info *, struct graph_plot *,
unsigned long long time);
int (*plot_event)(struct graph_info *ginfo,
struct graph_plot *plot,
struct pevent_record *record);
void (*end)(struct graph_info *, struct graph_plot *);
int (*display_last_event)(struct graph_info *ginfo, struct graph_plot *plot,
struct trace_seq *s, unsigned long long time);
struct pevent_record *(*find_record)(struct graph_info *, struct graph_plot *,
unsigned long long time);
int (*display_info)(struct graph_info *, struct graph_plot *,
struct trace_seq *s,
unsigned long long time);
void (*destroy)(struct graph_info *, struct graph_plot *);
};
struct graph_plot {
enum graph_plot_type type;
int pos;
char *label;
const struct plot_callbacks *cb;
void *private;
/* Used for drawing */
struct plot_info info;
gint last_color;
gint p1, p2, p3;
GdkGC *gc;
};
struct graph_callbacks {
graph_select_cb *select;
graph_filter_cb *filter;
};
struct plot_list {
struct plot_list *next;
struct graph_plot *plot;
};
struct plot_hash {
struct plot_hash *next;
struct plot_list *plots;
gint val;
};
#define PLOT_HASH_SIZE 1024
#define TASK_HASH_SIZE 1024
struct task_list;
struct graph_info {
struct tracecmd_input *handle;
struct pevent *pevent;
gint cpus;
gint plots;
struct graph_plot **plot_array; /* all plots */
struct graph_plot *plot_clicked; /* plot that was clicked on */
gint nr_task_hash;
struct plot_hash *task_hash[PLOT_HASH_SIZE];
struct plot_hash *cpu_hash[PLOT_HASH_SIZE];
struct plot_list *all_recs;
struct task_list *tasks[TASK_HASH_SIZE];
GtkWidget *widget; /* Box to hold graph */
GtkWidget *status_hbox; /* hbox holding status info */
GtkWidget *pointer_time; /* time that pointer is at */
GtkWidget *cursor_label; /* label showing cursor time */
GtkWidget *marka_label; /* label showing Marker A time */
GtkWidget *markb_label; /* label showing Marker B time */
GtkWidget *delta_label; /* label showing delta of B - A */
GtkWidget *scrollwin; /* graph scroll window */
GtkWidget *info_scrollwin; /* graph scroll window (for info widget) */
GtkWidget *info; /* info window */
GtkWidget *draw;
GdkPixmap *curr_pixmap; /* pixmap backstore */
GdkPixmap *info_pixmap; /* pixmap backstore */
GtkAdjustment *hadj; /* scrollwindow horizontal adjust */
guint64 start_time; /* True start time of trace */
guint64 end_time; /* True end time of trace */
guint64 view_start_time; /* visible start time */
guint64 view_end_time; /* visible end time */
gint start_x; /* virutal start of visible area */
gboolean no_draw; /* skip drawing the events */
guint64 cursor; /* time of cursor (double clicked) */
gdouble resolution; /* pixels / time */
gint press_x; /* x where button is pressed */
gint last_x; /* last x seen while moving mouse */
gboolean line_active; /* set when button is pressed */
guint64 line_time; /* time line of where line_active is set */
guint64 marka_time; /* time that marker A is at */
guint64 markb_time; /* time that marker B is at */
gboolean show_marka; /* draw marker A line */
gboolean show_markb; /* draw marker B line */
gboolean zoom; /* set when shift button is pressed */
gdouble hadj_value; /* value to set hadj width */
gdouble hadj_page_size; /* visible size to set hadj */
gint draw_width; /* width of pixmap */
gint draw_height; /* height of pixmap */
gint full_width; /* width of full trace in pixels */
/* This includes non visible part of trace */
struct graph_callbacks *callbacks; /* call back hooks for changes to graph */
gboolean filter_enabled;
gboolean filter_available;
gboolean all_events; /* all events enabled */
struct event_filter *event_filter; /* filtered events */
/* cache of event fields */
gint ftrace_sched_switch_id;
gint event_sched_switch_id;
gint event_wakeup_id;
gint event_wakeup_new_id;
gint *hard_irq_entry_ids;
gint *hard_irq_exit_ids;
gint *soft_irq_entry_ids;
gint *soft_irq_exit_ids;
struct format_field *event_prev_state;
struct format_field *event_pid_field;
struct format_field *event_comm_field;
struct format_field *ftrace_pid_field;
struct format_field *ftrace_comm_field;
struct format_field *wakeup_pid_field;
struct format_field *wakeup_success_field;
struct format_field *wakeup_new_pid_field;
struct format_field *wakeup_new_success_field;
gboolean no_irqs;
gboolean read_comms; /* Read all comms on first load */
struct filter_task *task_filter;
gint filter_task_selected;
struct filter_task *hide_tasks;
/* Box info for plot data info window */
gint plot_data_x;
gint plot_data_y;
gint plot_data_w;
gint plot_data_h;
};
struct graph_info *
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_select_by_time(struct graph_info *ginfo, guint64 time);
void trace_graph_event_filter_callback(gboolean accept,
gboolean all_events,
gchar **systems,
gint *events,
gpointer data);
void trace_graph_adv_filter_callback(gboolean accept,
const gchar *text,
gint *event_ids,
gpointer data);
static inline GtkWidget *trace_graph_get_draw(struct graph_info *ginfo)
{
return ginfo->draw;
}
static inline struct graph_callbacks *trace_graph_get_callbacks(struct graph_info *ginfo)
{
return ginfo->callbacks;
}
static inline GtkWidget *trace_graph_get_window(struct graph_info *ginfo)
{
return ginfo->widget;
}
void trace_graph_refresh(struct graph_info *ginfo);
struct filter_task_item *
trace_graph_filter_task_find_pid(struct graph_info *ginfo, gint pid);
struct filter_task_item *
trace_graph_hide_task_find_pid(struct graph_info *ginfo, gint pid);
void trace_graph_filter_toggle(struct graph_info *ginfo);
void trace_graph_filter_add_remove_task(struct graph_info *info,
gint pid);
void trace_graph_filter_hide_show_task(struct graph_info *ginfo,
gint pid);
void trace_graph_clear_tasks(struct graph_info *ginfo);
void trace_graph_free_info(struct graph_info *ginfo);
int trace_graph_load_handle(struct graph_info *ginfo,
struct tracecmd_input *handle);
int trace_graph_check_sched_switch(struct graph_info *ginfo,
struct pevent_record *record,
gint *pid, const char **comm);
int trace_graph_check_sched_wakeup(struct graph_info *ginfo,
struct pevent_record *record,
gint *pid);
enum graph_irq_type trace_graph_check_irq(struct graph_info *ginfo,
struct pevent_record *record);
gboolean trace_graph_filter_on_task(struct graph_info *ginfo, gint pid);
gboolean trace_graph_filter_on_event(struct graph_info *ginfo, struct pevent_record *record);
void trace_graph_copy_filter(struct graph_info *ginfo,
gboolean all_events,
struct event_filter *event_filter);
gint *trace_graph_task_list(struct graph_info *ginfo);
int trace_graph_load_filters(struct graph_info *ginfo,
struct tracecmd_xml_handle *handle);
int trace_graph_save_filters(struct graph_info *ginfo,
struct tracecmd_xml_handle *handle);
void trace_graph_update_filters(struct graph_info *ginfo,
struct filter_task *task_filter,
struct filter_task *hide_tasks);
void trace_graph_refresh_filters(struct graph_info *ginfo);
/* plots */
void trace_graph_plot_free(struct graph_info *ginfo);
void trace_graph_plot_init(struct graph_info *ginfo);
struct graph_plot *trace_graph_plot_append(struct graph_info *ginfo,
const char *label,
enum graph_plot_type type,
const struct plot_callbacks *cb,
void *data);
struct graph_plot *trace_graph_plot_insert(struct graph_info *ginfo,
int pos,
const char *label,
enum graph_plot_type type,
const struct plot_callbacks *cb,
void *data);
void trace_graph_plot_remove(struct graph_info *ginfo, struct graph_plot *plot);
struct plot_hash *trace_graph_plot_find_task(struct graph_info *ginfo, gint task);
void trace_graph_plot_add_task(struct graph_info *ginfo, struct graph_plot *plot,
gint task);
void trace_graph_plot_remove_task(struct graph_info *ginfo,
struct graph_plot *plot,
gint task);
struct plot_hash *trace_graph_plot_find_cpu(struct graph_info *ginfo, gint cpu);
void trace_graph_plot_add_cpu(struct graph_info *ginfo, struct graph_plot *plot,
gint cpu);
void trace_graph_plot_remove_cpu(struct graph_info *ginfo, struct graph_plot *plot,
gint cpu);
void trace_graph_plot_add_all_recs(struct graph_info *ginfo,
struct graph_plot *plot);
void trace_graph_plot_remove_all_recs(struct graph_info *ginfo,
struct graph_plot *plot);
/* plot callbacks */
int trace_graph_plot_match_time(struct graph_info *ginfo,
struct graph_plot *plot,
unsigned long long time);
int trace_graph_plot_display_last_event(struct graph_info *ginfo,
struct graph_plot *plot,
struct trace_seq *s,
unsigned long long time);
void trace_graph_plot_start(struct graph_info *ginfo,
struct graph_plot *plot,
unsigned long long time);
int trace_graph_plot_event(struct graph_info *ginfo,
struct graph_plot *plot,
struct pevent_record *record);
void trace_graph_plot_end(struct graph_info *ginfo,
struct graph_plot *plot);
struct pevent_record *
trace_graph_plot_find_record(struct graph_info *ginfo,
struct graph_plot *plot,
unsigned long long time);
int trace_graph_plot_display_info(struct graph_info *ginfo,
struct graph_plot *plot,
struct trace_seq *s,
unsigned long long time);
/* cpu plot */
void graph_plot_init_cpus(struct graph_info *ginfo, int cpus);
void graph_plot_cpus_plotted(struct graph_info *ginfo,
gboolean *all_cpus, guint64 **cpu_mask);
void graph_plot_cpus_update_callback(gboolean accept,
gboolean all_cpus,
guint64 *selected_cpu_mask,
gpointer data);
/* task plot */
void graph_plot_task(struct graph_info *ginfo, int pid, int pos);
void graph_plot_task_update_callback(gboolean accept,
gint *selected,
gint *non_select,
gpointer data);
void graph_plot_task_plotted(struct graph_info *ginfo,
gint **plotted);
#endif /* _TRACE_GRAPH_H */