1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399
|
/*
* 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,
};
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;
};
/*
* 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,
struct plot_info *info);
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 */
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 */
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;
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 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);
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,
struct plot_info *info);
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 */
|