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