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