start adding IRQ mode for cpu resource
[lttv.git] / ltt / branches / poly / lttv / modules / gui / resourceview / eventhooks.c
CommitLineData
9e01e6d4 1/* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Mathieu Desnoyers
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
16 * MA 02111-1307, USA.
17 */
18
19
20/*****************************************************************************
21 * Hooks to be called by the main window *
22 *****************************************************************************/
23
24
25/* Event hooks are the drawing hooks called during traceset read. They draw the
26 * icons, text, lines and background color corresponding to the events read.
27 *
28 * Two hooks are used for drawing : before_schedchange and after_schedchange hooks. The
29 * before_schedchange is called before the state update that occurs with an event and
30 * the after_schedchange hook is called after this state update.
31 *
32 * The before_schedchange hooks fulfill the task of drawing the visible objects that
33 * corresponds to the data accumulated by the after_schedchange hook.
34 *
35 * The after_schedchange hook accumulates the data that need to be shown on the screen
36 * (items) into a queue. Then, the next before_schedchange hook will draw what that
37 * queue contains. That's the Right Way (TM) of drawing items on the screen,
38 * because we need to draw the background first (and then add icons, text, ...
39 * over it), but we only know the length of a background region once the state
40 * corresponding to it is over, which happens to be at the next before_schedchange
41 * hook.
42 *
43 * We also have a hook called at the end of a chunk to draw the information left
44 * undrawn in each process queue. We use the current time as end of
45 * line/background.
46 */
47
48#ifdef HAVE_CONFIG_H
49#include <config.h>
50#endif
51
52//#define PANGO_ENABLE_BACKEND
53#include <gtk/gtk.h>
54#include <gdk/gdk.h>
55#include <glib.h>
56#include <assert.h>
57#include <string.h>
58#include <stdio.h>
59
60//#include <pango/pango.h>
61
62#include <ltt/event.h>
63#include <ltt/time.h>
64#include <ltt/type.h>
65#include <ltt/trace.h>
66
67#include <lttv/lttv.h>
68#include <lttv/hook.h>
69#include <lttv/state.h>
70#include <lttvwindow/lttvwindow.h>
71#include <lttvwindow/lttvwindowtraces.h>
72#include <lttvwindow/support.h>
73
74
75#include "eventhooks.h"
76#include "cfv.h"
77#include "processlist.h"
78#include "drawing.h"
79
80
81#define MAX_PATH_LEN 256
82#define STATE_LINE_WIDTH 4
83#define COLLISION_POSITION(height) (((height - STATE_LINE_WIDTH)/2) -3)
84
85extern GSList *g_legend_list;
86
87
88/* Action to do when background computation completed.
89 *
90 * Wait for all the awaited computations to be over.
91 */
92
93static gint background_ready(void *hook_data, void *call_data)
94{
95 ControlFlowData *control_flow_data = (ControlFlowData *)hook_data;
96 LttvTrace *trace = (LttvTrace*)call_data;
97
98 control_flow_data->background_info_waiting--;
99
100 if(control_flow_data->background_info_waiting == 0) {
101 g_message("control flow viewer : background computation data ready.");
102
103 drawing_clear(control_flow_data->drawing);
104 processlist_clear(control_flow_data->process_list);
105 gtk_widget_set_size_request(
106 control_flow_data->drawing->drawing_area,
107 -1, processlist_get_height(control_flow_data->process_list));
108 redraw_notify(control_flow_data, NULL);
109 }
110
111 return 0;
112}
113
114
115/* Request background computation. Verify if it is in progress or ready first.
116 * Only for each trace in the tab's traceset.
117 */
118static void request_background_data(ControlFlowData *control_flow_data)
119{
120 LttvTracesetContext * tsc =
121 lttvwindow_get_traceset_context(control_flow_data->tab);
122 gint num_traces = lttv_traceset_number(tsc->ts);
123 gint i;
124 LttvTrace *trace;
125 LttvTraceState *tstate;
126
127 LttvHooks *background_ready_hook =
128 lttv_hooks_new();
129 lttv_hooks_add(background_ready_hook, background_ready, control_flow_data,
130 LTTV_PRIO_DEFAULT);
131 control_flow_data->background_info_waiting = 0;
132
133 for(i=0;i<num_traces;i++) {
134 trace = lttv_traceset_get(tsc->ts, i);
135 tstate = LTTV_TRACE_STATE(tsc->traces[i]);
136
137 if(lttvwindowtraces_get_ready(g_quark_from_string("state"),trace)==FALSE
138 && !tstate->has_precomputed_states) {
139
140 if(lttvwindowtraces_get_in_progress(g_quark_from_string("state"),
141 trace) == FALSE) {
142 /* We first remove requests that could have been done for the same
143 * information. Happens when two viewers ask for it before servicing
144 * starts.
145 */
146 if(!lttvwindowtraces_background_request_find(trace, "state"))
147 lttvwindowtraces_background_request_queue(
148 main_window_get_widget(control_flow_data->tab), trace, "state");
149 lttvwindowtraces_background_notify_queue(control_flow_data,
150 trace,
151 ltt_time_infinite,
152 NULL,
153 background_ready_hook);
154 control_flow_data->background_info_waiting++;
155 } else { /* in progress */
156
157 lttvwindowtraces_background_notify_current(control_flow_data,
158 trace,
159 ltt_time_infinite,
160 NULL,
161 background_ready_hook);
162 control_flow_data->background_info_waiting++;
163 }
164 } else {
165 /* Data ready. By its nature, this viewer doesn't need to have
166 * its data ready hook called there, because a background
167 * request is always linked with a redraw.
168 */
169 }
170
171 }
172
173 lttv_hooks_destroy(background_ready_hook);
174}
175
176
177
178
179/**
180 * Event Viewer's constructor hook
181 *
182 * This constructor is given as a parameter to the menuitem and toolbar button
183 * registration. It creates the list.
184 * @param tab A pointer to the parent tab.
185 * @return The widget created.
186 */
187GtkWidget *
58a9b31b 188h_resourceview(LttvPlugin *plugin)
9e01e6d4 189{
190 LttvPluginTab *ptab = LTTV_PLUGIN_TAB(plugin);
191 Tab *tab = ptab->tab;
192 g_info("h_guicontrolflow, %p", tab);
58a9b31b 193 ControlFlowData *control_flow_data = resourceview(ptab);
9e01e6d4 194
195 control_flow_data->tab = tab;
196
197 // Unreg done in the GuiControlFlow_Destructor
198 lttvwindow_register_traceset_notify(tab,
199 traceset_notify,
200 control_flow_data);
201
202 lttvwindow_register_time_window_notify(tab,
203 update_time_window_hook,
204 control_flow_data);
205 lttvwindow_register_current_time_notify(tab,
206 update_current_time_hook,
207 control_flow_data);
208 lttvwindow_register_redraw_notify(tab,
209 redraw_notify,
210 control_flow_data);
211 lttvwindow_register_continue_notify(tab,
212 continue_notify,
213 control_flow_data);
214 request_background_data(control_flow_data);
215
216
217 return guicontrolflow_get_widget(control_flow_data) ;
218
219}
220
221void legend_destructor(GtkWindow *legend)
222{
223 g_legend_list = g_slist_remove(g_legend_list, legend);
224}
225
226/* Create a popup legend */
227GtkWidget *
228h_legend(LttvPlugin *plugin)
229{
230 LttvPluginTab *ptab = LTTV_PLUGIN_TAB(plugin);
231 Tab *tab = ptab->tab;
232 g_info("h_legend, %p", tab);
233
234 GtkWindow *legend = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
235
236 g_legend_list = g_slist_append(
237 g_legend_list,
238 legend);
239
240 g_object_set_data_full(
241 G_OBJECT(legend),
242 "legend",
243 legend,
244 (GDestroyNotify)legend_destructor);
245
246 gtk_window_set_title(legend, "Control Flow View Legend");
247
248 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(legend), "lttv-color-list.png");
249
250 // GtkImage *image = GTK_IMAGE(gtk_image_new_from_pixmap(
251 // GDK_PIXMAP(pixmap), NULL));
252
253 gtk_container_add(GTK_CONTAINER(legend), GTK_WIDGET(pixmap));
254
255 gtk_widget_show(GTK_WIDGET(pixmap));
256 gtk_widget_show(GTK_WIDGET(legend));
257
258
259 return NULL; /* This is a popup window */
260}
261
262
263int event_selected_hook(void *hook_data, void *call_data)
264{
265 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
266 guint *event_number = (guint*) call_data;
267
268 g_debug("DEBUG : event selected by main window : %u", *event_number);
269
270 return 0;
271}
272
273/* Function that selects the color of status&exemode line */
274static inline PropertiesLine prepare_s_e_line(LttvProcessState *process)
275{
276 PropertiesLine prop_line;
277 prop_line.line_width = STATE_LINE_WIDTH;
278 prop_line.style = GDK_LINE_SOLID;
279 prop_line.y = MIDDLE;
9e01e6d4 280
281 if(process->state->s == LTTV_STATE_RUN) {
282 if(process->state->t == LTTV_STATE_USER_MODE)
283 prop_line.color = drawing_colors[COL_RUN_USER_MODE];
284 else if(process->state->t == LTTV_STATE_SYSCALL)
285 prop_line.color = drawing_colors[COL_RUN_SYSCALL];
286 else if(process->state->t == LTTV_STATE_TRAP)
287 prop_line.color = drawing_colors[COL_RUN_TRAP];
288 else if(process->state->t == LTTV_STATE_IRQ)
289 prop_line.color = drawing_colors[COL_RUN_IRQ];
290 else if(process->state->t == LTTV_STATE_SOFT_IRQ)
291 prop_line.color = drawing_colors[COL_RUN_SOFT_IRQ];
292 else if(process->state->t == LTTV_STATE_MODE_UNKNOWN)
293 prop_line.color = drawing_colors[COL_MODE_UNKNOWN];
294 else
295 g_assert(FALSE); /* RUNNING MODE UNKNOWN */
296 } else if(process->state->s == LTTV_STATE_WAIT) {
297 /* We don't show if we wait while in user mode, trap, irq or syscall */
298 prop_line.color = drawing_colors[COL_WAIT];
299 } else if(process->state->s == LTTV_STATE_WAIT_CPU) {
300 /* We don't show if we wait for CPU while in user mode, trap, irq
301 * or syscall */
302 prop_line.color = drawing_colors[COL_WAIT_CPU];
303 } else if(process->state->s == LTTV_STATE_ZOMBIE) {
304 prop_line.color = drawing_colors[COL_ZOMBIE];
305 } else if(process->state->s == LTTV_STATE_WAIT_FORK) {
306 prop_line.color = drawing_colors[COL_WAIT_FORK];
307 } else if(process->state->s == LTTV_STATE_EXIT) {
308 prop_line.color = drawing_colors[COL_EXIT];
309 } else if(process->state->s == LTTV_STATE_UNNAMED) {
310 prop_line.color = drawing_colors[COL_UNNAMED];
311 } else {
312 g_critical("unknown state : %s", g_quark_to_string(process->state->s));
313 g_assert(FALSE); /* UNKNOWN STATE */
314 }
315
316 return prop_line;
317
318}
319
598026ba 320static void set_line_color_cpu(PropertiesLine *prop_line, GQuark present_state)
321{
322 if(present_state == LTTV_CPU_IDLE) {
323 prop_line->color = drawing_colors_cpu[COL_CPU_IDLE];
324 }
325 else if(present_state == LTTV_CPU_BUSY) {
326 prop_line->color = drawing_colors_cpu[COL_CPU_BUSY];
327 }
328 else if(present_state == LTTV_CPU_IRQ) {
329 prop_line->color = drawing_colors_cpu[COL_CPU_IRQ];
330 }
331}
9e01e6d4 332
333/* before_schedchange_hook
334 *
335 * This function basically draw lines and icons. Two types of lines are drawn :
336 * one small (3 pixels?) representing the state of the process and the second
337 * type is thicker (10 pixels?) representing on which CPU a process is running
338 * (and this only in running state).
339 *
340 * Extremums of the lines :
341 * x_min : time of the last event context for this process kept in memory.
342 * x_max : time of the current event.
343 * y : middle of the process in the process list. The process is found in the
344 * list, therefore is it's position in pixels.
345 *
346 * The choice of lines'color is defined by the context of the last event for this
347 * process.
348 */
349
350
351int before_schedchange_hook(void *hook_data, void *call_data)
352{
353 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
354 EventsRequest *events_request = (EventsRequest*)thf->hook_data;
355 ControlFlowData *control_flow_data = events_request->viewer_data;
356
357 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
358
359 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
360 LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
361
362 LttEvent *e;
363 e = ltt_tracefile_get_event(tfc->tf);
364 gint target_pid_saved = tfc->target_pid;
365
366 LttTime evtime = ltt_event_time(e);
367 LttvFilter *filter = control_flow_data->filter;
368
58a9b31b 369 GQuark cpuq;
370
9e01e6d4 371 /* we are in a schedchange, before the state update. We must draw the
372 * items corresponding to the state before it changes : now is the right
373 * time to do it.
374 */
375
376 guint pid_out;
377 guint pid_in;
58a9b31b 378 pid_out = ltt_event_get_long_unsigned(e, thf->f1);
379 pid_in = ltt_event_get_long_unsigned(e, thf->f2);
44ffb95f 380// if(pid_in != 0 && pid_out != 0) {
381// /* not a transition to/from idle */
382// return 0;
383// }
c4e6f4dc 384
598026ba 385 exit(0);
386
9e01e6d4 387 tfc->target_pid = pid_out;
58a9b31b 388// if(!filter || !filter->head ||
389// lttv_filter_tree_parse(filter->head,e,tfc->tf,
390// tfc->t_context->t,tfc,NULL,NULL)) {
9e01e6d4 391 /* For the pid_out */
392 /* First, check if the current process is in the state computation
393 * process list. If it is there, that means we must add it right now and
394 * draw items from the beginning of the read for it. If it is not
395 * present, it's a new process and it was not present : it will
396 * be added after the state update. */
397 guint cpu = tfs->cpu;
44ffb95f 398 {
399 gchar *cpustr;
400 cpustr = g_strdup_printf("CPU%u", cpu);
401 cpuq = g_quark_from_string(cpustr);
402 g_free(cpustr);
403 }
58a9b31b 404
9e01e6d4 405 guint trace_num = ts->parent.index;
58a9b31b 406// LttvProcessState *process = ts->running_process[cpu];
9e01e6d4 407 /* unknown state, bad current pid */
58a9b31b 408// if(process->pid != pid_out)
409// process = lttv_state_find_process(ts,
410// tfs->cpu, pid_out);
9e01e6d4 411
58a9b31b 412// if(process != NULL) {
9e01e6d4 413 /* Well, the process_out existed : we must get it in the process hash
414 * or add it, and draw its items.
415 */
416 /* Add process to process list (if not present) */
417 guint pl_height = 0;
58a9b31b 418 HashedResourceData *hashed_process_data = NULL;
9e01e6d4 419 ProcessList *process_list = control_flow_data->process_list;
58a9b31b 420// LttTime birth = process->creation_time;
9e01e6d4 421
58a9b31b 422 hashed_process_data = processlist_get_process_data(process_list, cpuq, trace_num);
423// hashed_process_data = processlist_get_process_data(process_list,
424// pid_out,
425// process->cpu,
426// &birth,
427// trace_num);
9e01e6d4 428 if(hashed_process_data == NULL)
429 {
58a9b31b 430// g_assert(pid_out == 0 || pid_out != process->ppid);
9e01e6d4 431 /* Process not present */
58a9b31b 432 ResourceInfo *process_info;
9e01e6d4 433 Drawing_t *drawing = control_flow_data->drawing;
c4e6f4dc 434 resourcelist_add(process_list,
9e01e6d4 435 drawing,
58a9b31b 436 trace_num,
437 cpuq, //process->name,
44ffb95f 438 0, //cpu
439 cpu,
9e01e6d4 440 &pl_height,
441 &process_info,
442 &hashed_process_data);
443 gtk_widget_set_size_request(drawing->drawing_area,
444 -1,
445 pl_height);
446 gtk_widget_queue_draw(drawing->drawing_area);
447
448 }
449
450 /* Now, the process is in the state hash and our own process hash.
451 * We definitely can draw the items related to the ending state.
452 */
453
454 if(ltt_time_compare(hashed_process_data->next_good_time,
455 evtime) > 0)
456 {
457 if(hashed_process_data->x.middle_marked == FALSE) {
458
459 TimeWindow time_window =
460 lttvwindow_get_time_window(control_flow_data->tab);
461#ifdef EXTRA_CHECK
462 if(ltt_time_compare(evtime, time_window.start_time) == -1
463 || ltt_time_compare(evtime, time_window.end_time) == 1)
464 return;
465#endif //EXTRA_CHECK
466 Drawing_t *drawing = control_flow_data->drawing;
467 guint width = drawing->width;
468 guint x;
469 convert_time_to_pixels(
470 time_window,
471 evtime,
472 width,
473 &x);
474
475 /* Draw collision indicator */
476 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
477 gdk_draw_point(hashed_process_data->pixmap,
478 drawing->gc,
479 x,
480 COLLISION_POSITION(hashed_process_data->height));
481 hashed_process_data->x.middle_marked = TRUE;
482 }
483 } else {
484 TimeWindow time_window =
485 lttvwindow_get_time_window(control_flow_data->tab);
486#ifdef EXTRA_CHECK
487 if(ltt_time_compare(evtime, time_window.start_time) == -1
488 || ltt_time_compare(evtime, time_window.end_time) == 1)
489 return;
490#endif //EXTRA_CHECK
491 Drawing_t *drawing = control_flow_data->drawing;
492 guint width = drawing->width;
493 guint x;
494 convert_time_to_pixels(
495 time_window,
496 evtime,
497 width,
498 &x);
499
500
501 /* Jump over draw if we are at the same x position */
502 if(x == hashed_process_data->x.middle &&
503 hashed_process_data->x.middle_used)
504 {
505 if(hashed_process_data->x.middle_marked == FALSE) {
506 /* Draw collision indicator */
507 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
508 gdk_draw_point(hashed_process_data->pixmap,
509 drawing->gc,
510 x,
511 COLLISION_POSITION(hashed_process_data->height));
512 hashed_process_data->x.middle_marked = TRUE;
513 }
514 /* jump */
515 } else {
516 DrawContext draw_context;
517
518 /* Now create the drawing context that will be used to draw
519 * items related to the last state. */
520 draw_context.drawable = hashed_process_data->pixmap;
521 draw_context.gc = drawing->gc;
522 draw_context.pango_layout = drawing->pango_layout;
523 draw_context.drawinfo.start.x = hashed_process_data->x.middle;
524 draw_context.drawinfo.end.x = x;
525
526 draw_context.drawinfo.y.over = 1;
527 draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
528 draw_context.drawinfo.y.under = hashed_process_data->height;
529
530 draw_context.drawinfo.start.offset.over = 0;
531 draw_context.drawinfo.start.offset.middle = 0;
532 draw_context.drawinfo.start.offset.under = 0;
533 draw_context.drawinfo.end.offset.over = 0;
534 draw_context.drawinfo.end.offset.middle = 0;
535 draw_context.drawinfo.end.offset.under = 0;
536
537 {
538 /* Draw the line */
58a9b31b 539 //PropertiesLine prop_line = prepare_s_e_line(process);
540 PropertiesLine prop_line;
541 prop_line.line_width = STATE_LINE_WIDTH;
542 prop_line.style = GDK_LINE_SOLID;
543 prop_line.y = MIDDLE;
598026ba 544 cpu_set_line_color(&prop_line, tfs->cpu_state->present_state);
9e01e6d4 545 draw_line((void*)&prop_line, (void*)&draw_context);
9e01e6d4 546
58a9b31b 547 }
548 /* become the last x position */
549 hashed_process_data->x.middle = x;
550 hashed_process_data->x.middle_used = TRUE;
551 hashed_process_data->x.middle_marked = FALSE;
9e01e6d4 552
58a9b31b 553 /* Calculate the next good time */
554 convert_pixels_to_time(width, x+1, time_window,
555 &hashed_process_data->next_good_time);
556 }
557 }
558// }
559// }
560
561// tfc->target_pid = pid_in;
562// if(!filter || !filter->head ||
563// lttv_filter_tree_parse(filter->head,e,tfc->tf,
564// tfc->t_context->t,tfc,NULL,NULL)) {
565// /* For the pid_in */
566// /* First, check if the current process is in the state computation
567// * process list. If it is there, that means we must add it right now and
568// * draw items from the beginning of the read for it. If it is not
569// * present, it's a new process and it was not present : it will
570// * be added after the state update. */
571// LttvProcessState *process;
572// process = lttv_state_find_process(ts,
573// tfs->cpu, pid_in);
574// guint trace_num = ts->parent.index;
575//
576// if(process != NULL) {
577// /* Well, the process existed : we must get it in the process hash
578// * or add it, and draw its items.
579// */
580// /* Add process to process list (if not present) */
581// guint pl_height = 0;
582// HashedResourceData *hashed_process_data = NULL;
583// ProcessList *process_list = control_flow_data->process_list;
584// LttTime birth = process->creation_time;
585//
586// hashed_process_data = processlist_get_process_data(process_list, cpuq);
587//// hashed_process_data = processlist_get_process_data(process_list,
588//// pid_in,
589//// tfs->cpu,
590//// &birth,
591//// trace_num);
592// if(hashed_process_data == NULL)
593// {
594// g_assert(pid_in == 0 || pid_in != process->ppid);
595// /* Process not present */
596// ResourceInfo *process_info;
597// Drawing_t *drawing = control_flow_data->drawing;
598// resourcelist_add(process_list,
599// drawing,
600//// pid_in,
601//// process->tgid,
602//// tfs->cpu,
603//// process->ppid,
604//// &birth,
605//// trace_num,
606// process->name,
607//// process->brand,
608// &pl_height,
609// &process_info,
610// &hashed_process_data);
611// gtk_widget_set_size_request(drawing->drawing_area,
612// -1,
613// pl_height);
614// gtk_widget_queue_draw(drawing->drawing_area);
615//
616// }
617// //We could set the current process and hash here, but will be done
618// //by after schedchange hook
619//
620// /* Now, the process is in the state hash and our own process hash.
621// * We definitely can draw the items related to the ending state.
622// */
623//
624// if(ltt_time_compare(hashed_process_data->next_good_time,
625// evtime) > 0)
626// {
627// if(hashed_process_data->x.middle_marked == FALSE) {
628//
629// TimeWindow time_window =
630// lttvwindow_get_time_window(control_flow_data->tab);
631//#ifdef EXTRA_CHECK
632// if(ltt_time_compare(evtime, time_window.start_time) == -1
633// || ltt_time_compare(evtime, time_window.end_time) == 1)
634// return;
635//#endif //EXTRA_CHECK
636// Drawing_t *drawing = control_flow_data->drawing;
637// guint width = drawing->width;
638// guint x;
639// convert_time_to_pixels(
640// time_window,
641// evtime,
642// width,
643// &x);
644//
645// /* Draw collision indicator */
646// gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
647// gdk_draw_point(hashed_process_data->pixmap,
648// drawing->gc,
649// x,
650// COLLISION_POSITION(hashed_process_data->height));
651// hashed_process_data->x.middle_marked = TRUE;
652// }
653// } else {
654// TimeWindow time_window =
655// lttvwindow_get_time_window(control_flow_data->tab);
656//#ifdef EXTRA_CHECK
657// if(ltt_time_compare(evtime, time_window.start_time) == -1
658// || ltt_time_compare(evtime, time_window.end_time) == 1)
659// return;
660//#endif //EXTRA_CHECK
661// Drawing_t *drawing = control_flow_data->drawing;
662// guint width = drawing->width;
663// guint x;
664//
665// convert_time_to_pixels(
666// time_window,
667// evtime,
668// width,
669// &x);
670//
671//
672// /* Jump over draw if we are at the same x position */
673// if(x == hashed_process_data->x.middle &&
674// hashed_process_data->x.middle_used)
675// {
676// if(hashed_process_data->x.middle_marked == FALSE) {
677// /* Draw collision indicator */
678// gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
679// gdk_draw_point(hashed_process_data->pixmap,
680// drawing->gc,
681// x,
682// COLLISION_POSITION(hashed_process_data->height));
683// hashed_process_data->x.middle_marked = TRUE;
684// }
685// /* jump */
686// } else {
687// DrawContext draw_context;
688//
689// /* Now create the drawing context that will be used to draw
690// * items related to the last state. */
691// draw_context.drawable = hashed_process_data->pixmap;
692// draw_context.gc = drawing->gc;
693// draw_context.pango_layout = drawing->pango_layout;
694// draw_context.drawinfo.start.x = hashed_process_data->x.middle;
695// draw_context.drawinfo.end.x = x;
696//
697// draw_context.drawinfo.y.over = 1;
698// draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
699// draw_context.drawinfo.y.under = hashed_process_data->height;
700//
701// draw_context.drawinfo.start.offset.over = 0;
702// draw_context.drawinfo.start.offset.middle = 0;
703// draw_context.drawinfo.start.offset.under = 0;
704// draw_context.drawinfo.end.offset.over = 0;
705// draw_context.drawinfo.end.offset.middle = 0;
706// draw_context.drawinfo.end.offset.under = 0;
707//
708// {
709// /* Draw the line */
710// PropertiesLine prop_line = prepare_s_e_line(process);
711// draw_line((void*)&prop_line, (void*)&draw_context);
712// }
713//
714//
715// /* become the last x position */
716// hashed_process_data->x.middle = x;
717// hashed_process_data->x.middle_used = TRUE;
718// hashed_process_data->x.middle_marked = FALSE;
719//
720// /* Calculate the next good time */
721// convert_pixels_to_time(width, x+1, time_window,
722// &hashed_process_data->next_good_time);
723// }
724// }
725// } else
726// g_warning("Cannot find pin_in in schedchange %u", pid_in);
727// }
728// tfc->target_pid = target_pid_saved;
729 return 0;
9e01e6d4 730
9e01e6d4 731
9e01e6d4 732
9e01e6d4 733
58a9b31b 734 /* Text dump */
735#ifdef DONTSHOW
736 GString *string = g_string_new("");;
737 gboolean field_names = TRUE, state = TRUE;
9e01e6d4 738
58a9b31b 739 lttv_event_to_string(e, tfc->tf, string, TRUE, field_names, tfs);
740 g_string_append_printf(string,"\n");
9e01e6d4 741
58a9b31b 742 if(state) {
743 g_string_append_printf(string, " %s",
744 g_quark_to_string(tfs->process->state->s));
9e01e6d4 745 }
746
58a9b31b 747 g_info("%s",string->str);
9e01e6d4 748
58a9b31b 749 g_string_free(string, TRUE);
750
751 /* End of text dump */
752#endif //DONTSHOW
9e01e6d4 753
754}
755
58a9b31b 756/* after_schedchange_hook
757 *
758 * The draw after hook is called by the reading API to have a
759 * particular event drawn on the screen.
760 * @param hook_data ControlFlowData structure of the viewer.
761 * @param call_data Event context.
762 *
763 * This function adds items to be drawn in a queue for each process.
764 *
765 */
766int after_schedchange_hook(void *hook_data, void *call_data)
9e01e6d4 767{
44ffb95f 768 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
769 EventsRequest *events_request = (EventsRequest*)thf->hook_data;
770 ControlFlowData *control_flow_data = events_request->viewer_data;
771
772 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
773
774 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
775
776 LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
777
778 LttEvent *e;
779 e = ltt_tracefile_get_event(tfc->tf);
780
781 LttvFilter *filter = control_flow_data->filter;
782 if(filter != NULL && filter->head != NULL)
783 if(!lttv_filter_tree_parse(filter->head,e,tfc->tf,
784 tfc->t_context->t,tfc,NULL,NULL))
785 return FALSE;
786
787 LttTime evtime = ltt_event_time(e);
788
789 GQuark cpuq;
790
791 /* Add process to process list (if not present) */
792 LttvProcessState *process_in;
793 LttTime birth;
794 guint pl_height = 0;
795 HashedResourceData *hashed_process_data_in = NULL;
796
797 ProcessList *process_list = control_flow_data->process_list;
798
799 guint pid_in;
800 {
801 guint pid_out;
802 pid_out = ltt_event_get_long_unsigned(e, thf->f1);
803 pid_in = ltt_event_get_long_unsigned(e, thf->f2);
804 }
805
806
807 /* Find process pid_in in the list... */
808 //process_in = lttv_state_find_process(ts, ANY_CPU, pid_in);
809 //process_in = tfs->process;
810 guint cpu = tfs->cpu;
811 {
812 gchar *cpustr;
813 cpustr = g_strdup_printf("CPU%u", cpu);
814 cpuq = g_quark_from_string(cpustr);
815 g_free(cpustr);
816 }
817 guint trace_num = ts->parent.index;
818 process_in = ts->running_process[cpu];
819 /* It should exist, because we are after the state update. */
820#ifdef EXTRA_CHECK
821 g_assert(process_in != NULL);
822#endif //EXTRA_CHECK
823 birth = process_in->creation_time;
824
825 hashed_process_data_in = processlist_get_process_data(process_list, cpuq, trace_num);
826// hashed_process_data_in = processlist_get_process_data(process_list,
827// pid_in,
828// process_in->cpu,
829// &birth,
830// trace_num);
831 if(hashed_process_data_in == NULL)
832 {
833 g_assert(pid_in == 0 || pid_in != process_in->ppid);
834 ResourceInfo *process_info;
835 Drawing_t *drawing = control_flow_data->drawing;
836 /* Process not present */
837 resourcelist_add(process_list,
838 drawing,
839 trace_num,
840 cpuq,
841 0,
842 cpu,
843 &pl_height,
844 &process_info,
845 &hashed_process_data_in);
846 gtk_widget_set_size_request(drawing->drawing_area,
847 -1,
848 pl_height);
849 gtk_widget_queue_draw(drawing->drawing_area);
850 }
851 /* Set the current process */
852 process_list->current_hash_data[trace_num][process_in->cpu] =
853 hashed_process_data_in;
854
855 if(ltt_time_compare(hashed_process_data_in->next_good_time,
856 evtime) <= 0)
857 {
858 TimeWindow time_window =
859 lttvwindow_get_time_window(control_flow_data->tab);
860
861#ifdef EXTRA_CHECK
862 if(ltt_time_compare(evtime, time_window.start_time) == -1
863 || ltt_time_compare(evtime, time_window.end_time) == 1)
864 return;
865#endif //EXTRA_CHECK
866 Drawing_t *drawing = control_flow_data->drawing;
867 guint width = drawing->width;
868 guint new_x;
869
870 convert_time_to_pixels(
871 time_window,
872 evtime,
873 width,
874 &new_x);
875
876 if(hashed_process_data_in->x.middle != new_x) {
877 hashed_process_data_in->x.middle = new_x;
878 hashed_process_data_in->x.middle_used = FALSE;
879 hashed_process_data_in->x.middle_marked = FALSE;
880 }
881 }
58a9b31b 882 return 0;
883}
9e01e6d4 884
58a9b31b 885/* before_execmode_hook
886 *
887 * This function basically draw lines and icons. Two types of lines are drawn :
888 * one small (3 pixels?) representing the state of the process and the second
889 * type is thicker (10 pixels?) representing on which CPU a process is running
890 * (and this only in running state).
891 *
892 * Extremums of the lines :
893 * x_min : time of the last event context for this process kept in memory.
894 * x_max : time of the current event.
895 * y : middle of the process in the process list. The process is found in the
896 * list, therefore is it's position in pixels.
897 *
898 * The choice of lines'color is defined by the context of the last event for this
899 * process.
900 */
9e01e6d4 901
598026ba 902int before_execmode_hook(void *hook_data, void *call_data)
903{
904 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
905 EventsRequest *events_request = (EventsRequest*)thf->hook_data;
906 ControlFlowData *control_flow_data = events_request->viewer_data;
907
908 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
909
910 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
911 LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
912
913 LttEvent *e;
914 e = ltt_tracefile_get_event(tfc->tf);
915
916 LttTime evtime = ltt_event_time(e);
917
918 GQuark cpuq;
919
920 /* we are in a execmode, before the state update. We must draw the
921 * items corresponding to the state before it changes : now is the right
922 * time to do it.
923 */
924 /* For the pid */
925 //LttvProcessState *process = tfs->process;
926 guint cpu = tfs->cpu;
927 {
928 gchar *cpustr;
929 cpustr = g_strdup_printf("CPU%u", cpu);
930 cpuq = g_quark_from_string(cpustr);
931 g_free(cpustr);
932 }
933 guint trace_num = ts->parent.index;
934 LttvProcessState *process = ts->running_process[cpu];
935 g_assert(process != NULL);
936
58a9b31b 937// guint pid = process->pid;
598026ba 938
939 /* Well, the process_out existed : we must get it in the process hash
940 * or add it, and draw its items.
941 */
942 /* Add process to process list (if not present) */
943 guint pl_height = 0;
944 HashedResourceData *hashed_process_data = NULL;
945 ProcessList *process_list = control_flow_data->process_list;
946 LttTime birth = process->creation_time;
947
948 if(likely(process_list->current_hash_data[trace_num][cpu] != NULL)) {
949 hashed_process_data = process_list->current_hash_data[trace_num][cpu];
950 } else {
951 hashed_process_data = processlist_get_process_data(process_list, cpuq, trace_num);
952// hashed_process_data = processlist_get_process_data(process_list,
953// pid,
954// process->cpu,
955// &birth,
956// trace_num);
957 if(unlikely(hashed_process_data == NULL))
958 {
959 //g_assert(pid == 0 || pid != process->ppid);
960 ResourceInfo *process_info;
961 /* Process not present */
962 Drawing_t *drawing = control_flow_data->drawing;
963 ressourcelist_add(process_list,
964 drawing,
965 trace_num,
966 cpuq, //process->name,
967 0, //cpu
968 cpu,
969 &pl_height,
970 &process_info,
971 &hashed_process_data);
972 gtk_widget_set_size_request(drawing->drawing_area,
973 -1,
974 pl_height);
975 gtk_widget_queue_draw(drawing->drawing_area);
976 }
977 /* Set the current process */
978 process_list->current_hash_data[trace_num][process->cpu] =
979 hashed_process_data;
980 }
981
982 /* Now, the process is in the state hash and our own process hash.
983 * We definitely can draw the items related to the ending state.
984 */
985
986 if(likely(ltt_time_compare(hashed_process_data->next_good_time,
987 evtime) > 0))
988 {
989 if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
990 TimeWindow time_window =
991 lttvwindow_get_time_window(control_flow_data->tab);
992
993#ifdef EXTRA_CHECK
994 if(ltt_time_compare(evtime, time_window.start_time) == -1
995 || ltt_time_compare(evtime, time_window.end_time) == 1)
996 return;
997#endif //EXTRA_CHECK
998 Drawing_t *drawing = control_flow_data->drawing;
999 guint width = drawing->width;
1000 guint x;
1001 convert_time_to_pixels(
1002 time_window,
1003 evtime,
1004 width,
1005 &x);
1006
1007 /* Draw collision indicator */
1008 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
1009 gdk_draw_point(hashed_process_data->pixmap,
1010 drawing->gc,
1011 x,
1012 COLLISION_POSITION(hashed_process_data->height));
1013 hashed_process_data->x.middle_marked = TRUE;
1014 }
1015 } else {
1016 TimeWindow time_window =
1017 lttvwindow_get_time_window(control_flow_data->tab);
1018
1019#ifdef EXTRA_CHECK
1020 if(ltt_time_compare(evtime, time_window.start_time) == -1
1021 || ltt_time_compare(evtime, time_window.end_time) == 1)
1022 return;
1023#endif //EXTRA_CHECK
1024 Drawing_t *drawing = control_flow_data->drawing;
1025 guint width = drawing->width;
1026 guint x;
1027
1028 convert_time_to_pixels(
1029 time_window,
1030 evtime,
1031 width,
1032 &x);
1033
1034
1035 /* Jump over draw if we are at the same x position */
1036 if(unlikely(x == hashed_process_data->x.middle &&
1037 hashed_process_data->x.middle_used))
1038 {
1039 if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
1040 /* Draw collision indicator */
1041 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
1042 gdk_draw_point(hashed_process_data->pixmap,
1043 drawing->gc,
1044 x,
1045 COLLISION_POSITION(hashed_process_data->height));
1046 hashed_process_data->x.middle_marked = TRUE;
1047 }
1048 /* jump */
1049 } else {
1050
1051 DrawContext draw_context;
1052 /* Now create the drawing context that will be used to draw
1053 * items related to the last state. */
1054 draw_context.drawable = hashed_process_data->pixmap;
1055 draw_context.gc = drawing->gc;
1056 draw_context.pango_layout = drawing->pango_layout;
1057 draw_context.drawinfo.start.x = hashed_process_data->x.middle;
1058 draw_context.drawinfo.end.x = x;
1059
1060 draw_context.drawinfo.y.over = 1;
1061 draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
1062 draw_context.drawinfo.y.under = hashed_process_data->height;
1063
1064 draw_context.drawinfo.start.offset.over = 0;
1065 draw_context.drawinfo.start.offset.middle = 0;
1066 draw_context.drawinfo.start.offset.under = 0;
1067 draw_context.drawinfo.end.offset.over = 0;
1068 draw_context.drawinfo.end.offset.middle = 0;
1069 draw_context.drawinfo.end.offset.under = 0;
1070
1071 {
1072 /* Draw the line */
1073 PropertiesLine prop_line;
1074 cpu_set_line_color(&prop_line, tfs->cpu_state->present_state);
1075 printf("current state: %s\n", g_quark_to_string(tfs->cpu_state->present_state));
1076 draw_line((void*)&prop_line, (void*)&draw_context);
1077 }
1078 /* become the last x position */
1079 hashed_process_data->x.middle = x;
1080 hashed_process_data->x.middle_used = TRUE;
1081 hashed_process_data->x.middle_marked = FALSE;
1082
1083 /* Calculate the next good time */
1084 convert_pixels_to_time(width, x+1, time_window,
1085 &hashed_process_data->next_good_time);
1086 }
1087 }
1088
1089 return 0;
1090}
9e01e6d4 1091
58a9b31b 1092/* before_process_exit_hook
1093 *
1094 * Draw lines for process event.
1095 *
1096 * @param hook_data ControlFlowData structure of the viewer.
1097 * @param call_data Event context.
1098 *
1099 * This function adds items to be drawn in a queue for each process.
1100 *
1101 */
9e01e6d4 1102
58a9b31b 1103//int before_process_exit_hook(void *hook_data, void *call_data)
1104//{
1105// LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
1106// EventsRequest *events_request = (EventsRequest*)thf->hook_data;
1107//
1108// ControlFlowData *control_flow_data = events_request->viewer_data;
1109//
1110// LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
1111//
1112// LttvTracefileState *tfs = (LttvTracefileState *)call_data;
1113//
1114// LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
1115//
1116// LttEvent *e;
1117// e = ltt_tracefile_get_event(tfc->tf);
1118//
1119// LttvFilter *filter = control_flow_data->filter;
1120// if(filter != NULL && filter->head != NULL)
1121// if(!lttv_filter_tree_parse(filter->head,e,tfc->tf,
1122// tfc->t_context->t,tfc,NULL,NULL))
1123// return FALSE;
1124//
1125// LttTime evtime = ltt_event_time(e);
1126//
1127// /* Add process to process list (if not present) */
1128// //LttvProcessState *process = tfs->process;
1129// guint cpu = tfs->cpu;
1130// guint trace_num = ts->parent.index;
1131// LttvProcessState *process = ts->running_process[cpu];
1132// guint pid = process->pid;
1133// LttTime birth;
1134// guint pl_height = 0;
1135// HashedResourceData *hashed_process_data = NULL;
1136//
1137// ProcessList *process_list = control_flow_data->process_list;
1138//
1139// g_assert(process != NULL);
1140//
1141// birth = process->creation_time;
1142//
1143// if(likely(process_list->current_hash_data[trace_num][cpu] != NULL)) {
1144// hashed_process_data = process_list->current_hash_data[trace_num][cpu];
1145// } else {
1146// hashed_process_data = processlist_get_process_data(process_list, "CPU0");
1147//// hashed_process_data = processlist_get_process_data(process_list,
1148//// pid,
1149//// process->cpu,
1150//// &birth,
1151//// trace_num);
1152// if(unlikely(hashed_process_data == NULL))
1153// {
1154// g_assert(pid == 0 || pid != process->ppid);
1155// /* Process not present */
1156// Drawing_t *drawing = control_flow_data->drawing;
1157// ResourceInfo *process_info;
1158// processlist_add(process_list,
1159// drawing,
1160// pid,
1161// process->tgid,
1162// process->cpu,
1163// process->ppid,
1164// &birth,
1165// trace_num,
1166// process->name,
1167// process->brand,
1168// &pl_height,
1169// &process_info,
1170// &hashed_process_data);
1171// gtk_widget_set_size_request(drawing->drawing_area,
1172// -1,
1173// pl_height);
1174// gtk_widget_queue_draw(drawing->drawing_area);
1175// }
1176// }
1177//
1178// /* Now, the process is in the state hash and our own process hash.
1179// * We definitely can draw the items related to the ending state.
1180// */
1181//
1182// if(likely(ltt_time_compare(hashed_process_data->next_good_time,
1183// evtime) > 0))
1184// {
1185// if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
1186// TimeWindow time_window =
1187// lttvwindow_get_time_window(control_flow_data->tab);
1188//
1189//#ifdef EXTRA_CHECK
1190// if(ltt_time_compare(evtime, time_window.start_time) == -1
1191// || ltt_time_compare(evtime, time_window.end_time) == 1)
1192// return;
1193//#endif //EXTRA_CHECK
1194// Drawing_t *drawing = control_flow_data->drawing;
1195// guint width = drawing->width;
1196// guint x;
1197// convert_time_to_pixels(
1198// time_window,
1199// evtime,
1200// width,
1201// &x);
1202//
1203// /* Draw collision indicator */
1204// gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
1205// gdk_draw_point(hashed_process_data->pixmap,
1206// drawing->gc,
1207// x,
1208// COLLISION_POSITION(hashed_process_data->height));
1209// hashed_process_data->x.middle_marked = TRUE;
1210// }
1211// } else {
1212// TimeWindow time_window =
1213// lttvwindow_get_time_window(control_flow_data->tab);
1214//
1215//#ifdef EXTRA_CHECK
1216// if(ltt_time_compare(evtime, time_window.start_time) == -1
1217// || ltt_time_compare(evtime, time_window.end_time) == 1)
1218// return;
1219//#endif //EXTRA_CHECK
1220// Drawing_t *drawing = control_flow_data->drawing;
1221// guint width = drawing->width;
1222// guint x;
1223//
1224// convert_time_to_pixels(
1225// time_window,
1226// evtime,
1227// width,
1228// &x);
1229//
1230//
1231// /* Jump over draw if we are at the same x position */
1232// if(unlikely(x == hashed_process_data->x.middle &&
1233// hashed_process_data->x.middle_used))
1234// {
1235// if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
1236// /* Draw collision indicator */
1237// gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
1238// gdk_draw_point(hashed_process_data->pixmap,
1239// drawing->gc,
1240// x,
1241// COLLISION_POSITION(hashed_process_data->height));
1242// hashed_process_data->x.middle_marked = TRUE;
1243// }
1244// /* jump */
1245// } else {
1246// DrawContext draw_context;
1247//
1248// /* Now create the drawing context that will be used to draw
1249// * items related to the last state. */
1250// draw_context.drawable = hashed_process_data->pixmap;
1251// draw_context.gc = drawing->gc;
1252// draw_context.pango_layout = drawing->pango_layout;
1253// draw_context.drawinfo.start.x = hashed_process_data->x.middle;
1254// draw_context.drawinfo.end.x = x;
1255//
1256// draw_context.drawinfo.y.over = 1;
1257// draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
1258// draw_context.drawinfo.y.under = hashed_process_data->height;
1259//
1260// draw_context.drawinfo.start.offset.over = 0;
1261// draw_context.drawinfo.start.offset.middle = 0;
1262// draw_context.drawinfo.start.offset.under = 0;
1263// draw_context.drawinfo.end.offset.over = 0;
1264// draw_context.drawinfo.end.offset.middle = 0;
1265// draw_context.drawinfo.end.offset.under = 0;
1266//
1267// {
1268// /* Draw the line */
1269// PropertiesLine prop_line = prepare_s_e_line(process);
1270// draw_line((void*)&prop_line, (void*)&draw_context);
1271//
1272// }
1273// /* become the last x position */
1274// hashed_process_data->x.middle = x;
1275// hashed_process_data->x.middle_used = TRUE;
1276// hashed_process_data->x.middle_marked = FALSE;
1277//
1278// /* Calculate the next good time */
1279// convert_pixels_to_time(width, x+1, time_window,
1280// &hashed_process_data->next_good_time);
1281// }
1282// }
1283//
1284// return 0;
1285//
1286//}
9e01e6d4 1287
9e01e6d4 1288
58a9b31b 1289/* before_process_release_hook
1290 *
1291 * Draw lines for process event.
1292 *
1293 * @param hook_data ControlFlowData structure of the viewer.
1294 * @param call_data Event context.
1295 *
1296 * This function adds items to be drawn in a queue for each process.
1297 *
1298 */
9e01e6d4 1299
58a9b31b 1300//int before_process_release_hook(void *hook_data, void *call_data)
1301//{
1302// LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
1303// EventsRequest *events_request = (EventsRequest*)thf->hook_data;
1304//
1305// ControlFlowData *control_flow_data = events_request->viewer_data;
1306//
1307// LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
1308//
1309// LttvTracefileState *tfs = (LttvTracefileState *)call_data;
1310//
1311// LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
1312//
1313// LttEvent *e;
1314// e = ltt_tracefile_get_event(tfc->tf);
1315//
1316// LttvFilter *filter = control_flow_data->filter;
1317// if(filter != NULL && filter->head != NULL)
1318// if(!lttv_filter_tree_parse(filter->head,e,tfc->tf,
1319// tfc->t_context->t,tfc,NULL,NULL))
1320// return FALSE;
1321//
1322// LttTime evtime = ltt_event_time(e);
1323//
1324// guint trace_num = ts->parent.index;
1325//
1326// guint pid;
1327// {
1328// pid = ltt_event_get_long_unsigned(e, thf->f1);
1329// }
1330//
1331// /* Add process to process list (if not present) */
1332// /* Don't care about the process if it's not in the state hash already :
1333// * that means a process that has never done anything in the trace and
1334// * unknown suddently gets destroyed : no state meaningful to show. */
1335// LttvProcessState *process = lttv_state_find_process(ts, ANY_CPU, pid);
1336//
1337// if(process != NULL) {
1338// LttTime birth;
1339// guint pl_height = 0;
1340// HashedResourceData *hashed_process_data = NULL;
1341//
1342// ProcessList *process_list = control_flow_data->process_list;
1343//
1344// birth = process->creation_time;
1345//
1346// /* Cannot use current process : this event happens on another process,
1347// * action done by the parent. */
1348// hashed_process_data = processlist_get_process_data(process_list, "CPU0");
1349//// hashed_process_data = processlist_get_process_data(process_list,
1350//// pid,
1351//// process->cpu,
1352//// &birth,
1353//// trace_num);
1354// if(unlikely(hashed_process_data == NULL))
1355// {
1356// g_assert(pid == 0 || pid != process->ppid);
1357// /* Process not present */
1358// Drawing_t *drawing = control_flow_data->drawing;
1359// ResourceInfo *process_info;
1360// processlist_add(process_list,
1361// drawing,
1362// pid,
1363// process->tgid,
1364// process->cpu,
1365// process->ppid,
1366// &birth,
1367// trace_num,
1368// process->name,
1369// process->brand,
1370// &pl_height,
1371// &process_info,
1372// &hashed_process_data);
1373// gtk_widget_set_size_request(drawing->drawing_area,
1374// -1,
1375// pl_height);
1376// gtk_widget_queue_draw(drawing->drawing_area);
1377// }
1378//
1379// /* Now, the process is in the state hash and our own process hash.
1380// * We definitely can draw the items related to the ending state.
1381// */
1382//
1383// if(likely(ltt_time_compare(hashed_process_data->next_good_time,
1384// evtime) > 0))
1385// {
1386// if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
1387// TimeWindow time_window =
1388// lttvwindow_get_time_window(control_flow_data->tab);
1389//
1390//#ifdef EXTRA_CHECK
1391// if(ltt_time_compare(evtime, time_window.start_time) == -1
1392// || ltt_time_compare(evtime, time_window.end_time) == 1)
1393// return;
1394//#endif //EXTRA_CHECK
1395// Drawing_t *drawing = control_flow_data->drawing;
1396// guint width = drawing->width;
1397// guint x;
1398// convert_time_to_pixels(
1399// time_window,
1400// evtime,
1401// width,
1402// &x);
1403//
1404// /* Draw collision indicator */
1405// gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
1406// gdk_draw_point(hashed_process_data->pixmap,
1407// drawing->gc,
1408// x,
1409// COLLISION_POSITION(hashed_process_data->height));
1410// hashed_process_data->x.middle_marked = TRUE;
1411// }
1412// } else {
1413// TimeWindow time_window =
1414// lttvwindow_get_time_window(control_flow_data->tab);
1415//
1416//#ifdef EXTRA_CHECK
1417// if(ltt_time_compare(evtime, time_window.start_time) == -1
1418// || ltt_time_compare(evtime, time_window.end_time) == 1)
1419// return;
1420//#endif //EXTRA_CHECK
1421// Drawing_t *drawing = control_flow_data->drawing;
1422// guint width = drawing->width;
1423// guint x;
1424//
1425// convert_time_to_pixels(
1426// time_window,
1427// evtime,
1428// width,
1429// &x);
1430//
1431//
1432// /* Jump over draw if we are at the same x position */
1433// if(unlikely(x == hashed_process_data->x.middle &&
1434// hashed_process_data->x.middle_used))
1435// {
1436// if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
1437// /* Draw collision indicator */
1438// gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
1439// gdk_draw_point(hashed_process_data->pixmap,
1440// drawing->gc,
1441// x,
1442// COLLISION_POSITION(hashed_process_data->height));
1443// hashed_process_data->x.middle_marked = TRUE;
1444// }
1445// /* jump */
1446// } else {
1447// DrawContext draw_context;
1448//
1449// /* Now create the drawing context that will be used to draw
1450// * items related to the last state. */
1451// draw_context.drawable = hashed_process_data->pixmap;
1452// draw_context.gc = drawing->gc;
1453// draw_context.pango_layout = drawing->pango_layout;
1454// draw_context.drawinfo.start.x = hashed_process_data->x.middle;
1455// draw_context.drawinfo.end.x = x;
1456//
1457// draw_context.drawinfo.y.over = 1;
1458// draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
1459// draw_context.drawinfo.y.under = hashed_process_data->height;
1460//
1461// draw_context.drawinfo.start.offset.over = 0;
1462// draw_context.drawinfo.start.offset.middle = 0;
1463// draw_context.drawinfo.start.offset.under = 0;
1464// draw_context.drawinfo.end.offset.over = 0;
1465// draw_context.drawinfo.end.offset.middle = 0;
1466// draw_context.drawinfo.end.offset.under = 0;
1467//
1468// {
1469// /* Draw the line */
1470// PropertiesLine prop_line = prepare_s_e_line(process);
1471// draw_line((void*)&prop_line, (void*)&draw_context);
1472//
1473// }
1474// /* become the last x position */
1475// hashed_process_data->x.middle = x;
1476// hashed_process_data->x.middle_used = TRUE;
1477// hashed_process_data->x.middle_marked = FALSE;
1478//
1479// /* Calculate the next good time */
1480// convert_pixels_to_time(width, x+1, time_window,
1481// &hashed_process_data->next_good_time);
1482// }
1483// }
1484// }
1485//
1486// return 0;
1487//}
9e01e6d4 1488
58a9b31b 1489/* after_process_fork_hook
9e01e6d4 1490 *
1491 * Create the processlist entry for the child process. Put the last
1492 * position in x at the current time value.
1493 *
1494 * @param hook_data ControlFlowData structure of the viewer.
1495 * @param call_data Event context.
1496 *
1497 * This function adds items to be drawn in a queue for each process.
1498 *
1499 */
58a9b31b 1500//int after_process_fork_hook(void *hook_data, void *call_data)
1501//{
1502// LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
1503// EventsRequest *events_request = (EventsRequest*)thf->hook_data;
1504// ControlFlowData *control_flow_data = events_request->viewer_data;
1505//
1506// LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
1507//
1508// LttvTracefileState *tfs = (LttvTracefileState *)call_data;
1509//
1510// LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
1511//
1512// LttEvent *e;
1513// e = ltt_tracefile_get_event(tfc->tf);
1514//
1515// LttvFilter *filter = control_flow_data->filter;
1516// if(filter != NULL && filter->head != NULL)
1517// if(!lttv_filter_tree_parse(filter->head,e,tfc->tf,
1518// tfc->t_context->t,tfc,NULL,NULL))
1519// return FALSE;
1520//
1521// LttTime evtime = ltt_event_time(e);
1522//
1523// guint child_pid;
1524// {
1525// child_pid = ltt_event_get_long_unsigned(e, thf->f2);
1526// }
1527//
1528// /* Add process to process list (if not present) */
1529// LttvProcessState *process_child;
1530// LttTime birth;
1531// guint pl_height = 0;
1532// HashedResourceData *hashed_process_data_child = NULL;
1533//
1534// ProcessList *process_list = control_flow_data->process_list;
1535//
1536// /* Find child in the list... */
1537// process_child = lttv_state_find_process(ts, ANY_CPU, child_pid);
1538// /* It should exist, because we are after the state update. */
1539// g_assert(process_child != NULL);
1540//
1541// birth = process_child->creation_time;
1542// guint trace_num = ts->parent.index;
1543//
1544// /* Cannot use current process, because this action is done by the parent
1545// * on its child. */
1546// hashed_process_data_child = processlist_get_process_data(process_list, "CPU0");
1547//// hashed_process_data_child = processlist_get_process_data(process_list,
1548//// child_pid,
1549//// process_child->cpu,
1550//// &birth,
1551//// trace_num);
1552// if(likely(hashed_process_data_child == NULL))
1553// {
1554// g_assert(child_pid == 0 || child_pid != process_child->ppid);
1555// /* Process not present */
1556// Drawing_t *drawing = control_flow_data->drawing;
1557// ResourceInfo *process_info;
1558// processlist_add(process_list,
1559// drawing,
1560// child_pid,
1561// process_child->tgid,
1562// process_child->cpu,
1563// process_child->ppid,
1564// &birth,
1565// trace_num,
1566// process_child->name,
1567// process_child->brand,
1568// &pl_height,
1569// &process_info,
1570// &hashed_process_data_child);
1571// gtk_widget_set_size_request(drawing->drawing_area,
1572// -1,
1573// pl_height);
1574// gtk_widget_queue_draw(drawing->drawing_area);
1575// } else {
1576// processlist_set_ppid(process_list, process_child->ppid,
1577// hashed_process_data_child);
1578// processlist_set_tgid(process_list, process_child->tgid,
1579// hashed_process_data_child);
1580// }
1581//
1582//
1583// if(likely(ltt_time_compare(hashed_process_data_child->next_good_time,
1584// evtime) <= 0))
1585// {
1586// TimeWindow time_window =
1587// lttvwindow_get_time_window(control_flow_data->tab);
1588//
1589//#ifdef EXTRA_CHECK
1590// if(ltt_time_compare(evtime, time_window.start_time) == -1
1591// || ltt_time_compare(evtime, time_window.end_time) == 1)
1592// return;
1593//#endif //EXTRA_CHECK
1594// Drawing_t *drawing = control_flow_data->drawing;
1595// guint width = drawing->width;
1596// guint new_x;
1597// convert_time_to_pixels(
1598// time_window,
1599// evtime,
1600// width,
1601// &new_x);
1602//
1603// if(likely(hashed_process_data_child->x.over != new_x)) {
1604// hashed_process_data_child->x.over = new_x;
1605// hashed_process_data_child->x.over_used = FALSE;
1606// hashed_process_data_child->x.over_marked = FALSE;
1607// }
1608// if(likely(hashed_process_data_child->x.middle != new_x)) {
1609// hashed_process_data_child->x.middle = new_x;
1610// hashed_process_data_child->x.middle_used = FALSE;
1611// hashed_process_data_child->x.middle_marked = FALSE;
1612// }
1613// if(likely(hashed_process_data_child->x.under != new_x)) {
1614// hashed_process_data_child->x.under = new_x;
1615// hashed_process_data_child->x.under_used = FALSE;
1616// hashed_process_data_child->x.under_marked = FALSE;
1617// }
1618// }
1619// return 0;
1620//}
9e01e6d4 1621
9e01e6d4 1622
9e01e6d4 1623
58a9b31b 1624/* after_process_exit_hook
1625 *
1626 * Create the processlist entry for the child process. Put the last
1627 * position in x at the current time value.
1628 *
1629 * @param hook_data ControlFlowData structure of the viewer.
1630 * @param call_data Event context.
1631 *
1632 * This function adds items to be drawn in a queue for each process.
1633 *
1634 */
1635//int after_process_exit_hook(void *hook_data, void *call_data)
1636//{
1637// LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
1638// EventsRequest *events_request = (EventsRequest*)thf->hook_data;
1639// ControlFlowData *control_flow_data = events_request->viewer_data;
1640//
1641// LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
1642//
1643// LttvTracefileState *tfs = (LttvTracefileState *)call_data;
1644//
1645// LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
1646//
1647// LttEvent *e;
1648// e = ltt_tracefile_get_event(tfc->tf);
1649//
1650// LttvFilter *filter = control_flow_data->filter;
1651// if(filter != NULL && filter->head != NULL)
1652// if(!lttv_filter_tree_parse(filter->head,e,tfc->tf,
1653// tfc->t_context->t,tfc,NULL,NULL))
1654// return FALSE;
1655//
1656// LttTime evtime = ltt_event_time(e);
1657//
1658// /* Add process to process list (if not present) */
1659// //LttvProcessState *process = tfs->process;
1660// guint cpu = tfs->cpu;
1661// guint trace_num = ts->parent.index;
1662// LttvProcessState *process = ts->running_process[cpu];
1663//
1664// /* It should exist, because we are after the state update. */
1665// g_assert(process != NULL);
1666//
1667// guint pid = process->pid;
1668// LttTime birth;
1669// guint pl_height = 0;
1670// HashedResourceData *hashed_process_data = NULL;
1671//
1672// ProcessList *process_list = control_flow_data->process_list;
1673//
1674// birth = process->creation_time;
1675//
1676// if(likely(process_list->current_hash_data[trace_num][cpu] != NULL) ){
1677// hashed_process_data = process_list->current_hash_data[trace_num][cpu];
1678// } else {
1679// hashed_process_data = processlist_get_process_data(process_list, "CPU0");
1680//// hashed_process_data = processlist_get_process_data(process_list,
1681//// pid,
1682//// process->cpu,
1683//// &birth,
1684//// trace_num);
1685// if(unlikely(hashed_process_data == NULL))
1686// {
1687// g_assert(pid == 0 || pid != process->ppid);
1688// /* Process not present */
1689// Drawing_t *drawing = control_flow_data->drawing;
1690// ResourceInfo *process_info;
1691// processlist_add(process_list,
1692// drawing,
1693// pid,
1694// process->tgid,
1695// process->cpu,
1696// process->ppid,
1697// &birth,
1698// trace_num,
1699// process->name,
1700// process->brand,
1701// &pl_height,
1702// &process_info,
1703// &hashed_process_data);
1704// gtk_widget_set_size_request(drawing->drawing_area,
1705// -1,
1706// pl_height);
1707// gtk_widget_queue_draw(drawing->drawing_area);
1708// }
1709//
1710// /* Set the current process */
1711// process_list->current_hash_data[trace_num][process->cpu] =
1712// hashed_process_data;
1713// }
1714//
1715// if(unlikely(ltt_time_compare(hashed_process_data->next_good_time,
1716// evtime) <= 0))
1717// {
1718// TimeWindow time_window =
1719// lttvwindow_get_time_window(control_flow_data->tab);
1720//
1721//#ifdef EXTRA_CHECK
1722// if(ltt_time_compare(evtime, time_window.start_time) == -1
1723// || ltt_time_compare(evtime, time_window.end_time) == 1)
1724// return;
1725//#endif //EXTRA_CHECK
1726// Drawing_t *drawing = control_flow_data->drawing;
1727// guint width = drawing->width;
1728// guint new_x;
1729// convert_time_to_pixels(
1730// time_window,
1731// evtime,
1732// width,
1733// &new_x);
1734// if(unlikely(hashed_process_data->x.middle != new_x)) {
1735// hashed_process_data->x.middle = new_x;
1736// hashed_process_data->x.middle_used = FALSE;
1737// hashed_process_data->x.middle_marked = FALSE;
1738// }
1739// }
1740//
1741// return 0;
1742//}
9e01e6d4 1743
9e01e6d4 1744
58a9b31b 1745/* Get the filename of the process to print */
1746//int after_fs_exec_hook(void *hook_data, void *call_data)
1747//{
1748// LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
1749// EventsRequest *events_request = (EventsRequest*)thf->hook_data;
1750// ControlFlowData *control_flow_data = events_request->viewer_data;
1751//
1752// LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
1753//
1754// LttvTracefileState *tfs = (LttvTracefileState *)call_data;
1755//
1756// LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
1757//
1758// LttEvent *e;
1759// e = ltt_tracefile_get_event(tfc->tf);
1760//
1761// LttvFilter *filter = control_flow_data->filter;
1762// if(filter != NULL && filter->head != NULL)
1763// if(!lttv_filter_tree_parse(filter->head,e,tfc->tf,
1764// tfc->t_context->t,tfc,NULL,NULL))
1765// return FALSE;
1766//
1767// guint cpu = tfs->cpu;
1768// guint trace_num = ts->parent.index;
1769// LttvProcessState *process = ts->running_process[cpu];
1770// g_assert(process != NULL);
1771//
1772// guint pid = process->pid;
1773//
1774// /* Well, the process_out existed : we must get it in the process hash
1775// * or add it, and draw its items.
1776// */
1777// /* Add process to process list (if not present) */
1778// guint pl_height = 0;
1779// HashedResourceData *hashed_process_data = NULL;
1780// ProcessList *process_list = control_flow_data->process_list;
1781// LttTime birth = process->creation_time;
1782//
1783// if(likely(process_list->current_hash_data[trace_num][cpu] != NULL)) {
1784// hashed_process_data = process_list->current_hash_data[trace_num][cpu];
1785// } else {
1786// hashed_process_data = processlist_get_process_data(process_list, "CPU0");
1787//// hashed_process_data = processlist_get_process_data(process_list,
1788//// pid,
1789//// process->cpu,
1790//// &birth,
1791//// trace_num);
1792// if(unlikely(hashed_process_data == NULL))
1793// {
1794// g_assert(pid == 0 || pid != process->ppid);
1795// ResourceInfo *process_info;
1796// /* Process not present */
1797// Drawing_t *drawing = control_flow_data->drawing;
1798// processlist_add(process_list,
1799// drawing,
1800// pid,
1801// process->tgid,
1802// process->cpu,
1803// process->ppid,
1804// &birth,
1805// trace_num,
1806// process->name,
1807// process->brand,
1808// &pl_height,
1809// &process_info,
1810// &hashed_process_data);
1811// gtk_widget_set_size_request(drawing->drawing_area,
1812// -1,
1813// pl_height);
1814// gtk_widget_queue_draw(drawing->drawing_area);
1815// }
1816// /* Set the current process */
1817// process_list->current_hash_data[trace_num][process->cpu] =
1818// hashed_process_data;
1819// }
1820//
1821// processlist_set_name(process_list, process->name, hashed_process_data);
1822//
1823// return 0;
1824//
1825//}
9e01e6d4 1826
58a9b31b 1827/* Get the filename of the process to print */
1828//int after_user_generic_thread_brand_hook(void *hook_data, void *call_data)
1829//{
1830// LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
1831// EventsRequest *events_request = (EventsRequest*)thf->hook_data;
1832// ControlFlowData *control_flow_data = events_request->viewer_data;
1833//
1834// LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
1835//
1836// LttvTracefileState *tfs = (LttvTracefileState *)call_data;
1837//
1838// LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
1839//
1840// LttEvent *e;
1841// e = ltt_tracefile_get_event(tfc->tf);
1842//
1843// LttvFilter *filter = control_flow_data->filter;
1844// if(filter != NULL && filter->head != NULL)
1845// if(!lttv_filter_tree_parse(filter->head,e,tfc->tf,
1846// tfc->t_context->t,tfc,NULL,NULL))
1847// return FALSE;
1848//
1849// guint cpu = tfs->cpu;
1850// guint trace_num = ts->parent.index;
1851// LttvProcessState *process = ts->running_process[cpu];
1852// g_assert(process != NULL);
1853//
1854// guint pid = process->pid;
1855//
1856// /* Well, the process_out existed : we must get it in the process hash
1857// * or add it, and draw its items.
1858// */
1859// /* Add process to process list (if not present) */
1860// guint pl_height = 0;
1861// HashedResourceData *hashed_process_data = NULL;
1862// ProcessList *process_list = control_flow_data->process_list;
1863// LttTime birth = process->creation_time;
1864//
1865// if(likely(process_list->current_hash_data[trace_num][cpu] != NULL)) {
1866// hashed_process_data = process_list->current_hash_data[trace_num][cpu];
1867// } else {
1868// hashed_process_data = processlist_get_process_data(process_list, "CPU0");
1869//// hashed_process_data = processlist_get_process_data(process_list,
1870//// pid,
1871//// process->cpu,
1872//// &birth,
1873//// trace_num);
1874// if(unlikely(hashed_process_data == NULL))
1875// {
1876// g_assert(pid == 0 || pid != process->ppid);
1877// ResourceInfo *process_info;
1878// /* Process not present */
1879// Drawing_t *drawing = control_flow_data->drawing;
1880// processlist_add(process_list,
1881// drawing,
1882// pid,
1883// process->tgid,
1884// process->cpu,
1885// process->ppid,
1886// &birth,
1887// trace_num,
1888// process->name,
1889// process->brand,
1890// &pl_height,
1891// &process_info,
1892// &hashed_process_data);
1893// gtk_widget_set_size_request(drawing->drawing_area,
1894// -1,
1895// pl_height);
1896// gtk_widget_queue_draw(drawing->drawing_area);
1897// }
1898// /* Set the current process */
1899// process_list->current_hash_data[trace_num][process->cpu] =
1900// hashed_process_data;
1901// }
1902//
1903// processlist_set_brand(process_list, process->brand, hashed_process_data);
1904//
1905// return 0;
1906//
1907//}
9e01e6d4 1908
9e01e6d4 1909
58a9b31b 1910/* after_event_enum_process_hook
1911 *
1912 * Create the processlist entry for the child process. Put the last
1913 * position in x at the current time value.
1914 *
1915 * @param hook_data ControlFlowData structure of the viewer.
1916 * @param call_data Event context.
1917 *
1918 * This function adds items to be drawn in a queue for each process.
1919 *
1920 */
1921//int after_event_enum_process_hook(void *hook_data, void *call_data)
1922//{
1923// LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
1924// EventsRequest *events_request = (EventsRequest*)thf->hook_data;
1925// ControlFlowData *control_flow_data = events_request->viewer_data;
1926//
1927// LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
1928//
1929// LttvTracefileState *tfs = (LttvTracefileState *)call_data;
1930//
1931// LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
1932//
1933// guint first_cpu, nb_cpus, cpu;
1934//
1935// LttEvent *e;
1936// e = ltt_tracefile_get_event(tfc->tf);
1937//
1938// LttvFilter *filter = control_flow_data->filter;
1939// if(filter != NULL && filter->head != NULL)
1940// if(!lttv_filter_tree_parse(filter->head,e,tfc->tf,
1941// tfc->t_context->t,tfc,NULL,NULL))
1942// return FALSE;
1943//
1944// LttTime evtime = ltt_event_time(e);
1945//
1946// /* Add process to process list (if not present) */
1947// LttvProcessState *process_in;
1948// LttTime birth;
1949// guint pl_height = 0;
1950// HashedResourceData *hashed_process_data_in = NULL;
1951//
1952// ProcessList *process_list = control_flow_data->process_list;
1953// guint trace_num = ts->parent.index;
1954//
1955// guint pid_in;
1956// {
1957// pid_in = ltt_event_get_long_unsigned(e, thf->f1);
1958// }
1959//
1960// if(pid_in == 0) {
1961// first_cpu = 0;
1962// nb_cpus = ltt_trace_get_num_cpu(ts->parent.t);
1963// } else {
1964// first_cpu = ANY_CPU;
1965// nb_cpus = ANY_CPU+1;
1966// }
1967//
1968// for(cpu = first_cpu; cpu < nb_cpus; cpu++) {
1969// /* Find process pid_in in the list... */
1970// process_in = lttv_state_find_process(ts, cpu, pid_in);
1971// //process_in = tfs->process;
1972// //guint cpu = tfs->cpu;
1973// //guint trace_num = ts->parent.index;
1974// //process_in = ts->running_process[cpu];
1975// /* It should exist, because we are after the state update. */
1976// #ifdef EXTRA_CHECK
1977// //g_assert(process_in != NULL);
1978// #endif //EXTRA_CHECK
1979// birth = process_in->creation_time;
1980//
1981// hashed_process_data_in = processlist_get_process_data(process_list, "CPU0");
1982//// hashed_process_data_in = processlist_get_process_data(process_list,
1983//// pid_in,
1984//// process_in->cpu,
1985//// &birth,
1986//// trace_num);
1987// if(hashed_process_data_in == NULL)
1988// {
1989// if(pid_in != 0 && pid_in == process_in->ppid)
1990// g_critical("TEST %u , %u", pid_in, process_in->ppid);
1991// g_assert(pid_in == 0 || pid_in != process_in->ppid);
1992// ResourceInfo *process_info;
1993// Drawing_t *drawing = control_flow_data->drawing;
1994// /* Process not present */
1995// processlist_add(process_list,
1996// drawing,
1997// pid_in,
1998// process_in->tgid,
1999// process_in->cpu,
2000// process_in->ppid,
2001// &birth,
2002// trace_num,
2003// process_in->name,
2004// process_in->brand,
2005// &pl_height,
2006// &process_info,
2007// &hashed_process_data_in);
2008// gtk_widget_set_size_request(drawing->drawing_area,
2009// -1,
2010// pl_height);
2011// gtk_widget_queue_draw(drawing->drawing_area);
2012// } else {
2013// processlist_set_name(process_list, process_in->name,
2014// hashed_process_data_in);
2015// processlist_set_ppid(process_list, process_in->ppid,
2016// hashed_process_data_in);
2017// processlist_set_tgid(process_list, process_in->tgid,
2018// hashed_process_data_in);
2019// }
2020// }
2021// return 0;
2022//}
9e01e6d4 2023
2024
2025gint update_time_window_hook(void *hook_data, void *call_data)
2026{
2027 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
2028 Drawing_t *drawing = control_flow_data->drawing;
2029 ProcessList *process_list = control_flow_data->process_list;
2030
2031 const TimeWindowNotifyData *time_window_nofify_data =
2032 ((const TimeWindowNotifyData *)call_data);
2033
2034 TimeWindow *old_time_window =
2035 time_window_nofify_data->old_time_window;
2036 TimeWindow *new_time_window =
2037 time_window_nofify_data->new_time_window;
2038
2039 /* Update the ruler */
2040 drawing_update_ruler(control_flow_data->drawing,
2041 new_time_window);
2042
2043
2044 /* Two cases : zoom in/out or scrolling */
2045
2046 /* In order to make sure we can reuse the old drawing, the scale must
2047 * be the same and the new time interval being partly located in the
2048 * currently shown time interval. (reuse is only for scrolling)
2049 */
2050
2051 g_info("Old time window HOOK : %lu, %lu to %lu, %lu",
2052 old_time_window->start_time.tv_sec,
2053 old_time_window->start_time.tv_nsec,
2054 old_time_window->time_width.tv_sec,
2055 old_time_window->time_width.tv_nsec);
2056
2057 g_info("New time window HOOK : %lu, %lu to %lu, %lu",
2058 new_time_window->start_time.tv_sec,
2059 new_time_window->start_time.tv_nsec,
2060 new_time_window->time_width.tv_sec,
2061 new_time_window->time_width.tv_nsec);
2062
2063 if( new_time_window->time_width.tv_sec == old_time_window->time_width.tv_sec
2064 && new_time_window->time_width.tv_nsec == old_time_window->time_width.tv_nsec)
2065 {
2066 /* Same scale (scrolling) */
2067 g_info("scrolling");
2068 LttTime *ns = &new_time_window->start_time;
2069 LttTime *nw = &new_time_window->time_width;
2070 LttTime *os = &old_time_window->start_time;
2071 LttTime *ow = &old_time_window->time_width;
2072 LttTime old_end = old_time_window->end_time;
2073 LttTime new_end = new_time_window->end_time;
2074 //if(ns<os+w<ns+w)
2075 //if(ns<os+w && os+w<ns+w)
2076 //if(ns<old_end && os<ns)
2077 if(ltt_time_compare(*ns, old_end) == -1
2078 && ltt_time_compare(*os, *ns) == -1)
2079 {
2080 g_info("scrolling near right");
2081 /* Scroll right, keep right part of the screen */
2082 guint x = 0;
2083 guint width = control_flow_data->drawing->width;
2084 convert_time_to_pixels(
2085 *old_time_window,
2086 *ns,
2087 width,
2088 &x);
2089
2090 /* Copy old data to new location */
2091 copy_pixmap_region(process_list,
2092 NULL,
2093 control_flow_data->drawing->drawing_area->style->black_gc,
2094 NULL,
2095 x, 0,
2096 0, 0,
2097 control_flow_data->drawing->width-x+SAFETY, -1);
2098
2099 if(drawing->damage_begin == drawing->damage_end)
2100 drawing->damage_begin = control_flow_data->drawing->width-x;
2101 else
2102 drawing->damage_begin = 0;
2103
2104 drawing->damage_end = control_flow_data->drawing->width;
2105
2106 /* Clear the data request background, but not SAFETY */
2107 rectangle_pixmap(process_list,
2108 control_flow_data->drawing->drawing_area->style->black_gc,
2109 TRUE,
2110 drawing->damage_begin+SAFETY, 0,
2111 drawing->damage_end - drawing->damage_begin, // do not overlap
2112 -1);
2113 gtk_widget_queue_draw(drawing->drawing_area);
2114 //gtk_widget_queue_draw_area (drawing->drawing_area,
2115 // 0,0,
2116 // control_flow_data->drawing->width,
2117 // control_flow_data->drawing->height);
2118
2119 /* Get new data for the rest. */
2120 drawing_data_request(control_flow_data->drawing,
2121 drawing->damage_begin, 0,
2122 drawing->damage_end - drawing->damage_begin,
2123 control_flow_data->drawing->height);
2124 } else {
2125 //if(ns<os<ns+w)
2126 //if(ns<os && os<ns+w)
2127 //if(ns<os && os<new_end)
2128 if(ltt_time_compare(*ns,*os) == -1
2129 && ltt_time_compare(*os,new_end) == -1)
2130 {
2131 g_info("scrolling near left");
2132 /* Scroll left, keep left part of the screen */
2133 guint x = 0;
2134 guint width = control_flow_data->drawing->width;
2135 convert_time_to_pixels(
2136 *new_time_window,
2137 *os,
2138 width,
2139 &x);
2140
2141 /* Copy old data to new location */
2142 copy_pixmap_region (process_list,
2143 NULL,
2144 control_flow_data->drawing->drawing_area->style->black_gc,
2145 NULL,
2146 0, 0,
2147 x, 0,
2148 -1, -1);
2149
2150 if(drawing->damage_begin == drawing->damage_end)
2151 drawing->damage_end = x;
2152 else
2153 drawing->damage_end =
2154 control_flow_data->drawing->width;
2155
2156 drawing->damage_begin = 0;
2157
2158 rectangle_pixmap (process_list,
2159 control_flow_data->drawing->drawing_area->style->black_gc,
2160 TRUE,
2161 drawing->damage_begin, 0,
2162 drawing->damage_end - drawing->damage_begin, // do not overlap
2163 -1);
2164
2165 gtk_widget_queue_draw(drawing->drawing_area);
2166 //gtk_widget_queue_draw_area (drawing->drawing_area,
2167 // 0,0,
2168 // control_flow_data->drawing->width,
2169 // control_flow_data->drawing->height);
2170
2171
2172 /* Get new data for the rest. */
2173 drawing_data_request(control_flow_data->drawing,
2174 drawing->damage_begin, 0,
2175 drawing->damage_end - drawing->damage_begin,
2176 control_flow_data->drawing->height);
2177
2178 } else {
2179 if(ltt_time_compare(*ns,*os) == 0)
2180 {
2181 g_info("not scrolling");
2182 } else {
2183 g_info("scrolling far");
2184 /* Cannot reuse any part of the screen : far jump */
2185
2186
2187 rectangle_pixmap (process_list,
2188 control_flow_data->drawing->drawing_area->style->black_gc,
2189 TRUE,
2190 0, 0,
2191 control_flow_data->drawing->width+SAFETY, // do not overlap
2192 -1);
2193
2194 //gtk_widget_queue_draw_area (drawing->drawing_area,
2195 // 0,0,
2196 // control_flow_data->drawing->width,
2197 // control_flow_data->drawing->height);
2198 gtk_widget_queue_draw(drawing->drawing_area);
2199
2200 drawing->damage_begin = 0;
2201 drawing->damage_end = control_flow_data->drawing->width;
2202
2203 drawing_data_request(control_flow_data->drawing,
2204 0, 0,
2205 control_flow_data->drawing->width,
2206 control_flow_data->drawing->height);
2207
2208 }
2209 }
2210 }
2211 } else {
2212 /* Different scale (zoom) */
2213 g_info("zoom");
2214
2215 rectangle_pixmap (process_list,
2216 control_flow_data->drawing->drawing_area->style->black_gc,
2217 TRUE,
2218 0, 0,
2219 control_flow_data->drawing->width+SAFETY, // do not overlap
2220 -1);
2221
2222 //gtk_widget_queue_draw_area (drawing->drawing_area,
2223 // 0,0,
2224 // control_flow_data->drawing->width,
2225 // control_flow_data->drawing->height);
2226 gtk_widget_queue_draw(drawing->drawing_area);
2227
2228 drawing->damage_begin = 0;
2229 drawing->damage_end = control_flow_data->drawing->width;
2230
2231 drawing_data_request(control_flow_data->drawing,
2232 0, 0,
2233 control_flow_data->drawing->width,
2234 control_flow_data->drawing->height);
2235 }
2236
2237 /* Update directly when scrolling */
2238 gdk_window_process_updates(control_flow_data->drawing->drawing_area->window,
2239 TRUE);
2240
2241 return 0;
2242}
2243
2244gint traceset_notify(void *hook_data, void *call_data)
2245{
2246 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
2247 Drawing_t *drawing = control_flow_data->drawing;
2248
2249 if(unlikely(drawing->gc == NULL)) {
2250 return FALSE;
2251 }
2252 if(drawing->dotted_gc == NULL) {
2253 return FALSE;
2254 }
2255
2256 drawing_clear(control_flow_data->drawing);
2257 processlist_clear(control_flow_data->process_list);
2258 gtk_widget_set_size_request(
2259 control_flow_data->drawing->drawing_area,
2260 -1, processlist_get_height(control_flow_data->process_list));
2261 redraw_notify(control_flow_data, NULL);
2262
2263 request_background_data(control_flow_data);
2264
2265 return FALSE;
2266}
2267
2268gint redraw_notify(void *hook_data, void *call_data)
2269{
2270 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
2271 Drawing_t *drawing = control_flow_data->drawing;
2272 GtkWidget *widget = drawing->drawing_area;
2273
2274 drawing->damage_begin = 0;
2275 drawing->damage_end = drawing->width;
2276
2277 /* fun feature, to be separated someday... */
2278 drawing_clear(control_flow_data->drawing);
2279 processlist_clear(control_flow_data->process_list);
2280 gtk_widget_set_size_request(
2281 control_flow_data->drawing->drawing_area,
2282 -1, processlist_get_height(control_flow_data->process_list));
2283 // Clear the images
2284 rectangle_pixmap (control_flow_data->process_list,
2285 widget->style->black_gc,
2286 TRUE,
2287 0, 0,
2288 drawing->alloc_width,
2289 -1);
2290
2291 gtk_widget_queue_draw(drawing->drawing_area);
2292
2293 if(drawing->damage_begin < drawing->damage_end)
2294 {
2295 drawing_data_request(drawing,
2296 drawing->damage_begin,
2297 0,
2298 drawing->damage_end-drawing->damage_begin,
2299 drawing->height);
2300 }
2301
2302 //gtk_widget_queue_draw_area(drawing->drawing_area,
2303 // 0,0,
2304 // drawing->width,
2305 // drawing->height);
2306 return FALSE;
2307
2308}
2309
2310
2311gint continue_notify(void *hook_data, void *call_data)
2312{
2313 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
2314 Drawing_t *drawing = control_flow_data->drawing;
2315
2316 //g_assert(widget->allocation.width == drawing->damage_end);
2317
2318 if(drawing->damage_begin < drawing->damage_end)
2319 {
2320 drawing_data_request(drawing,
2321 drawing->damage_begin,
2322 0,
2323 drawing->damage_end-drawing->damage_begin,
2324 drawing->height);
2325 }
2326
2327 return FALSE;
2328}
2329
2330
2331gint update_current_time_hook(void *hook_data, void *call_data)
2332{
2333 ControlFlowData *control_flow_data = (ControlFlowData*)hook_data;
2334 Drawing_t *drawing = control_flow_data->drawing;
2335
2336 LttTime current_time = *((LttTime*)call_data);
2337
2338 TimeWindow time_window =
2339 lttvwindow_get_time_window(control_flow_data->tab);
2340
2341 LttTime time_begin = time_window.start_time;
2342 LttTime width = time_window.time_width;
2343 LttTime half_width;
2344 {
2345 guint64 time_ll = ltt_time_to_uint64(width);
2346 time_ll = time_ll >> 1; /* divide by two */
2347 half_width = ltt_time_from_uint64(time_ll);
2348 }
2349 LttTime time_end = ltt_time_add(time_begin, width);
2350
2351 LttvTracesetContext * tsc =
2352 lttvwindow_get_traceset_context(control_flow_data->tab);
2353
2354 LttTime trace_start = tsc->time_span.start_time;
2355 LttTime trace_end = tsc->time_span.end_time;
2356
2357 g_info("New current time HOOK : %lu, %lu", current_time.tv_sec,
2358 current_time.tv_nsec);
2359
2360
2361
2362 /* If current time is inside time interval, just move the highlight
2363 * bar */
2364
2365 /* Else, we have to change the time interval. We have to tell it
2366 * to the main window. */
2367 /* The time interval change will take care of placing the current
2368 * time at the center of the visible area, or nearest possible if we are
2369 * at one end of the trace. */
2370
2371
2372 if(ltt_time_compare(current_time, time_begin) < 0)
2373 {
2374 TimeWindow new_time_window;
2375
2376 if(ltt_time_compare(current_time,
2377 ltt_time_add(trace_start,half_width)) < 0)
2378 time_begin = trace_start;
2379 else
2380 time_begin = ltt_time_sub(current_time,half_width);
2381
2382 new_time_window.start_time = time_begin;
2383 new_time_window.time_width = width;
2384 new_time_window.time_width_double = ltt_time_to_double(width);
2385 new_time_window.end_time = ltt_time_add(time_begin, width);
2386
2387 lttvwindow_report_time_window(control_flow_data->tab, new_time_window);
2388 }
2389 else if(ltt_time_compare(current_time, time_end) > 0)
2390 {
2391 TimeWindow new_time_window;
2392
2393 if(ltt_time_compare(current_time, ltt_time_sub(trace_end, half_width)) > 0)
2394 time_begin = ltt_time_sub(trace_end,width);
2395 else
2396 time_begin = ltt_time_sub(current_time,half_width);
2397
2398 new_time_window.start_time = time_begin;
2399 new_time_window.time_width = width;
2400 new_time_window.time_width_double = ltt_time_to_double(width);
2401 new_time_window.end_time = ltt_time_add(time_begin, width);
2402
2403 lttvwindow_report_time_window(control_flow_data->tab, new_time_window);
2404
2405 }
2406 gtk_widget_queue_draw(control_flow_data->drawing->drawing_area);
2407
2408 /* Update directly when scrolling */
2409 gdk_window_process_updates(control_flow_data->drawing->drawing_area->window,
2410 TRUE);
2411
2412 return 0;
2413}
2414
2415typedef struct _ClosureData {
2416 EventsRequest *events_request;
2417 LttvTracesetState *tss;
2418 LttTime end_time;
2419 guint x_end;
2420} ClosureData;
2421
58a9b31b 2422/* Draw line until end of the screen */
9e01e6d4 2423
2424void draw_closure(gpointer key, gpointer value, gpointer user_data)
2425{
44ffb95f 2426 ResourceInfo *process_info = (ResourceInfo*)key;
2427 HashedResourceData *hashed_process_data = (HashedResourceData*)value;
2428 ClosureData *closure_data = (ClosureData*)user_data;
2429
2430 EventsRequest *events_request = closure_data->events_request;
2431 ControlFlowData *control_flow_data = events_request->viewer_data;
2432
2433 LttvTracesetState *tss = closure_data->tss;
2434 LttvTracesetContext *tsc = (LttvTracesetContext*)tss;
2435
2436 LttTime evtime = closure_data->end_time;
2437
2438 gboolean dodraw = TRUE;
2439
2440 {
2441 /* For the process */
2442 /* First, check if the current process is in the state computation
2443 * process list. If it is there, that means we must add it right now and
2444 * draw items from the beginning of the read for it. If it is not
2445 * present, it's a new process and it was not present : it will
2446 * be added after the state update. */
2447#ifdef EXTRA_CHECK
2448 g_assert(lttv_traceset_number(tsc->ts) > 0);
2449#endif //EXTRA_CHECK
2450 LttvTraceContext *tc = tsc->traces[process_info->trace_num];
2451 LttvTraceState *ts = (LttvTraceState*)tc;
2452
2453#if 0
2454 //FIXME : optimize data structures.
2455 LttvTracefileState *tfs;
2456 LttvTracefileContext *tfc;
2457 guint i;
2458 for(i=0;i<tc->tracefiles->len;i++) {
2459 tfc = g_array_index(tc->tracefiles, LttvTracefileContext*, i);
2460 if(ltt_tracefile_name(tfc->tf) == LTT_NAME_CPU
2461 && tfs->cpu == process_info->cpu)
2462 break;
2463
2464 }
2465 g_assert(i<tc->tracefiles->len);
2466 tfs = LTTV_TRACEFILE_STATE(tfc);
2467#endif //0
2468 // LttvTracefileState *tfs =
2469 // (LttvTracefileState*)tsc->traces[process_info->trace_num]->
2470 // tracefiles[process_info->cpu];
2471
58a9b31b 2472// LttvProcessState *process;
2473// process = lttv_state_find_process(ts, process_info->cpu,
2474// process_info->pid);
44ffb95f 2475
58a9b31b 2476// if(unlikely(process != NULL)) {
44ffb95f 2477
58a9b31b 2478// LttvFilter *filter = control_flow_data->filter;
2479// if(filter != NULL && filter->head != NULL)
2480// if(!lttv_filter_tree_parse(filter->head,NULL,NULL,
2481// tc->t,NULL,process,tc))
2482// dodraw = FALSE;
44ffb95f 2483
2484 /* Only draw for processes that are currently in the trace states */
2485
2486 ProcessList *process_list = control_flow_data->process_list;
2487#ifdef EXTRA_CHECK
2488 /* Should be alike when background info is ready */
2489 if(control_flow_data->background_info_waiting==0)
2490 g_assert(ltt_time_compare(process->creation_time,
2491 process_info->birth) == 0);
2492#endif //EXTRA_CHECK
2493
2494 /* Now, the process is in the state hash and our own process hash.
2495 * We definitely can draw the items related to the ending state.
2496 */
2497
2498 if(unlikely(ltt_time_compare(hashed_process_data->next_good_time,
2499 evtime) <= 0))
2500 {
2501 TimeWindow time_window =
2502 lttvwindow_get_time_window(control_flow_data->tab);
2503
2504#ifdef EXTRA_CHECK
2505 if(ltt_time_compare(evtime, time_window.start_time) == -1
2506 || ltt_time_compare(evtime, time_window.end_time) == 1)
2507 return;
2508#endif //EXTRA_CHECK
2509 Drawing_t *drawing = control_flow_data->drawing;
2510 guint width = drawing->width;
2511
2512 guint x = closure_data->x_end;
2513
2514 DrawContext draw_context;
2515
2516 /* Now create the drawing context that will be used to draw
2517 * items related to the last state. */
2518 draw_context.drawable = hashed_process_data->pixmap;
2519 draw_context.gc = drawing->gc;
2520 draw_context.pango_layout = drawing->pango_layout;
2521 draw_context.drawinfo.end.x = x;
2522
2523 draw_context.drawinfo.y.over = 1;
2524 draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
2525 draw_context.drawinfo.y.under = hashed_process_data->height;
2526
2527 draw_context.drawinfo.start.offset.over = 0;
2528 draw_context.drawinfo.start.offset.middle = 0;
2529 draw_context.drawinfo.start.offset.under = 0;
2530 draw_context.drawinfo.end.offset.over = 0;
2531 draw_context.drawinfo.end.offset.middle = 0;
2532 draw_context.drawinfo.end.offset.under = 0;
2533#if 0
2534 /* Jump over draw if we are at the same x position */
2535 if(x == hashed_process_data->x.over)
2536 {
2537 /* jump */
2538 } else {
2539 draw_context.drawinfo.start.x = hashed_process_data->x.over;
2540 /* Draw the line */
2541 PropertiesLine prop_line = prepare_execmode_line(process);
2542 draw_line((void*)&prop_line, (void*)&draw_context);
2543
2544 hashed_process_data->x.over = x;
2545 }
2546#endif //0
2547
2548 if(unlikely(x == hashed_process_data->x.middle &&
2549 hashed_process_data->x.middle_used)) {
2550#if 0 /* do not mark closure : not missing information */
2551 if(hashed_process_data->x.middle_marked == FALSE) {
2552 /* Draw collision indicator */
2553 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
2554 gdk_draw_point(drawing->pixmap,
2555 drawing->gc,
2556 x,
2557 y+(height/2)-3);
2558 hashed_process_data->x.middle_marked = TRUE;
2559 }
2560#endif //0
2561 /* Jump */
2562 } else {
2563 draw_context.drawinfo.start.x = hashed_process_data->x.middle;
2564 /* Draw the line */
2565 if(dodraw) {
44ffb95f 2566 PropertiesLine prop_line;
2567 prop_line.line_width = STATE_LINE_WIDTH;
2568 prop_line.style = GDK_LINE_SOLID;
2569 prop_line.y = MIDDLE;
598026ba 2570 cpu_set_line_color(&prop_line, ts->cpu_states[process_info->id].present_state);
44ffb95f 2571
2572 draw_line((void*)&prop_line, (void*)&draw_context);
2573 }
2574
2575 /* become the last x position */
2576 if(likely(x != hashed_process_data->x.middle)) {
2577 hashed_process_data->x.middle = x;
2578 /* but don't use the pixel */
2579 hashed_process_data->x.middle_used = FALSE;
2580
2581 /* Calculate the next good time */
2582 convert_pixels_to_time(width, x+1, time_window,
2583 &hashed_process_data->next_good_time);
2584 }
2585 }
2586 }
58a9b31b 2587// }
44ffb95f 2588 }
9e01e6d4 2589 return;
2590}
2591
2592int before_chunk(void *hook_data, void *call_data)
2593{
2594 EventsRequest *events_request = (EventsRequest*)hook_data;
2595 LttvTracesetState *tss = (LttvTracesetState*)call_data;
2596 ControlFlowData *cfd = (ControlFlowData*)events_request->viewer_data;
2597#if 0
2598 /* Desactivate sort */
2599 gtk_tree_sortable_set_sort_column_id(
2600 GTK_TREE_SORTABLE(cfd->process_list->list_store),
2601 TRACE_COLUMN,
2602 GTK_SORT_ASCENDING);
2603#endif //0
2604 drawing_chunk_begin(events_request, tss);
2605
2606 return 0;
2607}
2608
2609int before_request(void *hook_data, void *call_data)
2610{
2611 EventsRequest *events_request = (EventsRequest*)hook_data;
2612 LttvTracesetState *tss = (LttvTracesetState*)call_data;
2613
2614 drawing_data_request_begin(events_request, tss);
2615
2616 return 0;
2617}
2618
2619
2620/*
2621 * after request is necessary in addition of after chunk in order to draw
2622 * lines until the end of the screen. after chunk just draws lines until
2623 * the last event.
2624 *
2625 * for each process
2626 * draw closing line
2627 * expose
2628 */
58a9b31b 2629// TODO pmf: reenable this
9e01e6d4 2630int after_request(void *hook_data, void *call_data)
2631{
58a9b31b 2632// EventsRequest *events_request = (EventsRequest*)hook_data;
2633// ControlFlowData *control_flow_data = events_request->viewer_data;
2634// LttvTracesetState *tss = (LttvTracesetState*)call_data;
2635//
2636// ProcessList *process_list = control_flow_data->process_list;
2637// LttTime end_time = events_request->end_time;
2638//
2639// ClosureData closure_data;
2640// closure_data.events_request = (EventsRequest*)hook_data;
2641// closure_data.tss = tss;
2642// closure_data.end_time = end_time;
2643//
2644// TimeWindow time_window =
2645// lttvwindow_get_time_window(control_flow_data->tab);
2646// guint width = control_flow_data->drawing->width;
2647// convert_time_to_pixels(
2648// time_window,
2649// end_time,
2650// width,
2651// &closure_data.x_end);
2652//
2653//
2654// /* Draw last items */
2655// g_hash_table_foreach(process_list->process_hash, draw_closure,
2656// (void*)&closure_data);
2657//
2658//
2659// /* Request expose */
2660// drawing_request_expose(events_request, tss, end_time);
9e01e6d4 2661 return 0;
2662}
2663
2664/*
2665 * for each process
2666 * draw closing line
2667 * expose
2668 */
2669int after_chunk(void *hook_data, void *call_data)
2670{
2671 EventsRequest *events_request = (EventsRequest*)hook_data;
2672 ControlFlowData *control_flow_data = events_request->viewer_data;
2673 LttvTracesetState *tss = (LttvTracesetState*)call_data;
2674 LttvTracesetContext *tsc = (LttvTracesetContext*)call_data;
2675 LttvTracefileContext *tfc = lttv_traceset_context_get_current_tfc(tsc);
2676 LttTime end_time;
2677
2678 ProcessList *process_list = control_flow_data->process_list;
2679 guint i;
2680 LttvTraceset *traceset = tsc->ts;
2681 guint nb_trace = lttv_traceset_number(traceset);
2682
2683 /* Only execute when called for the first trace's events request */
2684 if(!process_list->current_hash_data) return;
2685
2686 for(i = 0 ; i < nb_trace ; i++) {
2687 g_free(process_list->current_hash_data[i]);
2688 }
2689 g_free(process_list->current_hash_data);
2690 process_list->current_hash_data = NULL;
2691
2692 if(tfc != NULL)
2693 end_time = LTT_TIME_MIN(tfc->timestamp, events_request->end_time);
2694 else /* end of traceset, or position now out of request : end */
2695 end_time = events_request->end_time;
2696
2697 ClosureData closure_data;
2698 closure_data.events_request = (EventsRequest*)hook_data;
2699 closure_data.tss = tss;
2700 closure_data.end_time = end_time;
2701
2702 TimeWindow time_window =
2703 lttvwindow_get_time_window(control_flow_data->tab);
2704 guint width = control_flow_data->drawing->width;
2705 convert_time_to_pixels(
2706 time_window,
2707 end_time,
2708 width,
2709 &closure_data.x_end);
2710
2711 /* Draw last items */
2712 g_hash_table_foreach(process_list->process_hash, draw_closure,
2713 (void*)&closure_data);
2714#if 0
2715 /* Reactivate sort */
2716 gtk_tree_sortable_set_sort_column_id(
2717 GTK_TREE_SORTABLE(control_flow_data->process_list->list_store),
2718 GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
2719 GTK_SORT_ASCENDING);
2720
2721 update_index_to_pixmap(control_flow_data->process_list);
2722 /* Request a full expose : drawing scrambled */
2723 gtk_widget_queue_draw(control_flow_data->drawing->drawing_area);
2724#endif //0
2725 /* Request expose (updates damages zone also) */
2726 drawing_request_expose(events_request, tss, end_time);
2727
2728 return 0;
2729}
2730
2731/* after_statedump_end
2732 *
2733 * @param hook_data ControlFlowData structure of the viewer.
2734 * @param call_data Event context.
2735 *
2736 * This function adds items to be drawn in a queue for each process.
2737 *
2738 */
2739int before_statedump_end(void *hook_data, void *call_data)
2740{
2741 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
2742 EventsRequest *events_request = (EventsRequest*)thf->hook_data;
2743 ControlFlowData *control_flow_data = events_request->viewer_data;
2744
2745 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
2746
2747 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
2748
2749 LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
2750
2751 LttvTracesetState *tss = (LttvTracesetState*)tfc->t_context->ts_context;
2752 ProcessList *process_list = control_flow_data->process_list;
2753
2754 LttEvent *e;
2755 e = ltt_tracefile_get_event(tfc->tf);
2756
2757 LttvFilter *filter = control_flow_data->filter;
2758 if(filter != NULL && filter->head != NULL)
2759 if(!lttv_filter_tree_parse(filter->head,e,tfc->tf,
2760 tfc->t_context->t,tfc,NULL,NULL))
2761 return FALSE;
2762
2763 LttTime evtime = ltt_event_time(e);
2764
2765 ClosureData closure_data;
2766 closure_data.events_request = events_request;
2767 closure_data.tss = tss;
2768 closure_data.end_time = evtime;
2769
2770 TimeWindow time_window =
2771 lttvwindow_get_time_window(control_flow_data->tab);
2772 guint width = control_flow_data->drawing->width;
2773 convert_time_to_pixels(
2774 time_window,
2775 evtime,
2776 width,
2777 &closure_data.x_end);
2778
2779 /* Draw last items */
2780 g_hash_table_foreach(process_list->process_hash, draw_closure,
2781 (void*)&closure_data);
2782#if 0
2783 /* Reactivate sort */
2784 gtk_tree_sortable_set_sort_column_id(
2785 GTK_TREE_SORTABLE(control_flow_data->process_list->list_store),
2786 GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
2787 GTK_SORT_ASCENDING);
2788
2789 update_index_to_pixmap(control_flow_data->process_list);
2790 /* Request a full expose : drawing scrambled */
2791 gtk_widget_queue_draw(control_flow_data->drawing->drawing_area);
2792#endif //0
2793 /* Request expose (updates damages zone also) */
2794 drawing_request_expose(events_request, tss, evtime);
2795
2796 return 0;
2797}
This page took 0.132171 seconds and 4 git commands to generate.