continue implementation of resourceview
[lttv.git] / ltt / branches / poly / lttv / modules / gui / resourceview / eventhooks.c
CommitLineData
9e01e6d4 1/* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Mathieu Desnoyers
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
16 * MA 02111-1307, USA.
17 */
18
19
20/*****************************************************************************
21 * Hooks to be called by the main window *
22 *****************************************************************************/
23
24
25/* Event hooks are the drawing hooks called during traceset read. They draw the
26 * icons, text, lines and background color corresponding to the events read.
27 *
28 * Two hooks are used for drawing : before_schedchange and after_schedchange hooks. The
29 * before_schedchange is called before the state update that occurs with an event and
30 * the after_schedchange hook is called after this state update.
31 *
32 * The before_schedchange hooks fulfill the task of drawing the visible objects that
33 * corresponds to the data accumulated by the after_schedchange hook.
34 *
35 * The after_schedchange hook accumulates the data that need to be shown on the screen
36 * (items) into a queue. Then, the next before_schedchange hook will draw what that
37 * queue contains. That's the Right Way (TM) of drawing items on the screen,
38 * because we need to draw the background first (and then add icons, text, ...
39 * over it), but we only know the length of a background region once the state
40 * corresponding to it is over, which happens to be at the next before_schedchange
41 * hook.
42 *
43 * We also have a hook called at the end of a chunk to draw the information left
44 * undrawn in each process queue. We use the current time as end of
45 * line/background.
46 */
47
48#ifdef HAVE_CONFIG_H
49#include <config.h>
50#endif
51
52//#define PANGO_ENABLE_BACKEND
53#include <gtk/gtk.h>
54#include <gdk/gdk.h>
55#include <glib.h>
56#include <assert.h>
57#include <string.h>
58#include <stdio.h>
59
60//#include <pango/pango.h>
61
62#include <ltt/event.h>
63#include <ltt/time.h>
64#include <ltt/type.h>
65#include <ltt/trace.h>
66
67#include <lttv/lttv.h>
68#include <lttv/hook.h>
69#include <lttv/state.h>
70#include <lttvwindow/lttvwindow.h>
71#include <lttvwindow/lttvwindowtraces.h>
72#include <lttvwindow/support.h>
73
74
75#include "eventhooks.h"
76#include "cfv.h"
77#include "processlist.h"
78#include "drawing.h"
79
80
81#define MAX_PATH_LEN 256
82#define STATE_LINE_WIDTH 4
83#define COLLISION_POSITION(height) (((height - STATE_LINE_WIDTH)/2) -3)
84
85extern GSList *g_legend_list;
86
87
88/* Action to do when background computation completed.
89 *
90 * Wait for all the awaited computations to be over.
91 */
92
93static gint background_ready(void *hook_data, void *call_data)
94{
95 ControlFlowData *control_flow_data = (ControlFlowData *)hook_data;
96 LttvTrace *trace = (LttvTrace*)call_data;
97
98 control_flow_data->background_info_waiting--;
99
100 if(control_flow_data->background_info_waiting == 0) {
101 g_message("control flow viewer : background computation data ready.");
102
103 drawing_clear(control_flow_data->drawing);
104 processlist_clear(control_flow_data->process_list);
105 gtk_widget_set_size_request(
106 control_flow_data->drawing->drawing_area,
107 -1, processlist_get_height(control_flow_data->process_list));
108 redraw_notify(control_flow_data, NULL);
109 }
110
111 return 0;
112}
113
114
115/* Request background computation. Verify if it is in progress or ready first.
116 * Only for each trace in the tab's traceset.
117 */
118static void request_background_data(ControlFlowData *control_flow_data)
119{
120 LttvTracesetContext * tsc =
121 lttvwindow_get_traceset_context(control_flow_data->tab);
122 gint num_traces = lttv_traceset_number(tsc->ts);
123 gint i;
124 LttvTrace *trace;
125 LttvTraceState *tstate;
126
127 LttvHooks *background_ready_hook =
128 lttv_hooks_new();
129 lttv_hooks_add(background_ready_hook, background_ready, control_flow_data,
130 LTTV_PRIO_DEFAULT);
131 control_flow_data->background_info_waiting = 0;
132
133 for(i=0;i<num_traces;i++) {
134 trace = lttv_traceset_get(tsc->ts, i);
135 tstate = LTTV_TRACE_STATE(tsc->traces[i]);
136
137 if(lttvwindowtraces_get_ready(g_quark_from_string("state"),trace)==FALSE
138 && !tstate->has_precomputed_states) {
139
140 if(lttvwindowtraces_get_in_progress(g_quark_from_string("state"),
141 trace) == FALSE) {
142 /* We first remove requests that could have been done for the same
143 * information. Happens when two viewers ask for it before servicing
144 * starts.
145 */
146 if(!lttvwindowtraces_background_request_find(trace, "state"))
147 lttvwindowtraces_background_request_queue(
148 main_window_get_widget(control_flow_data->tab), trace, "state");
149 lttvwindowtraces_background_notify_queue(control_flow_data,
150 trace,
151 ltt_time_infinite,
152 NULL,
153 background_ready_hook);
154 control_flow_data->background_info_waiting++;
155 } else { /* in progress */
156
157 lttvwindowtraces_background_notify_current(control_flow_data,
158 trace,
159 ltt_time_infinite,
160 NULL,
161 background_ready_hook);
162 control_flow_data->background_info_waiting++;
163 }
164 } else {
165 /* Data ready. By its nature, this viewer doesn't need to have
166 * its data ready hook called there, because a background
167 * request is always linked with a redraw.
168 */
169 }
170
171 }
172
173 lttv_hooks_destroy(background_ready_hook);
174}
175
176
177
178
179/**
180 * Event Viewer's constructor hook
181 *
182 * This constructor is given as a parameter to the menuitem and toolbar button
183 * registration. It creates the list.
184 * @param tab A pointer to the parent tab.
185 * @return The widget created.
186 */
187GtkWidget *
58a9b31b 188h_resourceview(LttvPlugin *plugin)
9e01e6d4 189{
190 LttvPluginTab *ptab = LTTV_PLUGIN_TAB(plugin);
191 Tab *tab = ptab->tab;
192 g_info("h_guicontrolflow, %p", tab);
58a9b31b 193 ControlFlowData *control_flow_data = resourceview(ptab);
9e01e6d4 194
195 control_flow_data->tab = tab;
196
197 // Unreg done in the GuiControlFlow_Destructor
198 lttvwindow_register_traceset_notify(tab,
199 traceset_notify,
200 control_flow_data);
201
202 lttvwindow_register_time_window_notify(tab,
203 update_time_window_hook,
204 control_flow_data);
205 lttvwindow_register_current_time_notify(tab,
206 update_current_time_hook,
207 control_flow_data);
208 lttvwindow_register_redraw_notify(tab,
209 redraw_notify,
210 control_flow_data);
211 lttvwindow_register_continue_notify(tab,
212 continue_notify,
213 control_flow_data);
214 request_background_data(control_flow_data);
215
216
217 return guicontrolflow_get_widget(control_flow_data) ;
218
219}
220
221void legend_destructor(GtkWindow *legend)
222{
223 g_legend_list = g_slist_remove(g_legend_list, legend);
224}
225
226/* Create a popup legend */
227GtkWidget *
228h_legend(LttvPlugin *plugin)
229{
230 LttvPluginTab *ptab = LTTV_PLUGIN_TAB(plugin);
231 Tab *tab = ptab->tab;
232 g_info("h_legend, %p", tab);
233
234 GtkWindow *legend = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
235
236 g_legend_list = g_slist_append(
237 g_legend_list,
238 legend);
239
240 g_object_set_data_full(
241 G_OBJECT(legend),
242 "legend",
243 legend,
244 (GDestroyNotify)legend_destructor);
245
246 gtk_window_set_title(legend, "Control Flow View Legend");
247
248 GtkWidget *pixmap = create_pixmap(GTK_WIDGET(legend), "lttv-color-list.png");
249
250 // GtkImage *image = GTK_IMAGE(gtk_image_new_from_pixmap(
251 // GDK_PIXMAP(pixmap), NULL));
252
253 gtk_container_add(GTK_CONTAINER(legend), GTK_WIDGET(pixmap));
254
255 gtk_widget_show(GTK_WIDGET(pixmap));
256 gtk_widget_show(GTK_WIDGET(legend));
257
258
259 return NULL; /* This is a popup window */
260}
261
262
263int event_selected_hook(void *hook_data, void *call_data)
264{
265 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
266 guint *event_number = (guint*) call_data;
267
268 g_debug("DEBUG : event selected by main window : %u", *event_number);
269
270 return 0;
271}
272
273/* Function that selects the color of status&exemode line */
274static inline PropertiesLine prepare_s_e_line(LttvProcessState *process)
275{
276 PropertiesLine prop_line;
277 prop_line.line_width = STATE_LINE_WIDTH;
278 prop_line.style = GDK_LINE_SOLID;
279 prop_line.y = MIDDLE;
9e01e6d4 280
281 if(process->state->s == LTTV_STATE_RUN) {
282 if(process->state->t == LTTV_STATE_USER_MODE)
283 prop_line.color = drawing_colors[COL_RUN_USER_MODE];
284 else if(process->state->t == LTTV_STATE_SYSCALL)
285 prop_line.color = drawing_colors[COL_RUN_SYSCALL];
286 else if(process->state->t == LTTV_STATE_TRAP)
287 prop_line.color = drawing_colors[COL_RUN_TRAP];
288 else if(process->state->t == LTTV_STATE_IRQ)
289 prop_line.color = drawing_colors[COL_RUN_IRQ];
290 else if(process->state->t == LTTV_STATE_SOFT_IRQ)
291 prop_line.color = drawing_colors[COL_RUN_SOFT_IRQ];
292 else if(process->state->t == LTTV_STATE_MODE_UNKNOWN)
293 prop_line.color = drawing_colors[COL_MODE_UNKNOWN];
294 else
295 g_assert(FALSE); /* RUNNING MODE UNKNOWN */
296 } else if(process->state->s == LTTV_STATE_WAIT) {
297 /* We don't show if we wait while in user mode, trap, irq or syscall */
298 prop_line.color = drawing_colors[COL_WAIT];
299 } else if(process->state->s == LTTV_STATE_WAIT_CPU) {
300 /* We don't show if we wait for CPU while in user mode, trap, irq
301 * or syscall */
302 prop_line.color = drawing_colors[COL_WAIT_CPU];
303 } else if(process->state->s == LTTV_STATE_ZOMBIE) {
304 prop_line.color = drawing_colors[COL_ZOMBIE];
305 } else if(process->state->s == LTTV_STATE_WAIT_FORK) {
306 prop_line.color = drawing_colors[COL_WAIT_FORK];
307 } else if(process->state->s == LTTV_STATE_EXIT) {
308 prop_line.color = drawing_colors[COL_EXIT];
309 } else if(process->state->s == LTTV_STATE_UNNAMED) {
310 prop_line.color = drawing_colors[COL_UNNAMED];
311 } else {
312 g_critical("unknown state : %s", g_quark_to_string(process->state->s));
313 g_assert(FALSE); /* UNKNOWN STATE */
314 }
315
316 return prop_line;
317
318}
319
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
339int 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
58a9b31b 357 GQuark cpuq;
358
9e01e6d4 359 /* we are in a schedchange, before the state update. We must draw the
360 * items corresponding to the state before it changes : now is the right
361 * time to do it.
362 */
363
364 guint pid_out;
365 guint pid_in;
58a9b31b 366 pid_out = ltt_event_get_long_unsigned(e, thf->f1);
367 pid_in = ltt_event_get_long_unsigned(e, thf->f2);
44ffb95f 368// if(pid_in != 0 && pid_out != 0) {
369// /* not a transition to/from idle */
370// return 0;
371// }
c4e6f4dc 372
9e01e6d4 373 tfc->target_pid = pid_out;
58a9b31b 374// if(!filter || !filter->head ||
375// lttv_filter_tree_parse(filter->head,e,tfc->tf,
376// tfc->t_context->t,tfc,NULL,NULL)) {
9e01e6d4 377 /* For the pid_out */
378 /* First, check if the current process is in the state computation
379 * process list. If it is there, that means we must add it right now and
380 * draw items from the beginning of the read for it. If it is not
381 * present, it's a new process and it was not present : it will
382 * be added after the state update. */
383 guint cpu = tfs->cpu;
44ffb95f 384 {
385 gchar *cpustr;
386 cpustr = g_strdup_printf("CPU%u", cpu);
387 cpuq = g_quark_from_string(cpustr);
388 g_free(cpustr);
389 }
58a9b31b 390
9e01e6d4 391 guint trace_num = ts->parent.index;
58a9b31b 392// LttvProcessState *process = ts->running_process[cpu];
9e01e6d4 393 /* unknown state, bad current pid */
58a9b31b 394// if(process->pid != pid_out)
395// process = lttv_state_find_process(ts,
396// tfs->cpu, pid_out);
9e01e6d4 397
58a9b31b 398// if(process != NULL) {
9e01e6d4 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;
58a9b31b 404 HashedResourceData *hashed_process_data = NULL;
9e01e6d4 405 ProcessList *process_list = control_flow_data->process_list;
58a9b31b 406// LttTime birth = process->creation_time;
9e01e6d4 407
58a9b31b 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);
9e01e6d4 414 if(hashed_process_data == NULL)
415 {
58a9b31b 416// g_assert(pid_out == 0 || pid_out != process->ppid);
9e01e6d4 417 /* Process not present */
58a9b31b 418 ResourceInfo *process_info;
9e01e6d4 419 Drawing_t *drawing = control_flow_data->drawing;
c4e6f4dc 420 resourcelist_add(process_list,
9e01e6d4 421 drawing,
58a9b31b 422 trace_num,
423 cpuq, //process->name,
44ffb95f 424 0, //cpu
425 cpu,
9e01e6d4 426 &pl_height,
427 &process_info,
428 &hashed_process_data);
429 gtk_widget_set_size_request(drawing->drawing_area,
430 -1,
431 pl_height);
432 gtk_widget_queue_draw(drawing->drawing_area);
433
434 }
435
436 /* Now, the process is in the state hash and our own process hash.
437 * We definitely can draw the items related to the ending state.
438 */
439
440 if(ltt_time_compare(hashed_process_data->next_good_time,
441 evtime) > 0)
442 {
443 if(hashed_process_data->x.middle_marked == FALSE) {
444
445 TimeWindow time_window =
446 lttvwindow_get_time_window(control_flow_data->tab);
447#ifdef EXTRA_CHECK
448 if(ltt_time_compare(evtime, time_window.start_time) == -1
449 || ltt_time_compare(evtime, time_window.end_time) == 1)
450 return;
451#endif //EXTRA_CHECK
452 Drawing_t *drawing = control_flow_data->drawing;
453 guint width = drawing->width;
454 guint x;
455 convert_time_to_pixels(
456 time_window,
457 evtime,
458 width,
459 &x);
460
461 /* Draw collision indicator */
462 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
463 gdk_draw_point(hashed_process_data->pixmap,
464 drawing->gc,
465 x,
466 COLLISION_POSITION(hashed_process_data->height));
467 hashed_process_data->x.middle_marked = TRUE;
468 }
469 } else {
470 TimeWindow time_window =
471 lttvwindow_get_time_window(control_flow_data->tab);
472#ifdef EXTRA_CHECK
473 if(ltt_time_compare(evtime, time_window.start_time) == -1
474 || ltt_time_compare(evtime, time_window.end_time) == 1)
475 return;
476#endif //EXTRA_CHECK
477 Drawing_t *drawing = control_flow_data->drawing;
478 guint width = drawing->width;
479 guint x;
480 convert_time_to_pixels(
481 time_window,
482 evtime,
483 width,
484 &x);
485
486
487 /* Jump over draw if we are at the same x position */
488 if(x == hashed_process_data->x.middle &&
489 hashed_process_data->x.middle_used)
490 {
491 if(hashed_process_data->x.middle_marked == FALSE) {
492 /* Draw collision indicator */
493 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
494 gdk_draw_point(hashed_process_data->pixmap,
495 drawing->gc,
496 x,
497 COLLISION_POSITION(hashed_process_data->height));
498 hashed_process_data->x.middle_marked = TRUE;
499 }
500 /* jump */
501 } else {
502 DrawContext draw_context;
503
504 /* Now create the drawing context that will be used to draw
505 * items related to the last state. */
506 draw_context.drawable = hashed_process_data->pixmap;
507 draw_context.gc = drawing->gc;
508 draw_context.pango_layout = drawing->pango_layout;
509 draw_context.drawinfo.start.x = hashed_process_data->x.middle;
510 draw_context.drawinfo.end.x = x;
511
512 draw_context.drawinfo.y.over = 1;
513 draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
514 draw_context.drawinfo.y.under = hashed_process_data->height;
515
516 draw_context.drawinfo.start.offset.over = 0;
517 draw_context.drawinfo.start.offset.middle = 0;
518 draw_context.drawinfo.start.offset.under = 0;
519 draw_context.drawinfo.end.offset.over = 0;
520 draw_context.drawinfo.end.offset.middle = 0;
521 draw_context.drawinfo.end.offset.under = 0;
522
523 {
524 /* Draw the line */
58a9b31b 525 //PropertiesLine prop_line = prepare_s_e_line(process);
526 PropertiesLine prop_line;
527 prop_line.line_width = STATE_LINE_WIDTH;
528 prop_line.style = GDK_LINE_SOLID;
529 prop_line.y = MIDDLE;
44ffb95f 530 //if(pid_out == 0) {
531 if(tfs->cpu_state->present_state == LTTV_CPU_IDLE) {
532 prop_line.color = drawing_colors_cpu[COL_CPU_IDLE];
533 }
534 else {
535 prop_line.color = drawing_colors_cpu[COL_CPU_BUSY];
536 }
9e01e6d4 537
9e01e6d4 538 draw_line((void*)&prop_line, (void*)&draw_context);
9e01e6d4 539
58a9b31b 540 }
541 /* become the last x position */
542 hashed_process_data->x.middle = x;
543 hashed_process_data->x.middle_used = TRUE;
544 hashed_process_data->x.middle_marked = FALSE;
9e01e6d4 545
58a9b31b 546 /* Calculate the next good time */
547 convert_pixels_to_time(width, x+1, time_window,
548 &hashed_process_data->next_good_time);
549 }
550 }
551// }
552// }
553
554// tfc->target_pid = pid_in;
555// if(!filter || !filter->head ||
556// lttv_filter_tree_parse(filter->head,e,tfc->tf,
557// tfc->t_context->t,tfc,NULL,NULL)) {
558// /* For the pid_in */
559// /* First, check if the current process is in the state computation
560// * process list. If it is there, that means we must add it right now and
561// * draw items from the beginning of the read for it. If it is not
562// * present, it's a new process and it was not present : it will
563// * be added after the state update. */
564// LttvProcessState *process;
565// process = lttv_state_find_process(ts,
566// tfs->cpu, pid_in);
567// guint trace_num = ts->parent.index;
568//
569// if(process != NULL) {
570// /* Well, the process existed : we must get it in the process hash
571// * or add it, and draw its items.
572// */
573// /* Add process to process list (if not present) */
574// guint pl_height = 0;
575// HashedResourceData *hashed_process_data = NULL;
576// ProcessList *process_list = control_flow_data->process_list;
577// LttTime birth = process->creation_time;
578//
579// hashed_process_data = processlist_get_process_data(process_list, cpuq);
580//// hashed_process_data = processlist_get_process_data(process_list,
581//// pid_in,
582//// tfs->cpu,
583//// &birth,
584//// trace_num);
585// if(hashed_process_data == NULL)
586// {
587// g_assert(pid_in == 0 || pid_in != process->ppid);
588// /* Process not present */
589// ResourceInfo *process_info;
590// Drawing_t *drawing = control_flow_data->drawing;
591// resourcelist_add(process_list,
592// drawing,
593//// pid_in,
594//// process->tgid,
595//// tfs->cpu,
596//// process->ppid,
597//// &birth,
598//// trace_num,
599// process->name,
600//// process->brand,
601// &pl_height,
602// &process_info,
603// &hashed_process_data);
604// gtk_widget_set_size_request(drawing->drawing_area,
605// -1,
606// pl_height);
607// gtk_widget_queue_draw(drawing->drawing_area);
608//
609// }
610// //We could set the current process and hash here, but will be done
611// //by after schedchange hook
612//
613// /* Now, the process is in the state hash and our own process hash.
614// * We definitely can draw the items related to the ending state.
615// */
616//
617// if(ltt_time_compare(hashed_process_data->next_good_time,
618// evtime) > 0)
619// {
620// if(hashed_process_data->x.middle_marked == FALSE) {
621//
622// TimeWindow time_window =
623// lttvwindow_get_time_window(control_flow_data->tab);
624//#ifdef EXTRA_CHECK
625// if(ltt_time_compare(evtime, time_window.start_time) == -1
626// || ltt_time_compare(evtime, time_window.end_time) == 1)
627// return;
628//#endif //EXTRA_CHECK
629// Drawing_t *drawing = control_flow_data->drawing;
630// guint width = drawing->width;
631// guint x;
632// convert_time_to_pixels(
633// time_window,
634// evtime,
635// width,
636// &x);
637//
638// /* Draw collision indicator */
639// gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
640// gdk_draw_point(hashed_process_data->pixmap,
641// drawing->gc,
642// x,
643// COLLISION_POSITION(hashed_process_data->height));
644// hashed_process_data->x.middle_marked = TRUE;
645// }
646// } else {
647// TimeWindow time_window =
648// lttvwindow_get_time_window(control_flow_data->tab);
649//#ifdef EXTRA_CHECK
650// if(ltt_time_compare(evtime, time_window.start_time) == -1
651// || ltt_time_compare(evtime, time_window.end_time) == 1)
652// return;
653//#endif //EXTRA_CHECK
654// Drawing_t *drawing = control_flow_data->drawing;
655// guint width = drawing->width;
656// guint x;
657//
658// convert_time_to_pixels(
659// time_window,
660// evtime,
661// width,
662// &x);
663//
664//
665// /* Jump over draw if we are at the same x position */
666// if(x == hashed_process_data->x.middle &&
667// hashed_process_data->x.middle_used)
668// {
669// if(hashed_process_data->x.middle_marked == FALSE) {
670// /* Draw collision indicator */
671// gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
672// gdk_draw_point(hashed_process_data->pixmap,
673// drawing->gc,
674// x,
675// COLLISION_POSITION(hashed_process_data->height));
676// hashed_process_data->x.middle_marked = TRUE;
677// }
678// /* jump */
679// } else {
680// DrawContext draw_context;
681//
682// /* Now create the drawing context that will be used to draw
683// * items related to the last state. */
684// draw_context.drawable = hashed_process_data->pixmap;
685// draw_context.gc = drawing->gc;
686// draw_context.pango_layout = drawing->pango_layout;
687// draw_context.drawinfo.start.x = hashed_process_data->x.middle;
688// draw_context.drawinfo.end.x = x;
689//
690// draw_context.drawinfo.y.over = 1;
691// draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
692// draw_context.drawinfo.y.under = hashed_process_data->height;
693//
694// draw_context.drawinfo.start.offset.over = 0;
695// draw_context.drawinfo.start.offset.middle = 0;
696// draw_context.drawinfo.start.offset.under = 0;
697// draw_context.drawinfo.end.offset.over = 0;
698// draw_context.drawinfo.end.offset.middle = 0;
699// draw_context.drawinfo.end.offset.under = 0;
700//
701// {
702// /* Draw the line */
703// PropertiesLine prop_line = prepare_s_e_line(process);
704// draw_line((void*)&prop_line, (void*)&draw_context);
705// }
706//
707//
708// /* become the last x position */
709// hashed_process_data->x.middle = x;
710// hashed_process_data->x.middle_used = TRUE;
711// hashed_process_data->x.middle_marked = FALSE;
712//
713// /* Calculate the next good time */
714// convert_pixels_to_time(width, x+1, time_window,
715// &hashed_process_data->next_good_time);
716// }
717// }
718// } else
719// g_warning("Cannot find pin_in in schedchange %u", pid_in);
720// }
721// tfc->target_pid = target_pid_saved;
722 return 0;
9e01e6d4 723
9e01e6d4 724
9e01e6d4 725
9e01e6d4 726
58a9b31b 727 /* Text dump */
728#ifdef DONTSHOW
729 GString *string = g_string_new("");;
730 gboolean field_names = TRUE, state = TRUE;
9e01e6d4 731
58a9b31b 732 lttv_event_to_string(e, tfc->tf, string, TRUE, field_names, tfs);
733 g_string_append_printf(string,"\n");
9e01e6d4 734
58a9b31b 735 if(state) {
736 g_string_append_printf(string, " %s",
737 g_quark_to_string(tfs->process->state->s));
9e01e6d4 738 }
739
58a9b31b 740 g_info("%s",string->str);
9e01e6d4 741
58a9b31b 742 g_string_free(string, TRUE);
743
744 /* End of text dump */
745#endif //DONTSHOW
9e01e6d4 746
747}
748
58a9b31b 749/* after_schedchange_hook
750 *
751 * The draw after hook is called by the reading API to have a
752 * particular event drawn on the screen.
753 * @param hook_data ControlFlowData structure of the viewer.
754 * @param call_data Event context.
755 *
756 * This function adds items to be drawn in a queue for each process.
757 *
758 */
759int after_schedchange_hook(void *hook_data, void *call_data)
9e01e6d4 760{
44ffb95f 761 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
762 EventsRequest *events_request = (EventsRequest*)thf->hook_data;
763 ControlFlowData *control_flow_data = events_request->viewer_data;
764
765 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
766
767 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
768
769 LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
770
771 LttEvent *e;
772 e = ltt_tracefile_get_event(tfc->tf);
773
774 LttvFilter *filter = control_flow_data->filter;
775 if(filter != NULL && filter->head != NULL)
776 if(!lttv_filter_tree_parse(filter->head,e,tfc->tf,
777 tfc->t_context->t,tfc,NULL,NULL))
778 return FALSE;
779
780 LttTime evtime = ltt_event_time(e);
781
782 GQuark cpuq;
783
784 /* Add process to process list (if not present) */
785 LttvProcessState *process_in;
786 LttTime birth;
787 guint pl_height = 0;
788 HashedResourceData *hashed_process_data_in = NULL;
789
790 ProcessList *process_list = control_flow_data->process_list;
791
792 guint pid_in;
793 {
794 guint pid_out;
795 pid_out = ltt_event_get_long_unsigned(e, thf->f1);
796 pid_in = ltt_event_get_long_unsigned(e, thf->f2);
797 }
798
799
800 /* Find process pid_in in the list... */
801 //process_in = lttv_state_find_process(ts, ANY_CPU, pid_in);
802 //process_in = tfs->process;
803 guint cpu = tfs->cpu;
804 {
805 gchar *cpustr;
806 cpustr = g_strdup_printf("CPU%u", cpu);
807 cpuq = g_quark_from_string(cpustr);
808 g_free(cpustr);
809 }
810 guint trace_num = ts->parent.index;
811 process_in = ts->running_process[cpu];
812 /* It should exist, because we are after the state update. */
813#ifdef EXTRA_CHECK
814 g_assert(process_in != NULL);
815#endif //EXTRA_CHECK
816 birth = process_in->creation_time;
817
818 hashed_process_data_in = processlist_get_process_data(process_list, cpuq, trace_num);
819// hashed_process_data_in = processlist_get_process_data(process_list,
820// pid_in,
821// process_in->cpu,
822// &birth,
823// trace_num);
824 if(hashed_process_data_in == NULL)
825 {
826 g_assert(pid_in == 0 || pid_in != process_in->ppid);
827 ResourceInfo *process_info;
828 Drawing_t *drawing = control_flow_data->drawing;
829 /* Process not present */
830 resourcelist_add(process_list,
831 drawing,
832 trace_num,
833 cpuq,
834 0,
835 cpu,
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 }
58a9b31b 875 return 0;
876}
9e01e6d4 877
58a9b31b 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 */
9e01e6d4 894
58a9b31b 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//}
9e01e6d4 1086
58a9b31b 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 */
9e01e6d4 1097
58a9b31b 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//}
9e01e6d4 1282
9e01e6d4 1283
58a9b31b 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 */
9e01e6d4 1294
58a9b31b 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//}
9e01e6d4 1483
58a9b31b 1484/* after_process_fork_hook
9e01e6d4 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 */
58a9b31b 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//}
9e01e6d4 1616
9e01e6d4 1617
9e01e6d4 1618
58a9b31b 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//}
9e01e6d4 1738
9e01e6d4 1739
58a9b31b 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//}
9e01e6d4 1821
58a9b31b 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//}
9e01e6d4 1903
9e01e6d4 1904
58a9b31b 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//}
9e01e6d4 2018
2019
2020gint 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
2239gint 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
2263gint 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
2306gint 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
2326gint 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
2410typedef struct _ClosureData {
2411 EventsRequest *events_request;
2412 LttvTracesetState *tss;
2413 LttTime end_time;
2414 guint x_end;
2415} ClosureData;
2416
58a9b31b 2417/* Draw line until end of the screen */
9e01e6d4 2418
2419void draw_closure(gpointer key, gpointer value, gpointer user_data)
2420{
44ffb95f 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
58a9b31b 2467// LttvProcessState *process;
2468// process = lttv_state_find_process(ts, process_info->cpu,
2469// process_info->pid);
44ffb95f 2470
58a9b31b 2471// if(unlikely(process != NULL)) {
44ffb95f 2472
58a9b31b 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;
44ffb95f 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 PropertiesLine prop_line;
2563 prop_line.line_width = STATE_LINE_WIDTH;
2564 prop_line.style = GDK_LINE_SOLID;
2565 prop_line.y = MIDDLE;
2566/* if(pid_out == 0) {
2567 prop_line.color = drawing_colors_cpu[COL_IDLE];
2568 }
2569 else {
2570 prop_line.color = drawing_colors_cpu[COL_BUSY];
2571 }
2572*/
2573 //prop_line.color = drawing_colors_cpu[COL_CPU_UNKNOWN];
2574 if(ts->cpu_states[process_info->id].present_state == LTTV_CPU_IDLE) {
2575 prop_line.color = drawing_colors_cpu[COL_CPU_IDLE];
2576 }
2577 else {
2578 prop_line.color = drawing_colors_cpu[COL_CPU_BUSY];
2579 }
2580
2581 draw_line((void*)&prop_line, (void*)&draw_context);
2582 }
2583
2584 /* become the last x position */
2585 if(likely(x != hashed_process_data->x.middle)) {
2586 hashed_process_data->x.middle = x;
2587 /* but don't use the pixel */
2588 hashed_process_data->x.middle_used = FALSE;
2589
2590 /* Calculate the next good time */
2591 convert_pixels_to_time(width, x+1, time_window,
2592 &hashed_process_data->next_good_time);
2593 }
2594 }
2595 }
58a9b31b 2596// }
44ffb95f 2597 }
9e01e6d4 2598 return;
2599}
2600
2601int before_chunk(void *hook_data, void *call_data)
2602{
2603 EventsRequest *events_request = (EventsRequest*)hook_data;
2604 LttvTracesetState *tss = (LttvTracesetState*)call_data;
2605 ControlFlowData *cfd = (ControlFlowData*)events_request->viewer_data;
2606#if 0
2607 /* Desactivate sort */
2608 gtk_tree_sortable_set_sort_column_id(
2609 GTK_TREE_SORTABLE(cfd->process_list->list_store),
2610 TRACE_COLUMN,
2611 GTK_SORT_ASCENDING);
2612#endif //0
2613 drawing_chunk_begin(events_request, tss);
2614
2615 return 0;
2616}
2617
2618int before_request(void *hook_data, void *call_data)
2619{
2620 EventsRequest *events_request = (EventsRequest*)hook_data;
2621 LttvTracesetState *tss = (LttvTracesetState*)call_data;
2622
2623 drawing_data_request_begin(events_request, tss);
2624
2625 return 0;
2626}
2627
2628
2629/*
2630 * after request is necessary in addition of after chunk in order to draw
2631 * lines until the end of the screen. after chunk just draws lines until
2632 * the last event.
2633 *
2634 * for each process
2635 * draw closing line
2636 * expose
2637 */
58a9b31b 2638// TODO pmf: reenable this
9e01e6d4 2639int after_request(void *hook_data, void *call_data)
2640{
58a9b31b 2641// EventsRequest *events_request = (EventsRequest*)hook_data;
2642// ControlFlowData *control_flow_data = events_request->viewer_data;
2643// LttvTracesetState *tss = (LttvTracesetState*)call_data;
2644//
2645// ProcessList *process_list = control_flow_data->process_list;
2646// LttTime end_time = events_request->end_time;
2647//
2648// ClosureData closure_data;
2649// closure_data.events_request = (EventsRequest*)hook_data;
2650// closure_data.tss = tss;
2651// closure_data.end_time = end_time;
2652//
2653// TimeWindow time_window =
2654// lttvwindow_get_time_window(control_flow_data->tab);
2655// guint width = control_flow_data->drawing->width;
2656// convert_time_to_pixels(
2657// time_window,
2658// end_time,
2659// width,
2660// &closure_data.x_end);
2661//
2662//
2663// /* Draw last items */
2664// g_hash_table_foreach(process_list->process_hash, draw_closure,
2665// (void*)&closure_data);
2666//
2667//
2668// /* Request expose */
2669// drawing_request_expose(events_request, tss, end_time);
9e01e6d4 2670 return 0;
2671}
2672
2673/*
2674 * for each process
2675 * draw closing line
2676 * expose
2677 */
2678int after_chunk(void *hook_data, void *call_data)
2679{
2680 EventsRequest *events_request = (EventsRequest*)hook_data;
2681 ControlFlowData *control_flow_data = events_request->viewer_data;
2682 LttvTracesetState *tss = (LttvTracesetState*)call_data;
2683 LttvTracesetContext *tsc = (LttvTracesetContext*)call_data;
2684 LttvTracefileContext *tfc = lttv_traceset_context_get_current_tfc(tsc);
2685 LttTime end_time;
2686
2687 ProcessList *process_list = control_flow_data->process_list;
2688 guint i;
2689 LttvTraceset *traceset = tsc->ts;
2690 guint nb_trace = lttv_traceset_number(traceset);
2691
2692 /* Only execute when called for the first trace's events request */
2693 if(!process_list->current_hash_data) return;
2694
2695 for(i = 0 ; i < nb_trace ; i++) {
2696 g_free(process_list->current_hash_data[i]);
2697 }
2698 g_free(process_list->current_hash_data);
2699 process_list->current_hash_data = NULL;
2700
2701 if(tfc != NULL)
2702 end_time = LTT_TIME_MIN(tfc->timestamp, events_request->end_time);
2703 else /* end of traceset, or position now out of request : end */
2704 end_time = events_request->end_time;
2705
2706 ClosureData closure_data;
2707 closure_data.events_request = (EventsRequest*)hook_data;
2708 closure_data.tss = tss;
2709 closure_data.end_time = end_time;
2710
2711 TimeWindow time_window =
2712 lttvwindow_get_time_window(control_flow_data->tab);
2713 guint width = control_flow_data->drawing->width;
2714 convert_time_to_pixels(
2715 time_window,
2716 end_time,
2717 width,
2718 &closure_data.x_end);
2719
2720 /* Draw last items */
2721 g_hash_table_foreach(process_list->process_hash, draw_closure,
2722 (void*)&closure_data);
2723#if 0
2724 /* Reactivate sort */
2725 gtk_tree_sortable_set_sort_column_id(
2726 GTK_TREE_SORTABLE(control_flow_data->process_list->list_store),
2727 GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
2728 GTK_SORT_ASCENDING);
2729
2730 update_index_to_pixmap(control_flow_data->process_list);
2731 /* Request a full expose : drawing scrambled */
2732 gtk_widget_queue_draw(control_flow_data->drawing->drawing_area);
2733#endif //0
2734 /* Request expose (updates damages zone also) */
2735 drawing_request_expose(events_request, tss, end_time);
2736
2737 return 0;
2738}
2739
2740/* after_statedump_end
2741 *
2742 * @param hook_data ControlFlowData structure of the viewer.
2743 * @param call_data Event context.
2744 *
2745 * This function adds items to be drawn in a queue for each process.
2746 *
2747 */
2748int before_statedump_end(void *hook_data, void *call_data)
2749{
2750 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
2751 EventsRequest *events_request = (EventsRequest*)thf->hook_data;
2752 ControlFlowData *control_flow_data = events_request->viewer_data;
2753
2754 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
2755
2756 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
2757
2758 LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
2759
2760 LttvTracesetState *tss = (LttvTracesetState*)tfc->t_context->ts_context;
2761 ProcessList *process_list = control_flow_data->process_list;
2762
2763 LttEvent *e;
2764 e = ltt_tracefile_get_event(tfc->tf);
2765
2766 LttvFilter *filter = control_flow_data->filter;
2767 if(filter != NULL && filter->head != NULL)
2768 if(!lttv_filter_tree_parse(filter->head,e,tfc->tf,
2769 tfc->t_context->t,tfc,NULL,NULL))
2770 return FALSE;
2771
2772 LttTime evtime = ltt_event_time(e);
2773
2774 ClosureData closure_data;
2775 closure_data.events_request = events_request;
2776 closure_data.tss = tss;
2777 closure_data.end_time = evtime;
2778
2779 TimeWindow time_window =
2780 lttvwindow_get_time_window(control_flow_data->tab);
2781 guint width = control_flow_data->drawing->width;
2782 convert_time_to_pixels(
2783 time_window,
2784 evtime,
2785 width,
2786 &closure_data.x_end);
2787
2788 /* Draw last items */
2789 g_hash_table_foreach(process_list->process_hash, draw_closure,
2790 (void*)&closure_data);
2791#if 0
2792 /* Reactivate sort */
2793 gtk_tree_sortable_set_sort_column_id(
2794 GTK_TREE_SORTABLE(control_flow_data->process_list->list_store),
2795 GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
2796 GTK_SORT_ASCENDING);
2797
2798 update_index_to_pixmap(control_flow_data->process_list);
2799 /* Request a full expose : drawing scrambled */
2800 gtk_widget_queue_draw(control_flow_data->drawing->drawing_area);
2801#endif //0
2802 /* Request expose (updates damages zone also) */
2803 drawing_request_expose(events_request, tss, evtime);
2804
2805 return 0;
2806}
This page took 0.13877 seconds and 4 git commands to generate.