add process names
[lttv.git] / ltt / branches / poly / lttv / modules / gui / controlflow / eventhooks.c
CommitLineData
ce0214a6 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
f0d936c0 20/*****************************************************************************
21 * Hooks to be called by the main window *
22 *****************************************************************************/
23
f0d936c0 24
b9a010a2 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 *
e92eabaf 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.
b9a010a2 31 *
e92eabaf 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.
b9a010a2 34 *
e92eabaf 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
b9a010a2 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
e92eabaf 40 * corresponding to it is over, which happens to be at the next before_schedchange
b9a010a2 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
4e4d11b3 48#ifdef HAVE_CONFIG_H
49#include <config.h>
50#endif
b9a010a2 51
cf6cb7e0 52//#define PANGO_ENABLE_BACKEND
558aa013 53#include <gtk/gtk.h>
54#include <gdk/gdk.h>
5f16133f 55#include <glib.h>
80a52ff8 56#include <assert.h>
50439712 57#include <string.h>
319e9d81 58#include <stdio.h>
5f16133f 59
cf6cb7e0 60//#include <pango/pango.h>
61
80a52ff8 62#include <ltt/event.h>
4ba42155 63#include <ltt/time.h>
50439712 64#include <ltt/type.h>
2c82c4dc 65#include <ltt/trace.h>
80a52ff8 66
2a2fa4f0 67#include <lttv/lttv.h>
558aa013 68#include <lttv/hook.h>
80a52ff8 69#include <lttv/state.h>
2d262115 70#include <lttvwindow/lttvwindow.h>
6395d57c 71#include <lttvwindow/lttvwindowtraces.h>
80a52ff8 72
f0d936c0 73
a117e3f7 74#include "eventhooks.h"
75#include "cfv.h"
76#include "processlist.h"
77#include "drawing.h"
5f16133f 78
80a52ff8 79
1a31868c 80#define MAX_PATH_LEN 256
81
b9a010a2 82#if 0
83typedef struct _ProcessAddClosure {
84 ControlFlowData *cfd;
85 guint trace_num;
86} ProcessAddClosure;
87
88static void process_add(gpointer key,
89 gpointer value,
90 gpointer user_data)
91{
92 LttvProcessState *process = (LttvProcessState*)value;
93 ProcessAddClosure *closure = (ProcessAddClosure*)user_data;
94 ControlFlowData *control_flow_data = closure->cfd;
95 guint trace_num = closure->trace_num;
96
97 /* Add process to process list (if not present) */
98 guint pid;
99 LttTime birth;
100 guint y = 0, height = 0, pl_height = 0;
101
5c230fc4 102 ProcessList *process_list = control_flow_data->process_list;
b9a010a2 103
104 pid = process->pid;
105 birth = process->creation_time;
106 const gchar *name = g_quark_to_string(process->name);
107 HashedProcessData *hashed_process_data = NULL;
108
109 if(processlist_get_process_pixels(process_list,
110 pid,
111 &birth,
112 trace_num,
113 &y,
114 &height,
115 &hashed_process_data) == 1)
116 {
117 /* Process not present */
118 processlist_add(process_list,
119 pid,
120 &birth,
121 trace_num,
122 name,
123 &pl_height,
124 &hashed_process_data);
125 processlist_get_process_pixels(process_list,
126 pid,
127 &birth,
128 trace_num,
129 &y,
130 &height,
131 &hashed_process_data);
132 drawing_insert_square( control_flow_data->drawing, y, height);
133 }
134}
135#endif //0
136
137
6395d57c 138/* Action to do when background computation completed.
139 *
e800cf84 140 * Wait for all the awaited computations to be over.
6395d57c 141 */
142
143gint background_ready(void *hook_data, void *call_data)
144{
145 ControlFlowData *control_flow_data = (ControlFlowData *)hook_data;
146 LttvTrace *trace = (LttvTrace*)call_data;
147
e800cf84 148 control_flow_data->background_info_waiting--;
149
150 if(control_flow_data->background_info_waiting == 0) {
151 g_debug("control flow viewer : background computation data ready.");
6395d57c 152
e800cf84 153 drawing_clear(control_flow_data->drawing);
154 processlist_clear(control_flow_data->process_list);
07390ec1 155 gtk_widget_set_size_request(
156 control_flow_data->drawing->drawing_area,
157 -1, processlist_get_height(control_flow_data->process_list));
e800cf84 158 redraw_notify(control_flow_data, NULL);
b9a010a2 159 }
6395d57c 160
161 return 0;
162}
163
164
165/* Request background computation. Verify if it is in progress or ready first.
e800cf84 166 * Only for each trace in the tab's traceset.
6395d57c 167 */
168void request_background_data(ControlFlowData *control_flow_data)
169{
e800cf84 170 LttvTracesetContext * tsc =
171 lttvwindow_get_traceset_context(control_flow_data->tab);
172 gint num_traces = lttv_traceset_number(tsc->ts);
6395d57c 173 gint i;
174 LttvTrace *trace;
175
176 LttvHooks *background_ready_hook =
177 lttv_hooks_new();
178 lttv_hooks_add(background_ready_hook, background_ready, control_flow_data,
179 LTTV_PRIO_DEFAULT);
e800cf84 180 control_flow_data->background_info_waiting = 0;
6395d57c 181
182 for(i=0;i<num_traces;i++) {
e800cf84 183 trace = lttv_traceset_get(tsc->ts, i);
6395d57c 184
185 if(lttvwindowtraces_get_ready(g_quark_from_string("state"),trace)==FALSE) {
186
187 if(lttvwindowtraces_get_in_progress(g_quark_from_string("state"),
188 trace) == FALSE) {
189 /* We first remove requests that could have been done for the same
190 * information. Happens when two viewers ask for it before servicing
191 * starts.
192 */
193 lttvwindowtraces_background_request_remove(trace, "state");
194 lttvwindowtraces_background_request_queue(trace,
195 "state");
196 lttvwindowtraces_background_notify_queue(control_flow_data,
197 trace,
198 ltt_time_infinite,
199 NULL,
200 background_ready_hook);
e800cf84 201 control_flow_data->background_info_waiting++;
6395d57c 202 } else { /* in progress */
203
204 lttvwindowtraces_background_notify_current(control_flow_data,
205 trace,
206 ltt_time_infinite,
207 NULL,
208 background_ready_hook);
e800cf84 209 control_flow_data->background_info_waiting++;
6395d57c 210 }
4368b993 211 } else {
212 /* Data ready. Be its nature, this viewer doesn't need to have
213 * its data ready hook called htere, because a background
214 * request is always linked with a redraw.
215 */
6395d57c 216 }
4368b993 217
6395d57c 218 }
219
220 lttv_hooks_destroy(background_ready_hook);
221}
222
223
224
225
f0d936c0 226/**
227 * Event Viewer's constructor hook
228 *
229 * This constructor is given as a parameter to the menuitem and toolbar button
230 * registration. It creates the list.
ca0f8a8e 231 * @param tab A pointer to the parent tab.
f0d936c0 232 * @return The widget created.
233 */
234GtkWidget *
d47b33d2 235h_guicontrolflow(Tab *tab)
f0d936c0 236{
d47b33d2 237 g_info("h_guicontrolflow, %p", tab);
68997a22 238 ControlFlowData *control_flow_data = guicontrolflow() ;
a56a1ba4 239
ca0f8a8e 240 control_flow_data->tab = tab;
a56a1ba4 241
a56a1ba4 242 // Unreg done in the GuiControlFlow_Destructor
6395d57c 243 lttvwindow_register_traceset_notify(tab,
244 traceset_notify,
245 control_flow_data);
246
ca0f8a8e 247 lttvwindow_register_time_window_notify(tab,
224446ce 248 update_time_window_hook,
249 control_flow_data);
ca0f8a8e 250 lttvwindow_register_current_time_notify(tab,
224446ce 251 update_current_time_hook,
252 control_flow_data);
ca0f8a8e 253 lttvwindow_register_redraw_notify(tab,
254 redraw_notify,
255 control_flow_data);
256 lttvwindow_register_continue_notify(tab,
257 continue_notify,
258 control_flow_data);
667ca2a0 259 request_background_data(control_flow_data);
6395d57c 260
ca0f8a8e 261
68997a22 262 return guicontrolflow_get_widget(control_flow_data) ;
a56a1ba4 263
f0d936c0 264}
265
3cff8cc1 266int event_selected_hook(void *hook_data, void *call_data)
f0d936c0 267{
68997a22 268 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
14963be0 269 guint *event_number = (guint*) call_data;
f0d936c0 270
2a2fa4f0 271 g_debug("DEBUG : event selected by main window : %u", *event_number);
a56a1ba4 272
2eef04b5 273 return 0;
f0d936c0 274}
275
9a1ec01b 276/* Function that selects the color of status&exemode line */
6550d711 277static inline PropertiesLine prepare_s_e_line(LttvProcessState *process)
9a1ec01b 278{
279 PropertiesLine prop_line;
280 prop_line.line_width = 2;
281 prop_line.style = GDK_LINE_SOLID;
282 prop_line.y = MIDDLE;
283 //GdkColormap *colormap = gdk_colormap_get_system();
284
9a1ec01b 285 if(process->state->s == LTTV_STATE_RUN) {
286 if(process->state->t == LTTV_STATE_USER_MODE)
287 prop_line.color = drawing_colors[COL_RUN_USER_MODE];
288 else if(process->state->t == LTTV_STATE_SYSCALL)
289 prop_line.color = drawing_colors[COL_RUN_SYSCALL];
290 else if(process->state->t == LTTV_STATE_TRAP)
291 prop_line.color = drawing_colors[COL_RUN_TRAP];
292 else if(process->state->t == LTTV_STATE_IRQ)
293 prop_line.color = drawing_colors[COL_RUN_IRQ];
294 else if(process->state->t == LTTV_STATE_MODE_UNKNOWN)
295 prop_line.color = drawing_colors[COL_MODE_UNKNOWN];
296 else
297 g_assert(FALSE); /* RUNNING MODE UNKNOWN */
298 } else if(process->state->s == LTTV_STATE_WAIT) {
299 /* We don't show if we wait while in user mode, trap, irq or syscall */
300 prop_line.color = drawing_colors[COL_WAIT];
301 } else if(process->state->s == LTTV_STATE_WAIT_CPU) {
302 /* We don't show if we wait for CPU while in user mode, trap, irq
303 * or syscall */
304 prop_line.color = drawing_colors[COL_WAIT_CPU];
305 } else if(process->state->s == LTTV_STATE_ZOMBIE) {
306 prop_line.color = drawing_colors[COL_ZOMBIE];
307 } else if(process->state->s == LTTV_STATE_WAIT_FORK) {
308 prop_line.color = drawing_colors[COL_WAIT_FORK];
309 } else if(process->state->s == LTTV_STATE_EXIT) {
310 prop_line.color = drawing_colors[COL_EXIT];
311 } else if(process->state->s == LTTV_STATE_UNNAMED) {
312 prop_line.color = drawing_colors[COL_UNNAMED];
313 } else
314 g_assert(FALSE); /* UNKNOWN STATE */
315
316 return prop_line;
317
318}
319
320#if 0
6550d711 321static inline PropertiesLine prepare_status_line(LttvProcessState *process)
c8bba5fa 322{
323 PropertiesLine prop_line;
324 prop_line.line_width = 2;
325 prop_line.style = GDK_LINE_SOLID;
e800cf84 326 prop_line.y = MIDDLE;
327 //GdkColormap *colormap = gdk_colormap_get_system();
c8bba5fa 328
23093869 329 g_debug("prepare_status_line for state : %s",
330 g_quark_to_string(process->state->s));
c8bba5fa 331
332 /* color of line : status of the process */
333 if(process->state->s == LTTV_STATE_UNNAMED)
e800cf84 334 prop_line.color = drawing_colors[COL_WHITE];
c8bba5fa 335 else if(process->state->s == LTTV_STATE_WAIT_FORK)
e800cf84 336 prop_line.color = drawing_colors[COL_WAIT_FORK];
c8bba5fa 337 else if(process->state->s == LTTV_STATE_WAIT_CPU)
e800cf84 338 prop_line.color = drawing_colors[COL_WAIT_CPU];
dbd243b1 339 else if(process->state->s == LTTV_STATE_EXIT)
340 prop_line.color = drawing_colors[COL_EXIT];
0828099d 341 else if(process->state->s == LTTV_STATE_ZOMBIE)
342 prop_line.color = drawing_colors[COL_ZOMBIE];
c8bba5fa 343 else if(process->state->s == LTTV_STATE_WAIT)
e800cf84 344 prop_line.color = drawing_colors[COL_WAIT];
c8bba5fa 345 else if(process->state->s == LTTV_STATE_RUN)
e800cf84 346 prop_line.color = drawing_colors[COL_RUN];
c8bba5fa 347 else
23093869 348 prop_line.color = drawing_colors[COL_WHITE];
e800cf84 349
350 //gdk_colormap_alloc_color(colormap,
351 // prop_line.color,
352 // FALSE,
353 // TRUE);
c8bba5fa 354
355 return prop_line;
356
357}
9a1ec01b 358#endif //0
c8bba5fa 359
360
e92eabaf 361/* before_schedchange_hook
b9a010a2 362 *
f0d936c0 363 * This function basically draw lines and icons. Two types of lines are drawn :
364 * one small (3 pixels?) representing the state of the process and the second
365 * type is thicker (10 pixels?) representing on which CPU a process is running
366 * (and this only in running state).
367 *
368 * Extremums of the lines :
369 * x_min : time of the last event context for this process kept in memory.
370 * x_max : time of the current event.
371 * y : middle of the process in the process list. The process is found in the
372 * list, therefore is it's position in pixels.
373 *
374 * The choice of lines'color is defined by the context of the last event for this
375 * process.
376 */
b9a010a2 377
378
e92eabaf 379int before_schedchange_hook(void *hook_data, void *call_data)
f0d936c0 380{
2c82c4dc 381 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
382 EventsRequest *events_request = (EventsRequest*)thf->hook_data;
b9a010a2 383 ControlFlowData *control_flow_data = events_request->viewer_data;
384
385 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
386
387 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
348c6ba8 388 LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
b9a010a2 389
390 LttEvent *e;
2c82c4dc 391 e = ltt_tracefile_get_event(tfc->tf);
b9a010a2 392
393 LttTime evtime = ltt_event_time(e);
fd22065b 394
10a1069a 395 /* we are in a schedchange, before the state update. We must draw the
396 * items corresponding to the state before it changes : now is the right
397 * time to do it.
398 */
b9a010a2 399
10a1069a 400 guint pid_out;
401 guint pid_in;
402 {
2c82c4dc 403 pid_out = ltt_event_get_long_unsigned(e, thf->f1);
404 pid_in = ltt_event_get_long_unsigned(e, thf->f2);
10a1069a 405 }
406
407 {
408 /* For the pid_out */
409 /* First, check if the current process is in the state computation
410 * process list. If it is there, that means we must add it right now and
411 * draw items from the beginning of the read for it. If it is not
412 * present, it's a new process and it was not present : it will
413 * be added after the state update. */
348c6ba8 414 guint cpu = ltt_tracefile_num(tfc->tf);
415 LttvProcessState *process = ts->running_process[cpu];
40debf7b 416 /* unknown state, bad current pid */
348c6ba8 417 if(process->pid != pid_out)
418 process = lttv_state_find_process(ts, ANY_CPU, pid_out);
b9a010a2 419
10a1069a 420 if(process != NULL) {
421 /* Well, the process_out existed : we must get it in the process hash
422 * or add it, and draw its items.
423 */
424 /* Add process to process list (if not present) */
1c736ed5 425 guint pl_height = 0;
10a1069a 426 HashedProcessData *hashed_process_data = NULL;
5c230fc4 427 ProcessList *process_list = control_flow_data->process_list;
10a1069a 428 LttTime birth = process->creation_time;
b9a010a2 429
ac4e21cf 430 hashed_process_data = processlist_get_process_data(process_list,
10a1069a 431 pid_out,
348c6ba8 432 process->cpu,
10a1069a 433 &birth,
ac4e21cf 434 tfc->t_context->index);
435 if(hashed_process_data == NULL)
10a1069a 436 {
437 g_assert(pid_out == 0 || pid_out != process->ppid);
438 /* Process not present */
4e86ae2e 439 ProcessInfo *process_info;
1c736ed5 440 Drawing_t *drawing = control_flow_data->drawing;
10a1069a 441 processlist_add(process_list,
1c736ed5 442 drawing,
10a1069a 443 pid_out,
348c6ba8 444 process->cpu,
10a1069a 445 process->ppid,
446 &birth,
447 tfc->t_context->index,
f4b88a7d 448 process->name,
10a1069a 449 &pl_height,
4e86ae2e 450 &process_info,
10a1069a 451 &hashed_process_data);
1c736ed5 452 gtk_widget_set_size_request(drawing->drawing_area,
453 -1,
454 pl_height);
455 gtk_widget_queue_draw(drawing->drawing_area);
456
10a1069a 457 }
ac4e21cf 458
10a1069a 459 /* Now, the process is in the state hash and our own process hash.
460 * We definitely can draw the items related to the ending state.
461 */
e800cf84 462
b2743953 463 if(ltt_time_compare(hashed_process_data->next_good_time,
464 evtime) > 0)
10a1069a 465 {
b2743953 466 if(hashed_process_data->x.middle_marked == FALSE) {
ac4e21cf 467
fd22065b 468 TimeWindow time_window =
469 lttvwindow_get_time_window(control_flow_data->tab);
470#ifdef EXTRA_CHECK
471 if(ltt_time_compare(evtime, time_window.start_time) == -1
472 || ltt_time_compare(evtime, time_window.end_time) == 1)
473 return;
474#endif //EXTRA_CHECK
d6fef890 475 Drawing_t *drawing = control_flow_data->drawing;
96947fcf 476 guint width = drawing->width;
b2743953 477 guint x;
478 convert_time_to_pixels(
479 time_window,
480 evtime,
481 width,
482 &x);
483
484 /* Draw collision indicator */
485 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
1c736ed5 486 gdk_draw_point(hashed_process_data->pixmap,
b2743953 487 drawing->gc,
488 x,
1c736ed5 489 (hashed_process_data->height/2)-3);
b2743953 490 hashed_process_data->x.middle_marked = TRUE;
491 }
492 } else {
ac4e21cf 493 TimeWindow time_window =
494 lttvwindow_get_time_window(control_flow_data->tab);
fd22065b 495#ifdef EXTRA_CHECK
ac4e21cf 496 if(ltt_time_compare(evtime, time_window.start_time) == -1
497 || ltt_time_compare(evtime, time_window.end_time) == 1)
498 return;
fd22065b 499#endif //EXTRA_CHECK
d6fef890 500 Drawing_t *drawing = control_flow_data->drawing;
96947fcf 501 guint width = drawing->width;
10a1069a 502 guint x;
10a1069a 503 convert_time_to_pixels(
a18124ff 504 time_window,
4b7dc462 505 evtime,
506 width,
507 &x);
10a1069a 508
10a1069a 509
4b7dc462 510 /* Jump over draw if we are at the same x position */
e72908ed 511 if(x == hashed_process_data->x.middle &&
512 hashed_process_data->x.middle_used)
e800cf84 513 {
e72908ed 514 if(hashed_process_data->x.middle_marked == FALSE) {
515 /* Draw collision indicator */
516 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
1c736ed5 517 gdk_draw_point(hashed_process_data->pixmap,
e72908ed 518 drawing->gc,
519 x,
1c736ed5 520 (hashed_process_data->height/2)-3);
de4ea1ad 521 hashed_process_data->x.middle_marked = TRUE;
e72908ed 522 }
4b7dc462 523 /* jump */
524 } else {
525 DrawContext draw_context;
10a1069a 526
4b7dc462 527 /* Now create the drawing context that will be used to draw
528 * items related to the last state. */
1c736ed5 529 draw_context.drawable = hashed_process_data->pixmap;
4b7dc462 530 draw_context.gc = drawing->gc;
531 draw_context.pango_layout = drawing->pango_layout;
532 draw_context.drawinfo.start.x = hashed_process_data->x.middle;
533 draw_context.drawinfo.end.x = x;
534
1c736ed5 535 draw_context.drawinfo.y.over = 1;
536 draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
537 draw_context.drawinfo.y.under = hashed_process_data->height;
4b7dc462 538
539 draw_context.drawinfo.start.offset.over = 0;
540 draw_context.drawinfo.start.offset.middle = 0;
541 draw_context.drawinfo.start.offset.under = 0;
542 draw_context.drawinfo.end.offset.over = 0;
543 draw_context.drawinfo.end.offset.middle = 0;
544 draw_context.drawinfo.end.offset.under = 0;
545
546 {
547 /* Draw the line */
9a1ec01b 548 PropertiesLine prop_line = prepare_s_e_line(process);
4b7dc462 549 draw_line((void*)&prop_line, (void*)&draw_context);
550
551 }
552 /* become the last x position */
553 hashed_process_data->x.middle = x;
e72908ed 554 hashed_process_data->x.middle_used = TRUE;
555 hashed_process_data->x.middle_marked = FALSE;
b2743953 556
557 /* Calculate the next good time */
558 convert_pixels_to_time(width, x+1, time_window,
559 &hashed_process_data->next_good_time);
e800cf84 560 }
561 }
562 }
10a1069a 563 }
e800cf84 564
10a1069a 565 {
566 /* For the pid_in */
567 /* First, check if the current process is in the state computation
568 * process list. If it is there, that means we must add it right now and
569 * draw items from the beginning of the read for it. If it is not
570 * present, it's a new process and it was not present : it will
571 * be added after the state update. */
572 LttvProcessState *process;
348c6ba8 573 process = lttv_state_find_process(ts, ANY_CPU, pid_in);
10a1069a 574
575 if(process != NULL) {
576 /* Well, the process_out existed : we must get it in the process hash
577 * or add it, and draw its items.
578 */
579 /* Add process to process list (if not present) */
1c736ed5 580 guint pl_height = 0;
10a1069a 581 HashedProcessData *hashed_process_data = NULL;
5c230fc4 582 ProcessList *process_list = control_flow_data->process_list;
10a1069a 583 LttTime birth = process->creation_time;
e800cf84 584
ac4e21cf 585 hashed_process_data = processlist_get_process_data(process_list,
10a1069a 586 pid_in,
348c6ba8 587 process->cpu,
10a1069a 588 &birth,
ac4e21cf 589 tfc->t_context->index);
590 if(hashed_process_data == NULL)
10a1069a 591 {
592 g_assert(pid_in == 0 || pid_in != process->ppid);
593 /* Process not present */
4e86ae2e 594 ProcessInfo *process_info;
1c736ed5 595 Drawing_t *drawing = control_flow_data->drawing;
10a1069a 596 processlist_add(process_list,
1c736ed5 597 drawing,
10a1069a 598 pid_in,
348c6ba8 599 process->cpu,
10a1069a 600 process->ppid,
601 &birth,
602 tfc->t_context->index,
f4b88a7d 603 process->name,
10a1069a 604 &pl_height,
4e86ae2e 605 &process_info,
10a1069a 606 &hashed_process_data);
1c736ed5 607 gtk_widget_set_size_request(drawing->drawing_area,
608 -1,
609 pl_height);
610 gtk_widget_queue_draw(drawing->drawing_area);
611
10a1069a 612 }
40debf7b 613 //We could set the current process and hash here, but will be done
614 //by after schedchange hook
10a1069a 615
616 /* Now, the process is in the state hash and our own process hash.
617 * We definitely can draw the items related to the ending state.
618 */
b9a010a2 619
b2743953 620 if(ltt_time_compare(hashed_process_data->next_good_time,
621 evtime) > 0)
10a1069a 622 {
b2743953 623 if(hashed_process_data->x.middle_marked == FALSE) {
ac4e21cf 624
fd22065b 625 TimeWindow time_window =
626 lttvwindow_get_time_window(control_flow_data->tab);
627#ifdef EXTRA_CHECK
628 if(ltt_time_compare(evtime, time_window.start_time) == -1
629 || ltt_time_compare(evtime, time_window.end_time) == 1)
630 return;
631#endif //EXTRA_CHECK
d6fef890 632 Drawing_t *drawing = control_flow_data->drawing;
96947fcf 633 guint width = drawing->width;
b2743953 634 guint x;
635 convert_time_to_pixels(
636 time_window,
637 evtime,
638 width,
639 &x);
640
641 /* Draw collision indicator */
642 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
1c736ed5 643 gdk_draw_point(hashed_process_data->pixmap,
b2743953 644 drawing->gc,
645 x,
1c736ed5 646 (hashed_process_data->height/2)-3);
b2743953 647 hashed_process_data->x.middle_marked = TRUE;
648 }
649 } else {
fd22065b 650 TimeWindow time_window =
651 lttvwindow_get_time_window(control_flow_data->tab);
652#ifdef EXTRA_CHECK
653 if(ltt_time_compare(evtime, time_window.start_time) == -1
654 || ltt_time_compare(evtime, time_window.end_time) == 1)
655 return;
656#endif //EXTRA_CHECK
d6fef890 657 Drawing_t *drawing = control_flow_data->drawing;
96947fcf 658 guint width = drawing->width;
10a1069a 659 guint x;
10a1069a 660
661 convert_time_to_pixels(
a18124ff 662 time_window,
4b7dc462 663 evtime,
664 width,
665 &x);
10a1069a 666
10a1069a 667
4b7dc462 668 /* Jump over draw if we are at the same x position */
e72908ed 669 if(x == hashed_process_data->x.middle &&
670 hashed_process_data->x.middle_used)
4b7dc462 671 {
e72908ed 672 if(hashed_process_data->x.middle_marked == FALSE) {
673 /* Draw collision indicator */
674 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
1c736ed5 675 gdk_draw_point(hashed_process_data->pixmap,
e72908ed 676 drawing->gc,
677 x,
1c736ed5 678 (hashed_process_data->height/2)-3);
de4ea1ad 679 hashed_process_data->x.middle_marked = TRUE;
e72908ed 680 }
4b7dc462 681 /* jump */
682 } else {
683 DrawContext draw_context;
10a1069a 684
4b7dc462 685 /* Now create the drawing context that will be used to draw
686 * items related to the last state. */
1c736ed5 687 draw_context.drawable = hashed_process_data->pixmap;
4b7dc462 688 draw_context.gc = drawing->gc;
689 draw_context.pango_layout = drawing->pango_layout;
690 draw_context.drawinfo.start.x = hashed_process_data->x.middle;
691 draw_context.drawinfo.end.x = x;
10a1069a 692
1c736ed5 693 draw_context.drawinfo.y.over = 1;
694 draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
695 draw_context.drawinfo.y.under = hashed_process_data->height;
10a1069a 696
4b7dc462 697 draw_context.drawinfo.start.offset.over = 0;
698 draw_context.drawinfo.start.offset.middle = 0;
699 draw_context.drawinfo.start.offset.under = 0;
700 draw_context.drawinfo.end.offset.over = 0;
701 draw_context.drawinfo.end.offset.middle = 0;
702 draw_context.drawinfo.end.offset.under = 0;
703
704 {
705 /* Draw the line */
9a1ec01b 706 PropertiesLine prop_line = prepare_s_e_line(process);
4b7dc462 707 draw_line((void*)&prop_line, (void*)&draw_context);
708 }
709
710
711 /* become the last x position */
712 hashed_process_data->x.middle = x;
e72908ed 713 hashed_process_data->x.middle_used = TRUE;
714 hashed_process_data->x.middle_marked = FALSE;
b2743953 715
716 /* Calculate the next good time */
717 convert_pixels_to_time(width, x+1, time_window,
718 &hashed_process_data->next_good_time);
4b7dc462 719 }
c8bba5fa 720 }
b9a010a2 721 }
722 }
b9a010a2 723 return 0;
724
725
b9a010a2 726#if 0
ca0f8a8e 727 EventsRequest *events_request = (EventsRequest*)hook_data;
728 ControlFlowData *control_flow_data =
729 (ControlFlowData*)events_request->viewer_data;
730 Tab *tab = control_flow_data->tab;
e9a9c513 731
a56a1ba4 732 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
e9a9c513 733
734 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
1aff52a2 735 LttvTraceState *ts =(LttvTraceState *)LTTV_TRACEFILE_CONTEXT(tfs)->t_context;
a56a1ba4 736
e9a9c513 737 LttEvent *e;
e9a9c513 738 e = tfc->e;
739
9444deae 740 LttTime evtime = ltt_event_time(e);
ca0f8a8e 741 TimeWindow time_window =
742 lttvwindow_get_time_window(tab);
9444deae 743
a2aab3a3 744 LttTime time_window.end_time = time_window.time_window.end_time;
6f26fc38 745
9444deae 746 //if(time < time_beg || time > time_end) return;
ca0f8a8e 747 if(ltt_time_compare(evtime, time_window.start_time) == -1
a2aab3a3 748 || ltt_time_compare(evtime, time_window.end_time) == 1)
9444deae 749 return;
750
a56a1ba4 751 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e)),"schedchange") == 0)
752 {
2a2fa4f0 753 g_debug("schedchange!");
a56a1ba4 754
755 /* Add process to process list (if not present) and get drawing "y" from
756 * process position */
757 guint pid_out, pid_in;
758 LttvProcessState *process_out, *process_in;
759 LttTime birth;
760 guint y_in = 0, y_out = 0, height = 0, pl_height = 0;
761
5c230fc4 762 ProcessList *process_list = control_flow_data->process_list;
a56a1ba4 763
764
765 LttField *f = ltt_event_field(e);
766 LttField *element;
767 element = ltt_field_member(f,0);
768 pid_out = ltt_event_get_long_unsigned(e,element);
769 element = ltt_field_member(f,1);
770 pid_in = ltt_event_get_long_unsigned(e,element);
2a2fa4f0 771 g_debug("out : %u in : %u", pid_out, pid_in);
a56a1ba4 772
773
774 /* Find process pid_out in the list... */
87658614 775 process_out = lttv_state_find_process(tfs, pid_out);
1aff52a2 776 if(process_out == NULL) return 0;
2a2fa4f0 777 g_debug("out : %s",g_quark_to_string(process_out->state->s));
1aff52a2 778
a56a1ba4 779 birth = process_out->creation_time;
51705146 780 const gchar *name = g_quark_to_string(process_out->name);
14963be0 781 HashedProcessData *hashed_process_data_out = NULL;
a56a1ba4 782
783 if(processlist_get_process_pixels(process_list,
784 pid_out,
785 &birth,
d0cd7f09 786 tfc->t_context->index,
a56a1ba4 787 &y_out,
788 &height,
14963be0 789 &hashed_process_data_out) == 1)
a56a1ba4 790 {
51705146 791 /* Process not present */
792 processlist_add(process_list,
793 pid_out,
794 &birth,
795 tfc->t_context->index,
796 name,
797 &pl_height,
798 &hashed_process_data_out);
799 g_assert(processlist_get_process_pixels(process_list,
800 pid_out,
801 &birth,
802 tfc->t_context->index,
803 &y_out,
804 &height,
805 &hashed_process_data_out)==0);
806 drawing_insert_square( control_flow_data->drawing, y_out, height);
a56a1ba4 807 }
51705146 808 //g_free(name);
a56a1ba4 809
810 /* Find process pid_in in the list... */
87658614 811 process_in = lttv_state_find_process(tfs, pid_in);
1aff52a2 812 if(process_in == NULL) return 0;
2a2fa4f0 813 g_debug("in : %s",g_quark_to_string(process_in->state->s));
a56a1ba4 814
815 birth = process_in->creation_time;
51705146 816 name = g_quark_to_string(process_in->name);
14963be0 817 HashedProcessData *hashed_process_data_in = NULL;
a56a1ba4 818
819 if(processlist_get_process_pixels(process_list,
820 pid_in,
821 &birth,
d0cd7f09 822 tfc->t_context->index,
a56a1ba4 823 &y_in,
824 &height,
14963be0 825 &hashed_process_data_in) == 1)
a56a1ba4 826 {
51705146 827 /* Process not present */
a56a1ba4 828 processlist_add(process_list,
829 pid_in,
830 &birth,
d0cd7f09 831 tfc->t_context->index,
a56a1ba4 832 name,
833 &pl_height,
14963be0 834 &hashed_process_data_in);
a56a1ba4 835 processlist_get_process_pixels(process_list,
836 pid_in,
837 &birth,
d0cd7f09 838 tfc->t_context->index,
a56a1ba4 839 &y_in,
840 &height,
14963be0 841 &hashed_process_data_in);
a56a1ba4 842
ca0f8a8e 843 drawing_insert_square( control_flow_data->drawing, y_in, height);
a56a1ba4 844 }
51705146 845 //g_free(name);
a56a1ba4 846
847
848 /* Find pixels corresponding to time of the event. If the time does
849 * not fit in the window, show a warning, not supposed to happend. */
850 guint x = 0;
51705146 851 guint width = control_flow_data->drawing->width;
a56a1ba4 852
853 LttTime time = ltt_event_time(e);
854
a2aab3a3 855 LttTime window_end = time_window.time_window.end_time;
a56a1ba4 856
857 convert_time_to_pixels(
a18124ff 858 time_window,
a56a1ba4 859 time,
860 width,
861 &x);
9444deae 862 //assert(x <= width);
51705146 863 //
a56a1ba4 864 /* draw what represents the event for outgoing process. */
865
14963be0 866 DrawContext *draw_context_out = hashed_process_data_out->draw_context;
68997a22 867 draw_context_out->current->modify_over->x = x;
319e9d81 868 draw_context_out->current->modify_under->x = x;
68997a22 869 draw_context_out->current->modify_over->y = y_out;
319e9d81 870 draw_context_out->current->modify_under->y = y_out+(height/2)+2;
501d5405 871 draw_context_out->drawable = control_flow_data->drawing->pixmap;
872 draw_context_out->pango_layout = control_flow_data->drawing->pango_layout;
873 GtkWidget *widget = control_flow_data->drawing->drawing_area;
a56a1ba4 874 //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
d0cd7f09 875 //draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
876 //gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
a56a1ba4 877 //draw_context_out->gc = widget->style->black_gc;
878
879 //draw_arc((void*)&prop_arc, (void*)draw_context_out);
501d5405 880 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
a56a1ba4 881
d0cd7f09 882 /* Draw the line/background of the out process */
883 if(draw_context_out->previous->middle->x == -1)
884 {
ca0f8a8e 885 draw_context_out->previous->over->x =
886 control_flow_data->drawing->damage_begin;
887 draw_context_out->previous->middle->x =
888 control_flow_data->drawing->damage_begin;
889 draw_context_out->previous->under->x =
890 control_flow_data->drawing->damage_begin;
ca0f8a8e 891 g_debug("out middle x_beg : %u",control_flow_data->drawing->damage_begin);
d0cd7f09 892 }
893
894 draw_context_out->current->middle->x = x;
895 draw_context_out->current->over->x = x;
896 draw_context_out->current->under->x = x;
897 draw_context_out->current->middle->y = y_out + height/2;
898 draw_context_out->current->over->y = y_out;
899 draw_context_out->current->under->y = y_out + height;
900 draw_context_out->previous->middle->y = y_out + height/2;
901 draw_context_out->previous->over->y = y_out;
902 draw_context_out->previous->under->y = y_out + height;
903
904 draw_context_out->drawable = control_flow_data->drawing->pixmap;
905 draw_context_out->pango_layout = control_flow_data->drawing->pango_layout;
906
907 if(process_out->state->s == LTTV_STATE_RUN)
908 {
51705146 909 //draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
910 //gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
911 draw_context_out->gc = control_flow_data->drawing->gc;
d0cd7f09 912
913 PropertiesBG prop_bg;
914 prop_bg.color = g_new(GdkColor,1);
915
2c82c4dc 916 switch(ltt_tracefile_num(tfc->tf)) {
d0cd7f09 917 case 0:
918 prop_bg.color->red = 0x1515;
919 prop_bg.color->green = 0x1515;
920 prop_bg.color->blue = 0x8c8c;
921 break;
922 case 1:
923 prop_bg.color->red = 0x4e4e;
924 prop_bg.color->green = 0xa9a9;
925 prop_bg.color->blue = 0xa4a4;
926 break;
927 case 2:
928 prop_bg.color->red = 0x7a7a;
929 prop_bg.color->green = 0x4a4a;
930 prop_bg.color->blue = 0x8b8b;
931 break;
932 case 3:
933 prop_bg.color->red = 0x8080;
934 prop_bg.color->green = 0x7777;
935 prop_bg.color->blue = 0x4747;
936 break;
937 default:
938 prop_bg.color->red = 0xe7e7;
939 prop_bg.color->green = 0xe7e7;
940 prop_bg.color->blue = 0xe7e7;
941 }
942
2a2fa4f0 943 g_debug("calling from draw_event");
d0cd7f09 944 draw_bg((void*)&prop_bg, (void*)draw_context_out);
945 g_free(prop_bg.color);
51705146 946 //gdk_gc_unref(draw_context_out->gc);
d0cd7f09 947 }
948
949 draw_context_out->gc = widget->style->black_gc;
950
a56a1ba4 951 GdkColor colorfg_out = { 0, 0xffff, 0x0000, 0x0000 };
2df6f2bd 952 GdkColor colorbg_out = { 0, 0x0000, 0x0000, 0x0000 };
a56a1ba4 953 PropertiesText prop_text_out;
954 prop_text_out.foreground = &colorfg_out;
955 prop_text_out.background = &colorbg_out;
cfe526b1 956 prop_text_out.size = 6;
a56a1ba4 957 prop_text_out.position = OVER;
958
cfe526b1 959 /* color of text : status of the process */
960 if(process_out->state->s == LTTV_STATE_UNNAMED)
961 {
962 prop_text_out.foreground->red = 0xffff;
963 prop_text_out.foreground->green = 0xffff;
964 prop_text_out.foreground->blue = 0xffff;
965 }
966 else if(process_out->state->s == LTTV_STATE_WAIT_FORK)
967 {
968 prop_text_out.foreground->red = 0x0fff;
d52cfc84 969 prop_text_out.foreground->green = 0xffff;
970 prop_text_out.foreground->blue = 0xfff0;
cfe526b1 971 }
972 else if(process_out->state->s == LTTV_STATE_WAIT_CPU)
973 {
2df6f2bd 974 prop_text_out.foreground->red = 0xffff;
975 prop_text_out.foreground->green = 0xffff;
cfe526b1 976 prop_text_out.foreground->blue = 0x0000;
977 }
0828099d 978 else if(process_out->state->s == LTTV_STATE_ZOMBIE)
cfe526b1 979 {
980 prop_text_out.foreground->red = 0xffff;
981 prop_text_out.foreground->green = 0x0000;
982 prop_text_out.foreground->blue = 0xffff;
983 }
984 else if(process_out->state->s == LTTV_STATE_WAIT)
985 {
986 prop_text_out.foreground->red = 0xffff;
987 prop_text_out.foreground->green = 0x0000;
988 prop_text_out.foreground->blue = 0x0000;
989 }
990 else if(process_out->state->s == LTTV_STATE_RUN)
991 {
992 prop_text_out.foreground->red = 0x0000;
993 prop_text_out.foreground->green = 0xffff;
994 prop_text_out.foreground->blue = 0x0000;
995 }
996 else
997 {
998 prop_text_out.foreground->red = 0xffff;
999 prop_text_out.foreground->green = 0xffff;
1000 prop_text_out.foreground->blue = 0xffff;
1001 }
1002
d52cfc84 1003
a56a1ba4 1004 /* Print status of the process : U, WF, WC, E, W, R */
1005 if(process_out->state->s == LTTV_STATE_UNNAMED)
cfe526b1 1006 prop_text_out.text = "U->";
a56a1ba4 1007 else if(process_out->state->s == LTTV_STATE_WAIT_FORK)
cfe526b1 1008 prop_text_out.text = "WF->";
a56a1ba4 1009 else if(process_out->state->s == LTTV_STATE_WAIT_CPU)
cfe526b1 1010 prop_text_out.text = "WC->";
0828099d 1011 else if(process_out->state->s == LTTV_STATE_ZOMBIE)
cfe526b1 1012 prop_text_out.text = "E->";
a56a1ba4 1013 else if(process_out->state->s == LTTV_STATE_WAIT)
cfe526b1 1014 prop_text_out.text = "W->";
a56a1ba4 1015 else if(process_out->state->s == LTTV_STATE_RUN)
cfe526b1 1016 prop_text_out.text = "R->";
a56a1ba4 1017 else
68997a22 1018 prop_text_out.text = "U";
a56a1ba4 1019
1020 draw_text((void*)&prop_text_out, (void*)draw_context_out);
d0cd7f09 1021 //gdk_gc_unref(draw_context_out->gc);
a56a1ba4 1022
51705146 1023 //draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1024 //gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
1025 draw_context_out->gc = control_flow_data->drawing->gc;
a56a1ba4 1026
1027 PropertiesLine prop_line_out;
1028 prop_line_out.color = g_new(GdkColor,1);
cfe526b1 1029 prop_line_out.line_width = 2;
a56a1ba4 1030 prop_line_out.style = GDK_LINE_SOLID;
1031 prop_line_out.position = MIDDLE;
d52cfc84 1032
2a2fa4f0 1033 g_debug("out state : %s", g_quark_to_string(process_out->state->s));
a56a1ba4 1034
1035 /* color of line : status of the process */
1036 if(process_out->state->s == LTTV_STATE_UNNAMED)
1037 {
cfe526b1 1038 prop_line_out.color->red = 0xffff;
1039 prop_line_out.color->green = 0xffff;
1040 prop_line_out.color->blue = 0xffff;
a56a1ba4 1041 }
1042 else if(process_out->state->s == LTTV_STATE_WAIT_FORK)
1043 {
1044 prop_line_out.color->red = 0x0fff;
d52cfc84 1045 prop_line_out.color->green = 0xffff;
1046 prop_line_out.color->blue = 0xfff0;
a56a1ba4 1047 }
1048 else if(process_out->state->s == LTTV_STATE_WAIT_CPU)
1049 {
2df6f2bd 1050 prop_line_out.color->red = 0xffff;
1051 prop_line_out.color->green = 0xffff;
a56a1ba4 1052 prop_line_out.color->blue = 0x0000;
1053 }
0828099d 1054 else if(process_out->state->s == LTTV_STATE_ZOMBIE)
a56a1ba4 1055 {
1056 prop_line_out.color->red = 0xffff;
1057 prop_line_out.color->green = 0x0000;
1058 prop_line_out.color->blue = 0xffff;
1059 }
1060 else if(process_out->state->s == LTTV_STATE_WAIT)
1061 {
1062 prop_line_out.color->red = 0xffff;
1063 prop_line_out.color->green = 0x0000;
1064 prop_line_out.color->blue = 0x0000;
1065 }
1066 else if(process_out->state->s == LTTV_STATE_RUN)
1067 {
1068 prop_line_out.color->red = 0x0000;
1069 prop_line_out.color->green = 0xffff;
1070 prop_line_out.color->blue = 0x0000;
1071 }
1072 else
1073 {
cfe526b1 1074 prop_line_out.color->red = 0xffff;
1075 prop_line_out.color->green = 0xffff;
1076 prop_line_out.color->blue = 0xffff;
a56a1ba4 1077 }
1078
1079 draw_line((void*)&prop_line_out, (void*)draw_context_out);
1080 g_free(prop_line_out.color);
51705146 1081 //gdk_gc_unref(draw_context_out->gc);
a56a1ba4 1082 /* Note : finishing line will have to be added when trace read over. */
1083
1084 /* Finally, update the drawing context of the pid_in. */
1085
14963be0 1086 DrawContext *draw_context_in = hashed_process_data_in->draw_context;
68997a22 1087 draw_context_in->current->modify_over->x = x;
319e9d81 1088 draw_context_in->current->modify_under->x = x;
68997a22 1089 draw_context_in->current->modify_over->y = y_in;
319e9d81 1090 draw_context_in->current->modify_under->y = y_in+(height/2)+2;
501d5405 1091 draw_context_in->drawable = control_flow_data->drawing->pixmap;
1092 draw_context_in->pango_layout = control_flow_data->drawing->pango_layout;
1093 widget = control_flow_data->drawing->drawing_area;
a56a1ba4 1094 //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
1095 //draw_context_in->gc = widget->style->black_gc;
d0cd7f09 1096 //draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1097 //gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
a56a1ba4 1098
1099 //draw_arc((void*)&prop_arc, (void*)draw_context_in);
501d5405 1100 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
d0cd7f09 1101
1102 /* Draw the line/bg of the in process */
1103 if(draw_context_in->previous->middle->x == -1)
1104 {
ca0f8a8e 1105 draw_context_in->previous->over->x =
1106 control_flow_data->drawing->damage_begin;
1107 draw_context_in->previous->middle->x =
1108 control_flow_data->drawing->damage_begin;
1109 draw_context_in->previous->under->x =
1110 control_flow_data->drawing->damage_begin;
1111
1112 g_debug("in middle x_beg : %u",control_flow_data->drawing->damage_begin);
1113
d0cd7f09 1114 }
1115
1116 draw_context_in->current->middle->x = x;
1117 draw_context_in->current->over->x = x;
1118 draw_context_in->current->under->x = x;
1119 draw_context_in->current->middle->y = y_in + height/2;
1120 draw_context_in->current->over->y = y_in;
1121 draw_context_in->current->under->y = y_in + height;
1122 draw_context_in->previous->middle->y = y_in + height/2;
1123 draw_context_in->previous->over->y = y_in;
1124 draw_context_in->previous->under->y = y_in + height;
a56a1ba4 1125
d0cd7f09 1126 draw_context_in->drawable = control_flow_data->drawing->pixmap;
1127 draw_context_in->pango_layout = control_flow_data->drawing->pango_layout;
1128
1129
1130 if(process_in->state->s == LTTV_STATE_RUN)
1131 {
51705146 1132 //draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1133 //gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
1134 draw_context_in->gc = control_flow_data->drawing->gc;
d0cd7f09 1135
1136 PropertiesBG prop_bg;
1137 prop_bg.color = g_new(GdkColor,1);
1138
2c82c4dc 1139 switcht(ltt_tracefile_num(tfc->tf)) {
d0cd7f09 1140 case 0:
1141 prop_bg.color->red = 0x1515;
1142 prop_bg.color->green = 0x1515;
1143 prop_bg.color->blue = 0x8c8c;
1144 break;
1145 case 1:
1146 prop_bg.color->red = 0x4e4e;
1147 prop_bg.color->green = 0xa9a9;
1148 prop_bg.color->blue = 0xa4a4;
1149 break;
1150 case 2:
1151 prop_bg.color->red = 0x7a7a;
1152 prop_bg.color->green = 0x4a4a;
1153 prop_bg.color->blue = 0x8b8b;
1154 break;
1155 case 3:
1156 prop_bg.color->red = 0x8080;
1157 prop_bg.color->green = 0x7777;
1158 prop_bg.color->blue = 0x4747;
1159 break;
1160 default:
1161 prop_bg.color->red = 0xe7e7;
1162 prop_bg.color->green = 0xe7e7;
1163 prop_bg.color->blue = 0xe7e7;
1164 }
1165
1166
1167 draw_bg((void*)&prop_bg, (void*)draw_context_in);
1168 g_free(prop_bg.color);
51705146 1169 //gdk_gc_unref(draw_context_in->gc);
d0cd7f09 1170 }
1171
1172 draw_context_in->gc = widget->style->black_gc;
1173
a56a1ba4 1174 GdkColor colorfg_in = { 0, 0x0000, 0xffff, 0x0000 };
2df6f2bd 1175 GdkColor colorbg_in = { 0, 0x0000, 0x0000, 0x0000 };
a56a1ba4 1176 PropertiesText prop_text_in;
1177 prop_text_in.foreground = &colorfg_in;
1178 prop_text_in.background = &colorbg_in;
cfe526b1 1179 prop_text_in.size = 6;
a56a1ba4 1180 prop_text_in.position = OVER;
1181
2a2fa4f0 1182 g_debug("in state : %s", g_quark_to_string(process_in->state->s));
cfe526b1 1183 /* foreground of text : status of the process */
1184 if(process_in->state->s == LTTV_STATE_UNNAMED)
1185 {
1186 prop_text_in.foreground->red = 0xffff;
1187 prop_text_in.foreground->green = 0xffff;
1188 prop_text_in.foreground->blue = 0xffff;
1189 }
1190 else if(process_in->state->s == LTTV_STATE_WAIT_FORK)
1191 {
1192 prop_text_in.foreground->red = 0x0fff;
d52cfc84 1193 prop_text_in.foreground->green = 0xffff;
1194 prop_text_in.foreground->blue = 0xfff0;
cfe526b1 1195 }
1196 else if(process_in->state->s == LTTV_STATE_WAIT_CPU)
1197 {
2df6f2bd 1198 prop_text_in.foreground->red = 0xffff;
1199 prop_text_in.foreground->green = 0xffff;
cfe526b1 1200 prop_text_in.foreground->blue = 0x0000;
1201 }
0828099d 1202 else if(process_in->state->s == LTTV_STATE_ZOMBIE)
cfe526b1 1203 {
1204 prop_text_in.foreground->red = 0xffff;
1205 prop_text_in.foreground->green = 0x0000;
1206 prop_text_in.foreground->blue = 0xffff;
1207 }
1208 else if(process_in->state->s == LTTV_STATE_WAIT)
1209 {
1210 prop_text_in.foreground->red = 0xffff;
1211 prop_text_in.foreground->green = 0x0000;
1212 prop_text_in.foreground->blue = 0x0000;
1213 }
1214 else if(process_in->state->s == LTTV_STATE_RUN)
1215 {
1216 prop_text_in.foreground->red = 0x0000;
1217 prop_text_in.foreground->green = 0xffff;
1218 prop_text_in.foreground->blue = 0x0000;
1219 }
1220 else
1221 {
1222 prop_text_in.foreground->red = 0xffff;
1223 prop_text_in.foreground->green = 0xffff;
1224 prop_text_in.foreground->blue = 0xffff;
1225 }
1226
1227
1228
a56a1ba4 1229 /* Print status of the process : U, WF, WC, E, W, R */
1230 if(process_in->state->s == LTTV_STATE_UNNAMED)
cfe526b1 1231 prop_text_in.text = "U->";
a56a1ba4 1232 else if(process_in->state->s == LTTV_STATE_WAIT_FORK)
cfe526b1 1233 prop_text_in.text = "WF->";
a56a1ba4 1234 else if(process_in->state->s == LTTV_STATE_WAIT_CPU)
cfe526b1 1235 prop_text_in.text = "WC->";
0828099d 1236 else if(process_in->state->s == LTTV_STATE_ZOMBIE)
cfe526b1 1237 prop_text_in.text = "E->";
a56a1ba4 1238 else if(process_in->state->s == LTTV_STATE_WAIT)
cfe526b1 1239 prop_text_in.text = "W->";
a56a1ba4 1240 else if(process_in->state->s == LTTV_STATE_RUN)
cfe526b1 1241 prop_text_in.text = "R->";
a56a1ba4 1242 else
68997a22 1243 prop_text_in.text = "U";
a56a1ba4 1244
1245 draw_text((void*)&prop_text_in, (void*)draw_context_in);
d0cd7f09 1246 //gdk_gc_unref(draw_context_in->gc);
1247
51705146 1248 //draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1249 //gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
1250 draw_context_in->gc = control_flow_data->drawing->gc;
d0cd7f09 1251
a56a1ba4 1252 PropertiesLine prop_line_in;
1253 prop_line_in.color = g_new(GdkColor,1);
cfe526b1 1254 prop_line_in.line_width = 2;
a56a1ba4 1255 prop_line_in.style = GDK_LINE_SOLID;
1256 prop_line_in.position = MIDDLE;
1257
1258 /* color of line : status of the process */
1259 if(process_in->state->s == LTTV_STATE_UNNAMED)
1260 {
cfe526b1 1261 prop_line_in.color->red = 0xffff;
1262 prop_line_in.color->green = 0xffff;
1263 prop_line_in.color->blue = 0xffff;
a56a1ba4 1264 }
1265 else if(process_in->state->s == LTTV_STATE_WAIT_FORK)
1266 {
1267 prop_line_in.color->red = 0x0fff;
d52cfc84 1268 prop_line_in.color->green = 0xffff;
1269 prop_line_in.color->blue = 0xfff0;
a56a1ba4 1270 }
1271 else if(process_in->state->s == LTTV_STATE_WAIT_CPU)
1272 {
2df6f2bd 1273 prop_line_in.color->red = 0xffff;
1274 prop_line_in.color->green = 0xffff;
a56a1ba4 1275 prop_line_in.color->blue = 0x0000;
1276 }
0828099d 1277 else if(process_in->state->s == LTTV_STATE_ZOMBIE)
a56a1ba4 1278 {
1279 prop_line_in.color->red = 0xffff;
1280 prop_line_in.color->green = 0x0000;
1281 prop_line_in.color->blue = 0xffff;
1282 }
1283 else if(process_in->state->s == LTTV_STATE_WAIT)
1284 {
1285 prop_line_in.color->red = 0xffff;
1286 prop_line_in.color->green = 0x0000;
1287 prop_line_in.color->blue = 0x0000;
1288 }
1289 else if(process_in->state->s == LTTV_STATE_RUN)
1290 {
1291 prop_line_in.color->red = 0x0000;
1292 prop_line_in.color->green = 0xffff;
1293 prop_line_in.color->blue = 0x0000;
1294 }
1295 else
1296 {
cfe526b1 1297 prop_line_in.color->red = 0xffff;
1298 prop_line_in.color->green = 0xffff;
1299 prop_line_in.color->blue = 0xffff;
a56a1ba4 1300 }
1301
1302 draw_line((void*)&prop_line_in, (void*)draw_context_in);
1303 g_free(prop_line_in.color);
51705146 1304 //gdk_gc_unref(draw_context_in->gc);
a56a1ba4 1305 }
1306
1307 return 0;
b9a010a2 1308#endif //0
1309
1310
a56a1ba4 1311
51705146 1312 /* Text dump */
80a52ff8 1313#ifdef DONTSHOW
a56a1ba4 1314 GString *string = g_string_new("");;
1315 gboolean field_names = TRUE, state = TRUE;
80a52ff8 1316
e9a9c513 1317 lttv_event_to_string(e, tfc->tf, string, TRUE, field_names, tfs);
1318 g_string_append_printf(string,"\n");
1319
1320 if(state) {
1321 g_string_append_printf(string, " %s",
1322 g_quark_to_string(tfs->process->state->s));
1323 }
1324
1325 g_info("%s",string->str);
1326
a56a1ba4 1327 g_string_free(string, TRUE);
1328
1329 /* End of text dump */
80a52ff8 1330#endif //DONTSHOW
50439712 1331
f0d936c0 1332}
1333
e92eabaf 1334/* after_schedchange_hook
b9a010a2 1335 *
1336 * The draw after hook is called by the reading API to have a
1337 * particular event drawn on the screen.
1338 * @param hook_data ControlFlowData structure of the viewer.
1339 * @param call_data Event context.
1340 *
1341 * This function adds items to be drawn in a queue for each process.
1342 *
1343 */
e92eabaf 1344int after_schedchange_hook(void *hook_data, void *call_data)
f0d936c0 1345{
2c82c4dc 1346 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
1347 EventsRequest *events_request = (EventsRequest*)thf->hook_data;
ca0f8a8e 1348 ControlFlowData *control_flow_data = events_request->viewer_data;
50439712 1349
a56a1ba4 1350 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
50439712 1351
1352 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
1353
348c6ba8 1354 LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
1355
b9a010a2 1356 LttEvent *e;
2c82c4dc 1357 e = ltt_tracefile_get_event(tfc->tf);
b9a010a2 1358
1359 LttTime evtime = ltt_event_time(e);
b9a010a2 1360
10a1069a 1361 /* Add process to process list (if not present) */
2eef04b5 1362 LttvProcessState *process_in;
10a1069a 1363 LttTime birth;
1c736ed5 1364 guint pl_height = 0;
10a1069a 1365 HashedProcessData *hashed_process_data_in = NULL;
b9a010a2 1366
5c230fc4 1367 ProcessList *process_list = control_flow_data->process_list;
10a1069a 1368
1369 guint pid_in;
1370 {
1371 guint pid_out;
2c82c4dc 1372 pid_out = ltt_event_get_long_unsigned(e, thf->f1);
1373 pid_in = ltt_event_get_long_unsigned(e, thf->f2);
10a1069a 1374 }
b9a010a2 1375
1376
10a1069a 1377 /* Find process pid_in in the list... */
348c6ba8 1378 //process_in = lttv_state_find_process(ts, ANY_CPU, pid_in);
1379 //process_in = tfs->process;
1380 guint cpu = ltt_tracefile_num(tfc->tf);
1381 process_in = ts->running_process[cpu];
10a1069a 1382 /* It should exist, because we are after the state update. */
96947fcf 1383#ifdef EXTRA_CHECK
10a1069a 1384 g_assert(process_in != NULL);
96947fcf 1385#endif //EXTRA_CHECK
10a1069a 1386 birth = process_in->creation_time;
b9a010a2 1387
ac4e21cf 1388 hashed_process_data_in = processlist_get_process_data(process_list,
10a1069a 1389 pid_in,
348c6ba8 1390 process_in->cpu,
10a1069a 1391 &birth,
ac4e21cf 1392 tfc->t_context->index);
1393 if(hashed_process_data_in == NULL)
10a1069a 1394 {
1395 g_assert(pid_in == 0 || pid_in != process_in->ppid);
4e86ae2e 1396 ProcessInfo *process_info;
1c736ed5 1397 Drawing_t *drawing = control_flow_data->drawing;
10a1069a 1398 /* Process not present */
1399 processlist_add(process_list,
1c736ed5 1400 drawing,
10a1069a 1401 pid_in,
348c6ba8 1402 process_in->cpu,
10a1069a 1403 process_in->ppid,
1404 &birth,
1405 tfc->t_context->index,
f4b88a7d 1406 process_in->name,
10a1069a 1407 &pl_height,
4e86ae2e 1408 &process_info,
10a1069a 1409 &hashed_process_data_in);
1c736ed5 1410 gtk_widget_set_size_request(drawing->drawing_area,
1411 -1,
1412 pl_height);
1413 gtk_widget_queue_draw(drawing->drawing_area);
b9a010a2 1414 }
40debf7b 1415 /* Set the current process */
348c6ba8 1416 process_list->current_hash_data[process_in->cpu] =
40debf7b 1417 hashed_process_data_in;
10a1069a 1418
b2743953 1419 if(ltt_time_compare(hashed_process_data_in->next_good_time,
1420 evtime) <= 0)
1421 {
fd22065b 1422 TimeWindow time_window =
1423 lttvwindow_get_time_window(control_flow_data->tab);
1424
1425#ifdef EXTRA_CHECK
1426 if(ltt_time_compare(evtime, time_window.start_time) == -1
1427 || ltt_time_compare(evtime, time_window.end_time) == 1)
1428 return;
1429#endif //EXTRA_CHECK
d6fef890 1430 Drawing_t *drawing = control_flow_data->drawing;
1431 guint width = drawing->width;
b2743953 1432 guint new_x;
1433
1434 convert_time_to_pixels(
1435 time_window,
1436 evtime,
1437 width,
1438 &new_x);
e72908ed 1439
b2743953 1440 if(hashed_process_data_in->x.middle != new_x) {
1441 hashed_process_data_in->x.middle = new_x;
1442 hashed_process_data_in->x.middle_used = FALSE;
1443 hashed_process_data_in->x.middle_marked = FALSE;
1444 }
1445 }
b9a010a2 1446 return 0;
1447
1448
1449
e72908ed 1450
1451
b9a010a2 1452#if 0
1453 EventsRequest *events_request = (EventsRequest*)hook_data;
1454 ControlFlowData *control_flow_data = events_request->viewer_data;
1455
1456 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
1457
1458 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
1459 LttvTraceState *ts =(LttvTraceState *)LTTV_TRACEFILE_CONTEXT(tfs)->t_context;
1460
a56a1ba4 1461
50439712 1462 LttEvent *e;
1463 e = tfc->e;
1464
9444deae 1465 LttTime evtime = ltt_event_time(e);
ca0f8a8e 1466 TimeWindow time_window =
1467 lttvwindow_get_time_window(control_flow_data->tab);
9444deae 1468
a2aab3a3 1469 LttTime time_window.end_time = time_window.time_window.end_time;
6f26fc38 1470
9444deae 1471 //if(time < time_beg || time > time_end) return;
ca0f8a8e 1472 if(ltt_time_compare(evtime, time_window.start_time) == -1
a2aab3a3 1473 || ltt_time_compare(evtime, time_window.end_time) == 1)
9444deae 1474 return;
1475
1476
a56a1ba4 1477 if(strcmp(ltt_eventtype_name(ltt_event_eventtype(e)),"schedchange") == 0)
1478 {
2a2fa4f0 1479 g_debug("schedchange!");
a56a1ba4 1480
1481 /* Add process to process list (if not present) and get drawing "y" from
1482 * process position */
1483 guint pid_out, pid_in;
1484 LttvProcessState *process_out, *process_in;
1485 LttTime birth;
1486 guint y_in = 0, y_out = 0, height = 0, pl_height = 0;
1487
5c230fc4 1488 ProcessList *process_list = control_flow_data->process_list;
a56a1ba4 1489
1490
1491 LttField *f = ltt_event_field(e);
1492 LttField *element;
1493 element = ltt_field_member(f,0);
1494 pid_out = ltt_event_get_long_unsigned(e,element);
1495 element = ltt_field_member(f,1);
1496 pid_in = ltt_event_get_long_unsigned(e,element);
2a2fa4f0 1497 //g_debug("out : %u in : %u", pid_out, pid_in);
a56a1ba4 1498
1499
1500 /* Find process pid_out in the list... */
2a2fa4f0 1501 process_out = lttv_state_find_process(tfs, pid_out);
1aff52a2 1502 if(process_out == NULL) return 0;
2a2fa4f0 1503 //g_debug("out : %s",g_quark_to_string(process_out->state->s));
a56a1ba4 1504
1505 birth = process_out->creation_time;
1506 gchar *name = strdup(g_quark_to_string(process_out->name));
14963be0 1507 HashedProcessData *hashed_process_data_out = NULL;
a56a1ba4 1508
1509 if(processlist_get_process_pixels(process_list,
1510 pid_out,
1511 &birth,
d0cd7f09 1512 tfc->t_context->index,
a56a1ba4 1513 &y_out,
1514 &height,
14963be0 1515 &hashed_process_data_out) == 1)
a56a1ba4 1516 {
51705146 1517 /* Process not present */
1518 processlist_add(process_list,
1519 pid_out,
1520 &birth,
1521 tfc->t_context->index,
1522 name,
1523 &pl_height,
1524 &hashed_process_data_out);
1525 processlist_get_process_pixels(process_list,
1526 pid_out,
1527 &birth,
1528 tfc->t_context->index,
1529 &y_out,
1530 &height,
1531 &hashed_process_data_out);
1532 drawing_insert_square( control_flow_data->drawing, y_out, height);
a56a1ba4 1533 }
1534
1535 g_free(name);
1536
1537 /* Find process pid_in in the list... */
2a2fa4f0 1538 process_in = lttv_state_find_process(tfs, pid_in);
1aff52a2 1539 if(process_in == NULL) return 0;
2a2fa4f0 1540 //g_debug("in : %s",g_quark_to_string(process_in->state->s));
a56a1ba4 1541
1542 birth = process_in->creation_time;
1543 name = strdup(g_quark_to_string(process_in->name));
14963be0 1544 HashedProcessData *hashed_process_data_in = NULL;
a56a1ba4 1545
1546 if(processlist_get_process_pixels(process_list,
1547 pid_in,
1548 &birth,
d0cd7f09 1549 tfc->t_context->index,
a56a1ba4 1550 &y_in,
1551 &height,
14963be0 1552 &hashed_process_data_in) == 1)
a56a1ba4 1553 {
1554 /* Process not present */
1555 processlist_add(process_list,
1556 pid_in,
1557 &birth,
d0cd7f09 1558 tfc->t_context->index,
a56a1ba4 1559 name,
1560 &pl_height,
14963be0 1561 &hashed_process_data_in);
a56a1ba4 1562 processlist_get_process_pixels(process_list,
1563 pid_in,
1564 &birth,
d0cd7f09 1565 tfc->t_context->index,
a56a1ba4 1566 &y_in,
1567 &height,
14963be0 1568 &hashed_process_data_in);
a56a1ba4 1569
ca0f8a8e 1570 drawing_insert_square( control_flow_data->drawing, y_in, height);
a56a1ba4 1571 }
1572 g_free(name);
1573
1574
1575 /* Find pixels corresponding to time of the event. If the time does
1576 * not fit in the window, show a warning, not supposed to happend. */
1577 //guint x = 0;
501d5405 1578 //guint width = control_flow_data->drawing->drawing_area->allocation.width;
a56a1ba4 1579
1580 //LttTime time = ltt_event_time(e);
1581
a2aab3a3 1582 //LttTime window_end = time_window->time_window.end_time;
a56a1ba4 1583
1584
1585 //convert_time_to_pixels(
a18124ff 1586 // *time_window,
a56a1ba4 1587 // time,
1588 // width,
1589 // &x);
1590
1591 //assert(x <= width);
1592
1593 /* draw what represents the event for outgoing process. */
1594
14963be0 1595 DrawContext *draw_context_out = hashed_process_data_out->draw_context;
68997a22 1596 //draw_context_out->current->modify_over->x = x;
1597 draw_context_out->current->modify_over->y = y_out;
319e9d81 1598 draw_context_out->current->modify_under->y = y_out+(height/2)+2;
501d5405 1599 draw_context_out->drawable = control_flow_data->drawing->pixmap;
1600 draw_context_out->pango_layout = control_flow_data->drawing->pango_layout;
1601 GtkWidget *widget = control_flow_data->drawing->drawing_area;
a56a1ba4 1602 //draw_context_out->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
d0cd7f09 1603
a56a1ba4 1604 //draw_arc((void*)&prop_arc, (void*)draw_context_out);
501d5405 1605 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
d0cd7f09 1606
1607 /*if(process_out->state->s == LTTV_STATE_RUN)
1608 {
1609 draw_context_out->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1610 gdk_gc_copy(draw_context_out->gc, widget->style->black_gc);
1611 PropertiesBG prop_bg;
1612 prop_bg.color = g_new(GdkColor,1);
1613
1614 prop_bg.color->red = 0xffff;
1615 prop_bg.color->green = 0xffff;
1616 prop_bg.color->blue = 0xffff;
1617
1618 draw_bg((void*)&prop_bg, (void*)draw_context_out);
1619 g_free(prop_bg.color);
1620 gdk_gc_unref(draw_context_out->gc);
1621 }*/
1622
1623 draw_context_out->gc = widget->style->black_gc;
1624
a56a1ba4 1625 GdkColor colorfg_out = { 0, 0xffff, 0x0000, 0x0000 };
2df6f2bd 1626 GdkColor colorbg_out = { 0, 0x0000, 0x0000, 0x0000 };
a56a1ba4 1627 PropertiesText prop_text_out;
1628 prop_text_out.foreground = &colorfg_out;
1629 prop_text_out.background = &colorbg_out;
cfe526b1 1630 prop_text_out.size = 6;
a56a1ba4 1631 prop_text_out.position = OVER;
1632
cfe526b1 1633 /* color of text : status of the process */
1634 if(process_out->state->s == LTTV_STATE_UNNAMED)
1635 {
1636 prop_text_out.foreground->red = 0xffff;
1637 prop_text_out.foreground->green = 0xffff;
1638 prop_text_out.foreground->blue = 0xffff;
1639 }
1640 else if(process_out->state->s == LTTV_STATE_WAIT_FORK)
1641 {
1642 prop_text_out.foreground->red = 0x0fff;
d52cfc84 1643 prop_text_out.foreground->green = 0xffff;
1644 prop_text_out.foreground->blue = 0xfff0;
cfe526b1 1645 }
1646 else if(process_out->state->s == LTTV_STATE_WAIT_CPU)
1647 {
2df6f2bd 1648 prop_text_out.foreground->red = 0xffff;
1649 prop_text_out.foreground->green = 0xffff;
cfe526b1 1650 prop_text_out.foreground->blue = 0x0000;
1651 }
0828099d 1652 else if(process_out->state->s == LTTV_STATE_ZOMBIE)
cfe526b1 1653 {
1654 prop_text_out.foreground->red = 0xffff;
1655 prop_text_out.foreground->green = 0x0000;
1656 prop_text_out.foreground->blue = 0xffff;
1657 }
1658 else if(process_out->state->s == LTTV_STATE_WAIT)
1659 {
1660 prop_text_out.foreground->red = 0xffff;
1661 prop_text_out.foreground->green = 0x0000;
1662 prop_text_out.foreground->blue = 0x0000;
1663 }
1664 else if(process_out->state->s == LTTV_STATE_RUN)
1665 {
1666 prop_text_out.foreground->red = 0x0000;
1667 prop_text_out.foreground->green = 0xffff;
1668 prop_text_out.foreground->blue = 0x0000;
1669 }
1670 else
1671 {
1672 prop_text_out.foreground->red = 0xffff;
1673 prop_text_out.foreground->green = 0xffff;
1674 prop_text_out.foreground->blue = 0xffff;
1675 }
1676
a56a1ba4 1677 /* Print status of the process : U, WF, WC, E, W, R */
1678 if(process_out->state->s == LTTV_STATE_UNNAMED)
68997a22 1679 prop_text_out.text = "U";
a56a1ba4 1680 else if(process_out->state->s == LTTV_STATE_WAIT_FORK)
68997a22 1681 prop_text_out.text = "WF";
a56a1ba4 1682 else if(process_out->state->s == LTTV_STATE_WAIT_CPU)
68997a22 1683 prop_text_out.text = "WC";
0828099d 1684 else if(process_out->state->s == LTTV_STATE_ZOMBIE)
68997a22 1685 prop_text_out.text = "E";
a56a1ba4 1686 else if(process_out->state->s == LTTV_STATE_WAIT)
68997a22 1687 prop_text_out.text = "W";
a56a1ba4 1688 else if(process_out->state->s == LTTV_STATE_RUN)
68997a22 1689 prop_text_out.text = "R";
a56a1ba4 1690 else
68997a22 1691 prop_text_out.text = "U";
a56a1ba4 1692
1693 draw_text((void*)&prop_text_out, (void*)draw_context_out);
d0cd7f09 1694
1695 //gdk_gc_unref(draw_context_out->gc);
319e9d81 1696
68997a22 1697 draw_context_out->current->middle->y = y_out+height/2;
d0cd7f09 1698 draw_context_out->current->over->y = y_out;
1699 draw_context_out->current->under->y = y_out+height;
68997a22 1700 draw_context_out->current->status = process_out->state->s;
a56a1ba4 1701
68997a22 1702 /* for pid_out : remove previous, Prev = current, new current (default) */
1703 g_free(draw_context_out->previous->modify_under);
1704 g_free(draw_context_out->previous->modify_middle);
1705 g_free(draw_context_out->previous->modify_over);
1706 g_free(draw_context_out->previous->under);
1707 g_free(draw_context_out->previous->middle);
1708 g_free(draw_context_out->previous->over);
1709 g_free(draw_context_out->previous);
1710
1711 draw_context_out->previous = draw_context_out->current;
a56a1ba4 1712
68997a22 1713 draw_context_out->current = g_new(DrawInfo,1);
1714 draw_context_out->current->over = g_new(ItemInfo,1);
1715 draw_context_out->current->over->x = -1;
1716 draw_context_out->current->over->y = -1;
1717 draw_context_out->current->middle = g_new(ItemInfo,1);
1718 draw_context_out->current->middle->x = -1;
1719 draw_context_out->current->middle->y = -1;
1720 draw_context_out->current->under = g_new(ItemInfo,1);
1721 draw_context_out->current->under->x = -1;
1722 draw_context_out->current->under->y = -1;
1723 draw_context_out->current->modify_over = g_new(ItemInfo,1);
1724 draw_context_out->current->modify_over->x = -1;
1725 draw_context_out->current->modify_over->y = -1;
1726 draw_context_out->current->modify_middle = g_new(ItemInfo,1);
1727 draw_context_out->current->modify_middle->x = -1;
1728 draw_context_out->current->modify_middle->y = -1;
1729 draw_context_out->current->modify_under = g_new(ItemInfo,1);
1730 draw_context_out->current->modify_under->x = -1;
1731 draw_context_out->current->modify_under->y = -1;
1732 draw_context_out->current->status = LTTV_STATE_UNNAMED;
a56a1ba4 1733
1734 /* Finally, update the drawing context of the pid_in. */
1735
14963be0 1736 DrawContext *draw_context_in = hashed_process_data_in->draw_context;
68997a22 1737 //draw_context_in->current->modify_over->x = x;
1738 draw_context_in->current->modify_over->y = y_in;
319e9d81 1739 draw_context_in->current->modify_under->y = y_in+(height/2)+2;
501d5405 1740 draw_context_in->drawable = control_flow_data->drawing->pixmap;
1741 draw_context_in->pango_layout = control_flow_data->drawing->pango_layout;
1742 widget = control_flow_data->drawing->drawing_area;
a56a1ba4 1743 //draw_context_in->gc = widget->style->fg_gc[GTK_WIDGET_STATE (widget)];
a56a1ba4 1744
1745 //draw_arc((void*)&prop_arc, (void*)draw_context_in);
501d5405 1746 //test_draw_item(control_flow_data->drawing, control_flow_data->drawing->pixmap);
d0cd7f09 1747
1748 /*if(process_in->state->s == LTTV_STATE_RUN)
1749 {
1750 draw_context_in->gc = gdk_gc_new(control_flow_data->drawing->pixmap);
1751 gdk_gc_copy(draw_context_in->gc, widget->style->black_gc);
1752 PropertiesBG prop_bg;
1753 prop_bg.color = g_new(GdkColor,1);
1754
1755 prop_bg.color->red = 0xffff;
1756 prop_bg.color->green = 0xffff;
1757 prop_bg.color->blue = 0xffff;
1758
1759 draw_bg((void*)&prop_bg, (void*)draw_context_in);
1760 g_free(prop_bg.color);
1761 gdk_gc_unref(draw_context_in->gc);
1762 }*/
1763
1764 draw_context_in->gc = widget->style->black_gc;
1765
a56a1ba4 1766 GdkColor colorfg_in = { 0, 0x0000, 0xffff, 0x0000 };
2df6f2bd 1767 GdkColor colorbg_in = { 0, 0x0000, 0x0000, 0x0000 };
a56a1ba4 1768 PropertiesText prop_text_in;
1769 prop_text_in.foreground = &colorfg_in;
1770 prop_text_in.background = &colorbg_in;
cfe526b1 1771 prop_text_in.size = 6;
a56a1ba4 1772 prop_text_in.position = OVER;
1773
cfe526b1 1774 /* foreground of text : status of the process */
1775 if(process_in->state->s == LTTV_STATE_UNNAMED)
1776 {
1777 prop_text_in.foreground->red = 0xffff;
1778 prop_text_in.foreground->green = 0xffff;
1779 prop_text_in.foreground->blue = 0xffff;
1780 }
1781 else if(process_in->state->s == LTTV_STATE_WAIT_FORK)
1782 {
1783 prop_text_in.foreground->red = 0x0fff;
d52cfc84 1784 prop_text_in.foreground->green = 0xffff;
1785 prop_text_in.foreground->blue = 0xfff0;
cfe526b1 1786 }
1787 else if(process_in->state->s == LTTV_STATE_WAIT_CPU)
1788 {
2df6f2bd 1789 prop_text_in.foreground->red = 0xffff;
1790 prop_text_in.foreground->green = 0xffff;
cfe526b1 1791 prop_text_in.foreground->blue = 0x0000;
1792 }
0828099d 1793 else if(process_in->state->s == LTTV_STATE_ZOMBIE)
cfe526b1 1794 {
1795 prop_text_in.foreground->red = 0xffff;
1796 prop_text_in.foreground->green = 0x0000;
1797 prop_text_in.foreground->blue = 0xffff;
1798 }
1799 else if(process_in->state->s == LTTV_STATE_WAIT)
1800 {
1801 prop_text_in.foreground->red = 0xffff;
1802 prop_text_in.foreground->green = 0x0000;
1803 prop_text_in.foreground->blue = 0x0000;
1804 }
1805 else if(process_in->state->s == LTTV_STATE_RUN)
1806 {
1807 prop_text_in.foreground->red = 0x0000;
1808 prop_text_in.foreground->green = 0xffff;
1809 prop_text_in.foreground->blue = 0x0000;
1810 }
1811 else
1812 {
1813 prop_text_in.foreground->red = 0xffff;
1814 prop_text_in.foreground->green = 0xffff;
1815 prop_text_in.foreground->blue = 0xffff;
1816 }
1817
1818
a56a1ba4 1819 /* Print status of the process : U, WF, WC, E, W, R */
1820 if(process_in->state->s == LTTV_STATE_UNNAMED)
68997a22 1821 prop_text_in.text = "U";
a56a1ba4 1822 else if(process_in->state->s == LTTV_STATE_WAIT_FORK)
68997a22 1823 prop_text_in.text = "WF";
a56a1ba4 1824 else if(process_in->state->s == LTTV_STATE_WAIT_CPU)
68997a22 1825 prop_text_in.text = "WC";
0828099d 1826 else if(process_in->state->s == LTTV_STATE_ZOMBIE)
68997a22 1827 prop_text_in.text = "E";
a56a1ba4 1828 else if(process_in->state->s == LTTV_STATE_WAIT)
68997a22 1829 prop_text_in.text = "W";
a56a1ba4 1830 else if(process_in->state->s == LTTV_STATE_RUN)
68997a22 1831 prop_text_in.text = "R";
a56a1ba4 1832 else
68997a22 1833 prop_text_in.text = "U";
a56a1ba4 1834
1835 draw_text((void*)&prop_text_in, (void*)draw_context_in);
1836
d0cd7f09 1837
319e9d81 1838 if(process_in->state->s == LTTV_STATE_RUN)
1839 {
1840 gchar tmp[255];
1841 prop_text_in.foreground = &colorfg_in;
1842 prop_text_in.background = &colorbg_in;
1843 prop_text_in.foreground->red = 0xffff;
1844 prop_text_in.foreground->green = 0xffff;
1845 prop_text_in.foreground->blue = 0xffff;
1846 prop_text_in.size = 6;
1847 prop_text_in.position = UNDER;
1848
1849 prop_text_in.text = g_new(gchar, 260);
1850 strcpy(prop_text_in.text, "CPU ");
2c82c4dc 1851 snprintf(tmp, 255, "%u", ltt_tracefile_num(tfc->tf));
319e9d81 1852 strcat(prop_text_in.text, tmp);
1853
1854 draw_text((void*)&prop_text_in, (void*)draw_context_in);
1855 g_free(prop_text_in.text);
1856 }
1857
1858
68997a22 1859 draw_context_in->current->middle->y = y_in+height/2;
d0cd7f09 1860 draw_context_in->current->over->y = y_in;
1861 draw_context_in->current->under->y = y_in+height;
68997a22 1862 draw_context_in->current->status = process_in->state->s;
1863
1864 /* for pid_in : remove previous, Prev = current, new current (default) */
1865 g_free(draw_context_in->previous->modify_under);
1866 g_free(draw_context_in->previous->modify_middle);
1867 g_free(draw_context_in->previous->modify_over);
1868 g_free(draw_context_in->previous->under);
1869 g_free(draw_context_in->previous->middle);
1870 g_free(draw_context_in->previous->over);
1871 g_free(draw_context_in->previous);
1872
1873 draw_context_in->previous = draw_context_in->current;
a56a1ba4 1874
68997a22 1875 draw_context_in->current = g_new(DrawInfo,1);
1876 draw_context_in->current->over = g_new(ItemInfo,1);
1877 draw_context_in->current->over->x = -1;
1878 draw_context_in->current->over->y = -1;
1879 draw_context_in->current->middle = g_new(ItemInfo,1);
1880 draw_context_in->current->middle->x = -1;
1881 draw_context_in->current->middle->y = -1;
1882 draw_context_in->current->under = g_new(ItemInfo,1);
1883 draw_context_in->current->under->x = -1;
1884 draw_context_in->current->under->y = -1;
1885 draw_context_in->current->modify_over = g_new(ItemInfo,1);
1886 draw_context_in->current->modify_over->x = -1;
1887 draw_context_in->current->modify_over->y = -1;
1888 draw_context_in->current->modify_middle = g_new(ItemInfo,1);
1889 draw_context_in->current->modify_middle->x = -1;
1890 draw_context_in->current->modify_middle->y = -1;
1891 draw_context_in->current->modify_under = g_new(ItemInfo,1);
1892 draw_context_in->current->modify_under->x = -1;
1893 draw_context_in->current->modify_under->y = -1;
1894 draw_context_in->current->status = LTTV_STATE_UNNAMED;
a56a1ba4 1895
1896 }
1897
1898 return 0;
b9a010a2 1899#endif //0
f0d936c0 1900}
f7afe191 1901
9a1ec01b 1902#if 0
6550d711 1903static inline PropertiesLine prepare_execmode_line(LttvProcessState *process)
23093869 1904{
1905 PropertiesLine prop_line;
1906 prop_line.line_width = 1;
1907 prop_line.style = GDK_LINE_SOLID;
1908 prop_line.y = OVER;
1909 //GdkColormap *colormap = gdk_colormap_get_system();
1910
1911 /* color of line : execution mode of the process */
1912 if(process->state->t == LTTV_STATE_USER_MODE)
1913 prop_line.color = drawing_colors[COL_USER_MODE];
1914 else if(process->state->t == LTTV_STATE_SYSCALL)
1915 prop_line.color = drawing_colors[COL_SYSCALL];
1916 else if(process->state->t == LTTV_STATE_TRAP)
1917 prop_line.color = drawing_colors[COL_TRAP];
1918 else if(process->state->t == LTTV_STATE_IRQ)
1919 prop_line.color = drawing_colors[COL_IRQ];
1920 else if(process->state->t == LTTV_STATE_MODE_UNKNOWN)
1921 prop_line.color = drawing_colors[COL_MODE_UNKNOWN];
1922 else
1923 prop_line.color = drawing_colors[COL_WHITE];
1924
1925 //gdk_colormap_alloc_color(colormap,
1926 // prop_line.color,
1927 // FALSE,
1928 // TRUE);
1929
1930 return prop_line;
1931
1932}
9a1ec01b 1933#endif //0
23093869 1934
1935
1936/* before_execmode_hook
1937 *
1938 * This function basically draw lines and icons. Two types of lines are drawn :
1939 * one small (3 pixels?) representing the state of the process and the second
1940 * type is thicker (10 pixels?) representing on which CPU a process is running
1941 * (and this only in running state).
1942 *
1943 * Extremums of the lines :
1944 * x_min : time of the last event context for this process kept in memory.
1945 * x_max : time of the current event.
1946 * y : middle of the process in the process list. The process is found in the
1947 * list, therefore is it's position in pixels.
1948 *
1949 * The choice of lines'color is defined by the context of the last event for this
1950 * process.
1951 */
1952
1953
1954int before_execmode_hook(void *hook_data, void *call_data)
1955{
2c82c4dc 1956 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
1957 EventsRequest *events_request = (EventsRequest*)thf->hook_data;
23093869 1958 ControlFlowData *control_flow_data = events_request->viewer_data;
23093869 1959
1960 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
1961
1962 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
23093869 1963
348c6ba8 1964 LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
1965
23093869 1966 LttEvent *e;
2c82c4dc 1967 e = ltt_tracefile_get_event(tfc->tf);
23093869 1968
1969 LttTime evtime = ltt_event_time(e);
23093869 1970
10a1069a 1971 /* we are in a execmode, before the state update. We must draw the
1972 * items corresponding to the state before it changes : now is the right
1973 * time to do it.
1974 */
1975 /* For the pid */
348c6ba8 1976 //LttvProcessState *process = tfs->process;
1977 guint cpu = ltt_tracefile_num(tfc->tf);
1978 LttvProcessState *process = ts->running_process[cpu];
10a1069a 1979 g_assert(process != NULL);
23093869 1980
10a1069a 1981 guint pid = process->pid;
23093869 1982
10a1069a 1983 /* Well, the process_out existed : we must get it in the process hash
1984 * or add it, and draw its items.
1985 */
1986 /* Add process to process list (if not present) */
1c736ed5 1987 guint pl_height = 0;
10a1069a 1988 HashedProcessData *hashed_process_data = NULL;
5c230fc4 1989 ProcessList *process_list = control_flow_data->process_list;
10a1069a 1990 LttTime birth = process->creation_time;
40debf7b 1991
348c6ba8 1992 if(likely(process_list->current_hash_data[cpu] != NULL)) {
1993 hashed_process_data = process_list->current_hash_data[cpu];
40debf7b 1994 } else {
ac4e21cf 1995 hashed_process_data = processlist_get_process_data(process_list,
40debf7b 1996 pid,
348c6ba8 1997 process->cpu,
40debf7b 1998 &birth,
ac4e21cf 1999 tfc->t_context->index);
1d1df11d 2000 if(unlikely(hashed_process_data == NULL))
40debf7b 2001 {
2002 g_assert(pid == 0 || pid != process->ppid);
2003 ProcessInfo *process_info;
2004 /* Process not present */
1c736ed5 2005 Drawing_t *drawing = control_flow_data->drawing;
40debf7b 2006 processlist_add(process_list,
1c736ed5 2007 drawing,
40debf7b 2008 pid,
348c6ba8 2009 process->cpu,
40debf7b 2010 process->ppid,
2011 &birth,
2012 tfc->t_context->index,
f4b88a7d 2013 process->name,
40debf7b 2014 &pl_height,
2015 &process_info,
2016 &hashed_process_data);
1c736ed5 2017 gtk_widget_set_size_request(drawing->drawing_area,
2018 -1,
2019 pl_height);
2020 gtk_widget_queue_draw(drawing->drawing_area);
40debf7b 2021 }
2022 /* Set the current process */
348c6ba8 2023 process_list->current_hash_data[process->cpu] =
40debf7b 2024 hashed_process_data;
10a1069a 2025 }
23093869 2026
10a1069a 2027 /* Now, the process is in the state hash and our own process hash.
2028 * We definitely can draw the items related to the ending state.
2029 */
b2743953 2030
1d1df11d 2031 if(likely(ltt_time_compare(hashed_process_data->next_good_time,
2032 evtime) > 0))
10a1069a 2033 {
1d1df11d 2034 if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
fd22065b 2035 TimeWindow time_window =
2036 lttvwindow_get_time_window(control_flow_data->tab);
2037
2038#ifdef EXTRA_CHECK
2039 if(ltt_time_compare(evtime, time_window.start_time) == -1
2040 || ltt_time_compare(evtime, time_window.end_time) == 1)
2041 return;
2042#endif //EXTRA_CHECK
d6fef890 2043 Drawing_t *drawing = control_flow_data->drawing;
96947fcf 2044 guint width = drawing->width;
b2743953 2045 guint x;
2046 convert_time_to_pixels(
2047 time_window,
2048 evtime,
2049 width,
2050 &x);
2051
2052 /* Draw collision indicator */
2053 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
1c736ed5 2054 gdk_draw_point(hashed_process_data->pixmap,
b2743953 2055 drawing->gc,
2056 x,
1c736ed5 2057 (hashed_process_data->height/2)-3);
b2743953 2058 hashed_process_data->x.middle_marked = TRUE;
2059 }
2060 } else {
fd22065b 2061 TimeWindow time_window =
2062 lttvwindow_get_time_window(control_flow_data->tab);
2063
2064#ifdef EXTRA_CHECK
2065 if(ltt_time_compare(evtime, time_window.start_time) == -1
2066 || ltt_time_compare(evtime, time_window.end_time) == 1)
2067 return;
2068#endif //EXTRA_CHECK
d6fef890 2069 Drawing_t *drawing = control_flow_data->drawing;
96947fcf 2070 guint width = drawing->width;
10a1069a 2071 guint x;
dbd243b1 2072
10a1069a 2073 convert_time_to_pixels(
a18124ff 2074 time_window,
10a1069a 2075 evtime,
2076 width,
2077 &x);
dbd243b1 2078
23093869 2079
4b7dc462 2080 /* Jump over draw if we are at the same x position */
1d1df11d 2081 if(unlikely(x == hashed_process_data->x.middle &&
2082 hashed_process_data->x.middle_used))
10a1069a 2083 {
1d1df11d 2084 if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
e72908ed 2085 /* Draw collision indicator */
2086 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
1c736ed5 2087 gdk_draw_point(hashed_process_data->pixmap,
e72908ed 2088 drawing->gc,
2089 x,
1c736ed5 2090 (hashed_process_data->height/2)-3);
de4ea1ad 2091 hashed_process_data->x.middle_marked = TRUE;
e72908ed 2092 }
4b7dc462 2093 /* jump */
2094 } else {
2095
2096 DrawContext draw_context;
2097 /* Now create the drawing context that will be used to draw
2098 * items related to the last state. */
1c736ed5 2099 draw_context.drawable = hashed_process_data->pixmap;
4b7dc462 2100 draw_context.gc = drawing->gc;
2101 draw_context.pango_layout = drawing->pango_layout;
9a1ec01b 2102 draw_context.drawinfo.start.x = hashed_process_data->x.middle;
4b7dc462 2103 draw_context.drawinfo.end.x = x;
2104
1c736ed5 2105 draw_context.drawinfo.y.over = 1;
2106 draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
2107 draw_context.drawinfo.y.under = hashed_process_data->height;
4b7dc462 2108
2109 draw_context.drawinfo.start.offset.over = 0;
2110 draw_context.drawinfo.start.offset.middle = 0;
2111 draw_context.drawinfo.start.offset.under = 0;
2112 draw_context.drawinfo.end.offset.over = 0;
2113 draw_context.drawinfo.end.offset.middle = 0;
2114 draw_context.drawinfo.end.offset.under = 0;
2115
2116 {
2117 /* Draw the line */
9a1ec01b 2118 PropertiesLine prop_line = prepare_s_e_line(process);
4b7dc462 2119 draw_line((void*)&prop_line, (void*)&draw_context);
23093869 2120
4b7dc462 2121 }
2122 /* become the last x position */
9a1ec01b 2123 hashed_process_data->x.middle = x;
e72908ed 2124 hashed_process_data->x.middle_used = TRUE;
2125 hashed_process_data->x.middle_marked = FALSE;
b2743953 2126
2127 /* Calculate the next good time */
2128 convert_pixels_to_time(width, x+1, time_window,
2129 &hashed_process_data->next_good_time);
23093869 2130 }
2131 }
2132
2133 return 0;
2134}
2135
2136/* after_execmode_hook
2137 *
2138 * The draw after hook is called by the reading API to have a
2139 * particular event drawn on the screen.
2140 * @param hook_data ControlFlowData structure of the viewer.
2141 * @param call_data Event context.
2142 *
2143 * This function adds items to be drawn in a queue for each process.
2144 *
2145 */
348c6ba8 2146#if 0
23093869 2147int after_execmode_hook(void *hook_data, void *call_data)
2148{
8869ac08 2149 /**************** DOES NOTHING!! *************/
2150 /* hook desactivated in drawing.c */
2151 return 0;
2152
2153
2c82c4dc 2154 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
2155 EventsRequest *events_request = (EventsRequest*)thf->hook_data;
23093869 2156 ControlFlowData *control_flow_data = events_request->viewer_data;
2157
2158 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
2159
2160 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
23093869 2161
2162 LttEvent *e;
2c82c4dc 2163 e = ltt_tracefile_get_event(tfc->tf);
23093869 2164
2165 LttTime evtime = ltt_event_time(e);
23093869 2166
10a1069a 2167 /* Add process to process list (if not present) */
2168 LttvProcessState *process;
2169 LttTime birth;
1c736ed5 2170 guint pl_height = 0;
10a1069a 2171 HashedProcessData *hashed_process_data = NULL;
23093869 2172
5c230fc4 2173 ProcessList *process_list = control_flow_data->process_list;
23093869 2174
10a1069a 2175 /* Find process pid_in in the list... */
2176 process = tfs->process;
2177 /* It should exist, because we are after the state update. */
2178 g_assert(process != NULL);
23093869 2179
10a1069a 2180 guint pid = process->pid;
23093869 2181
10a1069a 2182 birth = process->creation_time;
23093869 2183
2c82c4dc 2184 if(likely(process_list->current_hash_data[ltt_tracefile_num(tfc->tf)] != NULL)) {
2185 hashed_process_data = process_list->current_hash_data[ltt_tracefile_num(tfc->tf)];
40debf7b 2186 } else {
ac4e21cf 2187 hashed_process_data = processlist_get_process_data(process_list,
40debf7b 2188 pid,
2189 process->last_cpu_index,
2190 &birth,
ac4e21cf 2191 tfc->t_context->index);
1d1df11d 2192 if(unlikely(hashed_process_data == NULL))
40debf7b 2193 {
2194 g_assert(pid == 0 || pid != process->ppid);
2195 /* Process not present */
1c736ed5 2196 Drawing_t *drawing = control_flow_data->drawing;
40debf7b 2197 const gchar *name = g_quark_to_string(process->name);
2198 ProcessInfo *process_info;
2199 processlist_add(process_list,
1c736ed5 2200 drawing,
40debf7b 2201 pid,
2202 process->last_cpu_index,
2203 process->ppid,
2204 &birth,
2205 tfc->t_context->index,
2206 name,
2207 &pl_height,
2208 &process_info,
2209 &hashed_process_data);
1c736ed5 2210 gtk_widget_set_size_request(drawing->drawing_area,
2211 -1,
2212 pl_height);
2213 gtk_widget_queue_draw(drawing->drawing_area);
40debf7b 2214 }
2215 /* Set the current process */
2216 process_list->current_hash_data[process->last_cpu_index] =
2217 hashed_process_data;
23093869 2218 }
40debf7b 2219
1d1df11d 2220 if(unlikely(ltt_time_compare(hashed_process_data->next_good_time,
2221 evtime) <= 0))
b2743953 2222 {
fd22065b 2223 TimeWindow time_window =
2224 lttvwindow_get_time_window(control_flow_data->tab);
2225
2226#ifdef EXTRA_CHECK
2227 if(ltt_time_compare(evtime, time_window.start_time) == -1
2228 || ltt_time_compare(evtime, time_window.end_time) == 1)
2229 return;
2230#endif //EXTRA_CHECK
d6fef890 2231 Drawing_t *drawing = control_flow_data->drawing;
2232 guint width = drawing->width;
b2743953 2233 guint new_x;
2234
2235 convert_time_to_pixels(
2236 time_window,
2237 evtime,
2238 width,
2239 &new_x);
e72908ed 2240
b2743953 2241 if(hashed_process_data->x.middle != new_x) {
2242 hashed_process_data->x.middle = new_x;
2243 hashed_process_data->x.middle_used = FALSE;
2244 hashed_process_data->x.middle_marked = FALSE;
2245 }
2246 }
23093869 2247 return 0;
2248}
348c6ba8 2249#endif //0
23093869 2250
dbd243b1 2251
2c82c4dc 2252
2253/* before_process_exit_hook
dbd243b1 2254 *
2255 * Draw lines for process event.
2256 *
2257 * @param hook_data ControlFlowData structure of the viewer.
2258 * @param call_data Event context.
2259 *
2260 * This function adds items to be drawn in a queue for each process.
2261 *
2262 */
2c82c4dc 2263
2264
2265int before_process_exit_hook(void *hook_data, void *call_data)
dbd243b1 2266{
2c82c4dc 2267 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
2268 EventsRequest *events_request = (EventsRequest*)thf->hook_data;
2269
dbd243b1 2270 ControlFlowData *control_flow_data = events_request->viewer_data;
dbd243b1 2271
2272 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
2273
2274 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
dbd243b1 2275
348c6ba8 2276 LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
2277
dbd243b1 2278 LttEvent *e;
2c82c4dc 2279 e = ltt_tracefile_get_event(tfc->tf);
dbd243b1 2280
2281 LttTime evtime = ltt_event_time(e);
dbd243b1 2282
2c82c4dc 2283 /* Add process to process list (if not present) */
348c6ba8 2284 //LttvProcessState *process = tfs->process;
2285 guint cpu = ltt_tracefile_num(tfc->tf);
2286 LttvProcessState *process = ts->running_process[cpu];
2c82c4dc 2287 guint pid = process->pid;
2288 LttTime birth;
2289 guint pl_height = 0;
2290 HashedProcessData *hashed_process_data = NULL;
dbd243b1 2291
2c82c4dc 2292 ProcessList *process_list = control_flow_data->process_list;
2293
2294 g_assert(process != NULL);
dbd243b1 2295
2c82c4dc 2296 birth = process->creation_time;
dbd243b1 2297
348c6ba8 2298 if(likely(process_list->current_hash_data[cpu] != NULL)) {
2299 hashed_process_data = process_list->current_hash_data[cpu];
2c82c4dc 2300 } else {
2301 hashed_process_data = processlist_get_process_data(process_list,
2302 pid,
348c6ba8 2303 process->cpu,
2c82c4dc 2304 &birth,
2305 tfc->t_context->index);
2306 if(unlikely(hashed_process_data == NULL))
2307 {
2308 g_assert(pid == 0 || pid != process->ppid);
2309 /* Process not present */
2310 Drawing_t *drawing = control_flow_data->drawing;
2c82c4dc 2311 ProcessInfo *process_info;
2312 processlist_add(process_list,
2313 drawing,
2314 pid,
348c6ba8 2315 process->cpu,
2c82c4dc 2316 process->ppid,
2317 &birth,
2318 tfc->t_context->index,
f4b88a7d 2319 process->name,
2c82c4dc 2320 &pl_height,
2321 &process_info,
2322 &hashed_process_data);
2323 gtk_widget_set_size_request(drawing->drawing_area,
2324 -1,
2325 pl_height);
2326 gtk_widget_queue_draw(drawing->drawing_area);
2327 }
2328 }
dbd243b1 2329
2c82c4dc 2330 /* Now, the process is in the state hash and our own process hash.
2331 * We definitely can draw the items related to the ending state.
2332 */
2333
2334 if(likely(ltt_time_compare(hashed_process_data->next_good_time,
2335 evtime) > 0))
2336 {
2337 if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
2338 TimeWindow time_window =
2339 lttvwindow_get_time_window(control_flow_data->tab);
dbd243b1 2340
2c82c4dc 2341#ifdef EXTRA_CHECK
2342 if(ltt_time_compare(evtime, time_window.start_time) == -1
2343 || ltt_time_compare(evtime, time_window.end_time) == 1)
2344 return;
2345#endif //EXTRA_CHECK
2346 Drawing_t *drawing = control_flow_data->drawing;
2347 guint width = drawing->width;
2348 guint x;
2349 convert_time_to_pixels(
2350 time_window,
2351 evtime,
2352 width,
2353 &x);
dbd243b1 2354
2c82c4dc 2355 /* Draw collision indicator */
2356 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
2357 gdk_draw_point(hashed_process_data->pixmap,
2358 drawing->gc,
2359 x,
2360 (hashed_process_data->height/2)-3);
2361 hashed_process_data->x.middle_marked = TRUE;
2362 }
2363 } else {
2364 TimeWindow time_window =
2365 lttvwindow_get_time_window(control_flow_data->tab);
fd22065b 2366
2367#ifdef EXTRA_CHECK
2c82c4dc 2368 if(ltt_time_compare(evtime, time_window.start_time) == -1
2369 || ltt_time_compare(evtime, time_window.end_time) == 1)
2370 return;
fd22065b 2371#endif //EXTRA_CHECK
2c82c4dc 2372 Drawing_t *drawing = control_flow_data->drawing;
2373 guint width = drawing->width;
2374 guint x;
2375
2376 convert_time_to_pixels(
2377 time_window,
2378 evtime,
2379 width,
2380 &x);
2381
b2743953 2382
2c82c4dc 2383 /* Jump over draw if we are at the same x position */
2384 if(unlikely(x == hashed_process_data->x.middle &&
2385 hashed_process_data->x.middle_used))
2386 {
2387 if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
b2743953 2388 /* Draw collision indicator */
2389 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
1c736ed5 2390 gdk_draw_point(hashed_process_data->pixmap,
b2743953 2391 drawing->gc,
2392 x,
1c736ed5 2393 (hashed_process_data->height/2)-3);
b2743953 2394 hashed_process_data->x.middle_marked = TRUE;
2395 }
2c82c4dc 2396 /* jump */
b2743953 2397 } else {
2c82c4dc 2398 DrawContext draw_context;
fd22065b 2399
2c82c4dc 2400 /* Now create the drawing context that will be used to draw
2401 * items related to the last state. */
2402 draw_context.drawable = hashed_process_data->pixmap;
2403 draw_context.gc = drawing->gc;
2404 draw_context.pango_layout = drawing->pango_layout;
2405 draw_context.drawinfo.start.x = hashed_process_data->x.middle;
2406 draw_context.drawinfo.end.x = x;
dbd243b1 2407
2c82c4dc 2408 draw_context.drawinfo.y.over = 1;
2409 draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
2410 draw_context.drawinfo.y.under = hashed_process_data->height;
dbd243b1 2411
2c82c4dc 2412 draw_context.drawinfo.start.offset.over = 0;
2413 draw_context.drawinfo.start.offset.middle = 0;
2414 draw_context.drawinfo.start.offset.under = 0;
2415 draw_context.drawinfo.end.offset.over = 0;
2416 draw_context.drawinfo.end.offset.middle = 0;
2417 draw_context.drawinfo.end.offset.under = 0;
dbd243b1 2418
2c82c4dc 2419 {
2420 /* Draw the line */
2421 PropertiesLine prop_line = prepare_s_e_line(process);
2422 draw_line((void*)&prop_line, (void*)&draw_context);
dbd243b1 2423
2c82c4dc 2424 }
2425 /* become the last x position */
2426 hashed_process_data->x.middle = x;
2427 hashed_process_data->x.middle_used = TRUE;
2428 hashed_process_data->x.middle_marked = FALSE;
dbd243b1 2429
2c82c4dc 2430 /* Calculate the next good time */
2431 convert_pixels_to_time(width, x+1, time_window,
2432 &hashed_process_data->next_good_time);
2433 }
2434 }
2435
2436 return 0;
2437
2438}
2439
2440
2441
2442/* before_process_release_hook
2443 *
2444 * Draw lines for process event.
2445 *
2446 * @param hook_data ControlFlowData structure of the viewer.
2447 * @param call_data Event context.
2448 *
2449 * This function adds items to be drawn in a queue for each process.
2450 *
2451 */
2452
2453
2454int before_process_release_hook(void *hook_data, void *call_data)
2455{
2456 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
2457 EventsRequest *events_request = (EventsRequest*)thf->hook_data;
2458
2459 ControlFlowData *control_flow_data = events_request->viewer_data;
2460
2461 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
2462
2463 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
2464
348c6ba8 2465 LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
2466
2c82c4dc 2467 LttEvent *e;
2468 e = ltt_tracefile_get_event(tfc->tf);
2469
2470 LttTime evtime = ltt_event_time(e);
2471
2472
2473 guint pid;
2474 {
2475 pid = ltt_event_get_long_unsigned(e, thf->f1);
2476 }
2477
2478 /* Add process to process list (if not present) */
2479 /* Don't care about the process if it's not in the state hash already :
2480 * that means a process that has never done anything in the trace and
2481 * unknown suddently gets destroyed : no state meaningful to show. */
348c6ba8 2482 LttvProcessState *process = lttv_state_find_process(ts, ANY_CPU, pid);
2c82c4dc 2483
2484 if(process != NULL) {
2485 LttTime birth;
2486 guint pl_height = 0;
2487 HashedProcessData *hashed_process_data = NULL;
2488
2489 ProcessList *process_list = control_flow_data->process_list;
2490
2491 birth = process->creation_time;
2492
2493 /* Cannot use current process : this event happens on another process,
2494 * action done by the parent. */
2495 hashed_process_data = processlist_get_process_data(process_list,
2496 pid,
348c6ba8 2497 process->cpu,
2c82c4dc 2498 &birth,
2499 tfc->t_context->index);
2500 if(unlikely(hashed_process_data == NULL))
2501 {
2502 g_assert(pid == 0 || pid != process->ppid);
2503 /* Process not present */
2504 Drawing_t *drawing = control_flow_data->drawing;
2c82c4dc 2505 ProcessInfo *process_info;
2506 processlist_add(process_list,
2507 drawing,
2508 pid,
348c6ba8 2509 process->cpu,
2c82c4dc 2510 process->ppid,
2511 &birth,
2512 tfc->t_context->index,
f4b88a7d 2513 process->name,
2c82c4dc 2514 &pl_height,
2515 &process_info,
2516 &hashed_process_data);
2517 gtk_widget_set_size_request(drawing->drawing_area,
2518 -1,
2519 pl_height);
2520 gtk_widget_queue_draw(drawing->drawing_area);
2521 }
2522
2523 /* Now, the process is in the state hash and our own process hash.
2524 * We definitely can draw the items related to the ending state.
2525 */
2526
2527 if(likely(ltt_time_compare(hashed_process_data->next_good_time,
2528 evtime) > 0))
2529 {
2530 if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
2531 TimeWindow time_window =
2532 lttvwindow_get_time_window(control_flow_data->tab);
2533
2534#ifdef EXTRA_CHECK
2535 if(ltt_time_compare(evtime, time_window.start_time) == -1
2536 || ltt_time_compare(evtime, time_window.end_time) == 1)
2537 return;
2538#endif //EXTRA_CHECK
2539 Drawing_t *drawing = control_flow_data->drawing;
2540 guint width = drawing->width;
2541 guint x;
2542 convert_time_to_pixels(
2543 time_window,
2544 evtime,
2545 width,
2546 &x);
2547
2548 /* Draw collision indicator */
2549 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
2550 gdk_draw_point(hashed_process_data->pixmap,
2551 drawing->gc,
2552 x,
2553 (hashed_process_data->height/2)-3);
2554 hashed_process_data->x.middle_marked = TRUE;
2555 }
2556 } else {
2557 TimeWindow time_window =
2558 lttvwindow_get_time_window(control_flow_data->tab);
2559
2560#ifdef EXTRA_CHECK
2561 if(ltt_time_compare(evtime, time_window.start_time) == -1
2562 || ltt_time_compare(evtime, time_window.end_time) == 1)
2563 return;
2564#endif //EXTRA_CHECK
2565 Drawing_t *drawing = control_flow_data->drawing;
2566 guint width = drawing->width;
2567 guint x;
2568
2569 convert_time_to_pixels(
2570 time_window,
2571 evtime,
2572 width,
2573 &x);
2574
2575
2576 /* Jump over draw if we are at the same x position */
2577 if(unlikely(x == hashed_process_data->x.middle &&
2578 hashed_process_data->x.middle_used))
2579 {
2580 if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
2581 /* Draw collision indicator */
2582 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
2583 gdk_draw_point(hashed_process_data->pixmap,
2584 drawing->gc,
2585 x,
2586 (hashed_process_data->height/2)-3);
2587 hashed_process_data->x.middle_marked = TRUE;
2588 }
2589 /* jump */
2590 } else {
2591 DrawContext draw_context;
2592
2593 /* Now create the drawing context that will be used to draw
2594 * items related to the last state. */
2595 draw_context.drawable = hashed_process_data->pixmap;
2596 draw_context.gc = drawing->gc;
2597 draw_context.pango_layout = drawing->pango_layout;
2598 draw_context.drawinfo.start.x = hashed_process_data->x.middle;
2599 draw_context.drawinfo.end.x = x;
2600
2601 draw_context.drawinfo.y.over = 1;
2602 draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
2603 draw_context.drawinfo.y.under = hashed_process_data->height;
2604
2605 draw_context.drawinfo.start.offset.over = 0;
2606 draw_context.drawinfo.start.offset.middle = 0;
2607 draw_context.drawinfo.start.offset.under = 0;
2608 draw_context.drawinfo.end.offset.over = 0;
2609 draw_context.drawinfo.end.offset.middle = 0;
2610 draw_context.drawinfo.end.offset.under = 0;
2611
2612 {
2613 /* Draw the line */
2614 PropertiesLine prop_line = prepare_s_e_line(process);
2615 draw_line((void*)&prop_line, (void*)&draw_context);
2616
2617 }
2618 /* become the last x position */
2619 hashed_process_data->x.middle = x;
2620 hashed_process_data->x.middle_used = TRUE;
2621 hashed_process_data->x.middle_marked = FALSE;
2622
2623 /* Calculate the next good time */
2624 convert_pixels_to_time(width, x+1, time_window,
2625 &hashed_process_data->next_good_time);
2626 }
2627 }
2628 }
2629
2630 return 0;
2631}
2632
2633
2634
2635
2636
2637
2638
2639
2640#if 0
2641/* before_process_hook
2642 *
2643 * Draw lines for process event.
2644 *
2645 * @param hook_data ControlFlowData structure of the viewer.
2646 * @param call_data Event context.
2647 *
2648 * This function adds items to be drawn in a queue for each process.
2649 *
2650 */
2651int before_process_hook(void *hook_data, void *call_data)
2652{
2653 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
2654 EventsRequest *events_request = (EventsRequest*)thf->hook_data;
2655 ControlFlowData *control_flow_data = events_request->viewer_data;
2656
2657 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
2658
2659 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
2660
2661 LttEvent *e;
2662 e = ltt_tracefile_get_event(tfc->tf);
2663
2664 LttTime evtime = ltt_event_time(e);
2665
2666 guint sub_id;
2667 {
2668 LttField *f = ltt_event_field(e);
2669 LttField *element;
2670 element = ltt_field_member(f,0);
2671 sub_id = ltt_event_get_long_unsigned(e,element);
2672 }
2673
2674 if(sub_id == 3) { /* exit */
2675
2676 /* Add process to process list (if not present) */
2677 LttvProcessState *process = tfs->process;
2678 guint pid = process->pid;
2679 LttTime birth;
2680 guint pl_height = 0;
2681 HashedProcessData *hashed_process_data = NULL;
2682
2683 ProcessList *process_list = control_flow_data->process_list;
2684
2685 g_assert(process != NULL);
2686
2687 birth = process->creation_time;
2688
2689 if(likely(process_list->current_hash_data[tfc->index] != NULL)) {
2690 hashed_process_data = process_list->current_hash_data[tfc->index];
2691 } else {
2692 hashed_process_data = processlist_get_process_data(process_list,
2693 pid,
2694 process->last_cpu_index,
2695 &birth,
2696 tfc->t_context->index);
2697 if(unlikely(hashed_process_data == NULL))
2698 {
2699 g_assert(pid == 0 || pid != process->ppid);
2700 /* Process not present */
2701 Drawing_t *drawing = control_flow_data->drawing;
2702 const gchar *name = g_quark_to_string(process->name);
2703 ProcessInfo *process_info;
2704 processlist_add(process_list,
2705 drawing,
2706 pid,
2707 process->last_cpu_index,
2708 process->ppid,
2709 &birth,
2710 tfc->t_context->index,
2711 name,
2712 &pl_height,
2713 &process_info,
2714 &hashed_process_data);
2715 gtk_widget_set_size_request(drawing->drawing_area,
2716 -1,
2717 pl_height);
2718 gtk_widget_queue_draw(drawing->drawing_area);
2719 }
2720 }
2721
2722 /* Now, the process is in the state hash and our own process hash.
2723 * We definitely can draw the items related to the ending state.
2724 */
2725
2726 if(likely(ltt_time_compare(hashed_process_data->next_good_time,
2727 evtime) > 0))
2728 {
2729 if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
2730 TimeWindow time_window =
2731 lttvwindow_get_time_window(control_flow_data->tab);
2732
2733#ifdef EXTRA_CHECK
2734 if(ltt_time_compare(evtime, time_window.start_time) == -1
2735 || ltt_time_compare(evtime, time_window.end_time) == 1)
2736 return;
2737#endif //EXTRA_CHECK
2738 Drawing_t *drawing = control_flow_data->drawing;
2739 guint width = drawing->width;
2740 guint x;
2741 convert_time_to_pixels(
2742 time_window,
2743 evtime,
2744 width,
2745 &x);
2746
2747 /* Draw collision indicator */
2748 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
2749 gdk_draw_point(hashed_process_data->pixmap,
2750 drawing->gc,
2751 x,
2752 (hashed_process_data->height/2)-3);
2753 hashed_process_data->x.middle_marked = TRUE;
2754 }
2755 } else {
2756 TimeWindow time_window =
2757 lttvwindow_get_time_window(control_flow_data->tab);
2758
2759#ifdef EXTRA_CHECK
2760 if(ltt_time_compare(evtime, time_window.start_time) == -1
2761 || ltt_time_compare(evtime, time_window.end_time) == 1)
2762 return;
2763#endif //EXTRA_CHECK
2764 Drawing_t *drawing = control_flow_data->drawing;
2765 guint width = drawing->width;
2766 guint x;
2767
2768 convert_time_to_pixels(
2769 time_window,
2770 evtime,
2771 width,
2772 &x);
2773
2774
2775 /* Jump over draw if we are at the same x position */
2776 if(unlikely(x == hashed_process_data->x.middle &&
2777 hashed_process_data->x.middle_used))
2778 {
2779 if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
2780 /* Draw collision indicator */
2781 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
2782 gdk_draw_point(hashed_process_data->pixmap,
2783 drawing->gc,
2784 x,
2785 (hashed_process_data->height/2)-3);
2786 hashed_process_data->x.middle_marked = TRUE;
2787 }
2788 /* jump */
2789 } else {
2790 DrawContext draw_context;
2791
2792 /* Now create the drawing context that will be used to draw
2793 * items related to the last state. */
2794 draw_context.drawable = hashed_process_data->pixmap;
2795 draw_context.gc = drawing->gc;
2796 draw_context.pango_layout = drawing->pango_layout;
2797 draw_context.drawinfo.start.x = hashed_process_data->x.middle;
2798 draw_context.drawinfo.end.x = x;
2799
2800 draw_context.drawinfo.y.over = 1;
1c736ed5 2801 draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
2802 draw_context.drawinfo.y.under = hashed_process_data->height;
4b7dc462 2803
2804 draw_context.drawinfo.start.offset.over = 0;
2805 draw_context.drawinfo.start.offset.middle = 0;
2806 draw_context.drawinfo.start.offset.under = 0;
2807 draw_context.drawinfo.end.offset.over = 0;
2808 draw_context.drawinfo.end.offset.middle = 0;
2809 draw_context.drawinfo.end.offset.under = 0;
dbd243b1 2810
4b7dc462 2811 {
2812 /* Draw the line */
9a1ec01b 2813 PropertiesLine prop_line = prepare_s_e_line(process);
4b7dc462 2814 draw_line((void*)&prop_line, (void*)&draw_context);
2815
2816 }
2817 /* become the last x position */
2818 hashed_process_data->x.middle = x;
e72908ed 2819 hashed_process_data->x.middle_used = TRUE;
2820 hashed_process_data->x.middle_marked = FALSE;
b2743953 2821
2822 /* Calculate the next good time */
2823 convert_pixels_to_time(width, x+1, time_window,
2824 &hashed_process_data->next_good_time);
dbd243b1 2825 }
dbd243b1 2826 }
2827
2da61677 2828 } else if(sub_id == 7) /* release */ {
2829
2830 guint pid;
2831 {
2832 LttField *f = ltt_event_field(e);
2833 LttField *element;
2834 element = ltt_field_member(f,1);
2835 pid = ltt_event_get_long_unsigned(e,element);
2836 }
2837
2838 /* Add process to process list (if not present) */
2839 /* Don't care about the process if it's not in the state hash already :
2840 * that means a process that has never done anything in the trace and
2841 * unknown suddently gets destroyed : no state meaningful to show. */
2842 LttvProcessState *process = lttv_state_find_process(tfs, pid);
2843
2844 if(process != NULL) {
2845 LttTime birth;
2846 guint pl_height = 0;
2847 HashedProcessData *hashed_process_data = NULL;
2848
2849 ProcessList *process_list = control_flow_data->process_list;
2850
2851 birth = process->creation_time;
2852
2853 /* Cannot use current process : this event happens on another process,
2854 * action done by the parent. */
2855 hashed_process_data = processlist_get_process_data(process_list,
2856 pid,
2857 process->last_cpu_index,
2858 &birth,
2859 tfc->t_context->index);
2860 if(unlikely(hashed_process_data == NULL))
2861 {
2862 g_assert(pid == 0 || pid != process->ppid);
2863 /* Process not present */
2864 Drawing_t *drawing = control_flow_data->drawing;
2da61677 2865 ProcessInfo *process_info;
2866 processlist_add(process_list,
2867 drawing,
2868 pid,
2869 process->last_cpu_index,
2870 process->ppid,
2871 &birth,
2872 tfc->t_context->index,
f4b88a7d 2873 process->name,
2da61677 2874 &pl_height,
2875 &process_info,
2876 &hashed_process_data);
2877 gtk_widget_set_size_request(drawing->drawing_area,
2878 -1,
2879 pl_height);
2880 gtk_widget_queue_draw(drawing->drawing_area);
2881 }
2882
2883 /* Now, the process is in the state hash and our own process hash.
2884 * We definitely can draw the items related to the ending state.
2885 */
2886
2887 if(likely(ltt_time_compare(hashed_process_data->next_good_time,
2888 evtime) > 0))
2889 {
2890 if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
2891 TimeWindow time_window =
2892 lttvwindow_get_time_window(control_flow_data->tab);
2893
2894#ifdef EXTRA_CHECK
2895 if(ltt_time_compare(evtime, time_window.start_time) == -1
2896 || ltt_time_compare(evtime, time_window.end_time) == 1)
2897 return;
2898#endif //EXTRA_CHECK
2899 Drawing_t *drawing = control_flow_data->drawing;
2900 guint width = drawing->width;
2901 guint x;
2902 convert_time_to_pixels(
2903 time_window,
2904 evtime,
2905 width,
2906 &x);
2907
2908 /* Draw collision indicator */
2909 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
2910 gdk_draw_point(hashed_process_data->pixmap,
2911 drawing->gc,
2912 x,
2913 (hashed_process_data->height/2)-3);
2914 hashed_process_data->x.middle_marked = TRUE;
2915 }
2916 } else {
2917 TimeWindow time_window =
2918 lttvwindow_get_time_window(control_flow_data->tab);
2919
2920#ifdef EXTRA_CHECK
2921 if(ltt_time_compare(evtime, time_window.start_time) == -1
2922 || ltt_time_compare(evtime, time_window.end_time) == 1)
2923 return;
2924#endif //EXTRA_CHECK
2925 Drawing_t *drawing = control_flow_data->drawing;
2926 guint width = drawing->width;
2927 guint x;
2928
2929 convert_time_to_pixels(
2930 time_window,
2931 evtime,
2932 width,
2933 &x);
2934
2935
2936 /* Jump over draw if we are at the same x position */
2937 if(unlikely(x == hashed_process_data->x.middle &&
2938 hashed_process_data->x.middle_used))
2939 {
2940 if(unlikely(hashed_process_data->x.middle_marked == FALSE)) {
2941 /* Draw collision indicator */
2942 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
2943 gdk_draw_point(hashed_process_data->pixmap,
2944 drawing->gc,
2945 x,
2946 (hashed_process_data->height/2)-3);
2947 hashed_process_data->x.middle_marked = TRUE;
2948 }
2949 /* jump */
2950 } else {
2951 DrawContext draw_context;
2952
2953 /* Now create the drawing context that will be used to draw
2954 * items related to the last state. */
2955 draw_context.drawable = hashed_process_data->pixmap;
2956 draw_context.gc = drawing->gc;
2957 draw_context.pango_layout = drawing->pango_layout;
2958 draw_context.drawinfo.start.x = hashed_process_data->x.middle;
2959 draw_context.drawinfo.end.x = x;
2960
2961 draw_context.drawinfo.y.over = 1;
2962 draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
2963 draw_context.drawinfo.y.under = hashed_process_data->height;
2964
2965 draw_context.drawinfo.start.offset.over = 0;
2966 draw_context.drawinfo.start.offset.middle = 0;
2967 draw_context.drawinfo.start.offset.under = 0;
2968 draw_context.drawinfo.end.offset.over = 0;
2969 draw_context.drawinfo.end.offset.middle = 0;
2970 draw_context.drawinfo.end.offset.under = 0;
2971
2972 {
2973 /* Draw the line */
2974 PropertiesLine prop_line = prepare_s_e_line(process);
2975 draw_line((void*)&prop_line, (void*)&draw_context);
2976
2977 }
2978 /* become the last x position */
2979 hashed_process_data->x.middle = x;
2980 hashed_process_data->x.middle_used = TRUE;
2981 hashed_process_data->x.middle_marked = FALSE;
2982
2983 /* Calculate the next good time */
2984 convert_pixels_to_time(width, x+1, time_window,
2985 &hashed_process_data->next_good_time);
2986 }
2987 }
2988 }
2989
dbd243b1 2990 }
2991 return 0;
2992
2993}
2994
2c82c4dc 2995#endif //0
2996
2997
2998
2999/* after_process_fork_hook
3000 *
3001 * Create the processlist entry for the child process. Put the last
3002 * position in x at the current time value.
3003 *
3004 * @param hook_data ControlFlowData structure of the viewer.
3005 * @param call_data Event context.
3006 *
3007 * This function adds items to be drawn in a queue for each process.
3008 *
3009 */
3010int after_process_fork_hook(void *hook_data, void *call_data)
3011{
3012 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
3013 EventsRequest *events_request = (EventsRequest*)thf->hook_data;
3014 ControlFlowData *control_flow_data = events_request->viewer_data;
3015
3016 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
3017
3018 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
3019
348c6ba8 3020 LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
3021
2c82c4dc 3022 LttEvent *e;
3023 e = ltt_tracefile_get_event(tfc->tf);
3024
3025 LttTime evtime = ltt_event_time(e);
3026
3027 guint child_pid;
3028 {
3029 child_pid = ltt_event_get_long_unsigned(e, thf->f2);
3030 }
3031
3032 /* Add process to process list (if not present) */
3033 LttvProcessState *process_child;
3034 LttTime birth;
3035 guint pl_height = 0;
3036 HashedProcessData *hashed_process_data_child = NULL;
3037
3038 ProcessList *process_list = control_flow_data->process_list;
3039
3040 /* Find child in the list... */
348c6ba8 3041 process_child = lttv_state_find_process(ts, ANY_CPU, child_pid);
2c82c4dc 3042 /* It should exist, because we are after the state update. */
3043 g_assert(process_child != NULL);
3044
3045 birth = process_child->creation_time;
3046
3047 /* Cannot use current process, because this action is done by the parent
3048 * on its child. */
3049 hashed_process_data_child = processlist_get_process_data(process_list,
3050 child_pid,
348c6ba8 3051 process_child->cpu,
2c82c4dc 3052 &birth,
3053 tfc->t_context->index);
3054 if(likely(hashed_process_data_child == NULL))
3055 {
3056 g_assert(child_pid == 0 || child_pid != process_child->ppid);
3057 /* Process not present */
3058 Drawing_t *drawing = control_flow_data->drawing;
2c82c4dc 3059 ProcessInfo *process_info;
3060 processlist_add(process_list,
3061 drawing,
3062 child_pid,
348c6ba8 3063 process_child->cpu,
2c82c4dc 3064 process_child->ppid,
3065 &birth,
3066 tfc->t_context->index,
f4b88a7d 3067 process_child->name,
2c82c4dc 3068 &pl_height,
3069 &process_info,
3070 &hashed_process_data_child);
3071 gtk_widget_set_size_request(drawing->drawing_area,
3072 -1,
3073 pl_height);
3074 gtk_widget_queue_draw(drawing->drawing_area);
3075 }
3076
3077
3078 if(likely(ltt_time_compare(hashed_process_data_child->next_good_time,
3079 evtime) <= 0))
3080 {
3081 TimeWindow time_window =
3082 lttvwindow_get_time_window(control_flow_data->tab);
3083
3084#ifdef EXTRA_CHECK
3085 if(ltt_time_compare(evtime, time_window.start_time) == -1
3086 || ltt_time_compare(evtime, time_window.end_time) == 1)
3087 return;
3088#endif //EXTRA_CHECK
3089 Drawing_t *drawing = control_flow_data->drawing;
3090 guint width = drawing->width;
3091 guint new_x;
3092 convert_time_to_pixels(
3093 time_window,
3094 evtime,
3095 width,
3096 &new_x);
3097
3098 if(likely(hashed_process_data_child->x.over != new_x)) {
3099 hashed_process_data_child->x.over = new_x;
3100 hashed_process_data_child->x.over_used = FALSE;
3101 hashed_process_data_child->x.over_marked = FALSE;
3102 }
3103 if(likely(hashed_process_data_child->x.middle != new_x)) {
3104 hashed_process_data_child->x.middle = new_x;
3105 hashed_process_data_child->x.middle_used = FALSE;
3106 hashed_process_data_child->x.middle_marked = FALSE;
3107 }
3108 if(likely(hashed_process_data_child->x.under != new_x)) {
3109 hashed_process_data_child->x.under = new_x;
3110 hashed_process_data_child->x.under_used = FALSE;
3111 hashed_process_data_child->x.under_marked = FALSE;
3112 }
3113 }
3114 return 0;
3115}
3116
3117
3118
3119/* after_process_exit_hook
3120 *
3121 * Create the processlist entry for the child process. Put the last
3122 * position in x at the current time value.
3123 *
3124 * @param hook_data ControlFlowData structure of the viewer.
3125 * @param call_data Event context.
3126 *
3127 * This function adds items to be drawn in a queue for each process.
3128 *
3129 */
3130int after_process_exit_hook(void *hook_data, void *call_data)
3131{
3132 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
3133 EventsRequest *events_request = (EventsRequest*)thf->hook_data;
3134 ControlFlowData *control_flow_data = events_request->viewer_data;
3135
3136 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
3137
3138 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
3139
348c6ba8 3140 LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
3141
2c82c4dc 3142 LttEvent *e;
3143 e = ltt_tracefile_get_event(tfc->tf);
3144
3145 LttTime evtime = ltt_event_time(e);
3146
3147 /* Add process to process list (if not present) */
348c6ba8 3148 //LttvProcessState *process = tfs->process;
3149 guint cpu = ltt_tracefile_num(tfc->tf);
3150 LttvProcessState *process = ts->running_process[cpu];
3151
3152 /* It should exist, because we are after the state update. */
3153 g_assert(process != NULL);
3154
2c82c4dc 3155 guint pid = process->pid;
3156 LttTime birth;
3157 guint pl_height = 0;
3158 HashedProcessData *hashed_process_data = NULL;
3159
3160 ProcessList *process_list = control_flow_data->process_list;
3161
2c82c4dc 3162 birth = process->creation_time;
3163
348c6ba8 3164 if(likely(process_list->current_hash_data[cpu] != NULL) ){
3165 hashed_process_data = process_list->current_hash_data[cpu];
2c82c4dc 3166 } else {
3167 hashed_process_data = processlist_get_process_data(process_list,
3168 pid,
348c6ba8 3169 process->cpu,
2c82c4dc 3170 &birth,
3171 tfc->t_context->index);
3172 if(unlikely(hashed_process_data == NULL))
3173 {
3174 g_assert(pid == 0 || pid != process->ppid);
3175 /* Process not present */
3176 Drawing_t *drawing = control_flow_data->drawing;
2c82c4dc 3177 ProcessInfo *process_info;
3178 processlist_add(process_list,
3179 drawing,
3180 pid,
348c6ba8 3181 process->cpu,
2c82c4dc 3182 process->ppid,
3183 &birth,
3184 tfc->t_context->index,
f4b88a7d 3185 process->name,
2c82c4dc 3186 &pl_height,
3187 &process_info,
3188 &hashed_process_data);
3189 gtk_widget_set_size_request(drawing->drawing_area,
3190 -1,
3191 pl_height);
3192 gtk_widget_queue_draw(drawing->drawing_area);
3193 }
3194
3195 /* Set the current process */
348c6ba8 3196 process_list->current_hash_data[process->cpu] =
2c82c4dc 3197 hashed_process_data;
3198 }
3199
3200 if(unlikely(ltt_time_compare(hashed_process_data->next_good_time,
3201 evtime) <= 0))
3202 {
3203 TimeWindow time_window =
3204 lttvwindow_get_time_window(control_flow_data->tab);
dbd243b1 3205
2c82c4dc 3206#ifdef EXTRA_CHECK
3207 if(ltt_time_compare(evtime, time_window.start_time) == -1
3208 || ltt_time_compare(evtime, time_window.end_time) == 1)
3209 return;
3210#endif //EXTRA_CHECK
3211 Drawing_t *drawing = control_flow_data->drawing;
3212 guint width = drawing->width;
3213 guint new_x;
3214 convert_time_to_pixels(
3215 time_window,
3216 evtime,
3217 width,
3218 &new_x);
3219 if(unlikely(hashed_process_data->x.middle != new_x)) {
3220 hashed_process_data->x.middle = new_x;
3221 hashed_process_data->x.middle_used = FALSE;
3222 hashed_process_data->x.middle_marked = FALSE;
3223 }
3224 }
dbd243b1 3225
2c82c4dc 3226 return 0;
3227}
dbd243b1 3228
3229
2c82c4dc 3230#if 0
dbd243b1 3231
3232/* after_process_hook
e92eabaf 3233 *
3234 * Create the processlist entry for the child process. Put the last
3235 * position in x at the current time value.
3236 *
3237 * @param hook_data ControlFlowData structure of the viewer.
3238 * @param call_data Event context.
3239 *
3240 * This function adds items to be drawn in a queue for each process.
3241 *
3242 */
dbd243b1 3243int after_process_hook(void *hook_data, void *call_data)
e92eabaf 3244{
2c82c4dc 3245 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
3246 EventsRequest *events_request = (EventsRequest*)thf->hook_data;
e92eabaf 3247 ControlFlowData *control_flow_data = events_request->viewer_data;
3248
3249 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
3250
3251 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
e92eabaf 3252
3253 LttEvent *e;
2c82c4dc 3254 e = ltt_tracefile_get_event(tfc->tf);
e92eabaf 3255
3256 LttTime evtime = ltt_event_time(e);
e92eabaf 3257
10a1069a 3258 guint sub_id;
3259 guint param1;
3260 {
3261 LttField *f = ltt_event_field(e);
3262 LttField *element;
3263 element = ltt_field_member(f,0);
3264 sub_id = ltt_event_get_long_unsigned(e,element);
3265 element = ltt_field_member(f,1);
3266 param1 = ltt_event_get_long_unsigned(e,element);
3267 }
e92eabaf 3268
10a1069a 3269 if(sub_id == 2) { /* fork */
3270
3271 guint child_pid = param1;
3272 /* Add process to process list (if not present) */
3273 LttvProcessState *process_child;
3274 LttTime birth;
1c736ed5 3275 guint pl_height = 0;
10a1069a 3276 HashedProcessData *hashed_process_data_child = NULL;
e92eabaf 3277
5c230fc4 3278 ProcessList *process_list = control_flow_data->process_list;
e92eabaf 3279
10a1069a 3280 /* Find child in the list... */
3281 process_child = lttv_state_find_process(tfs, child_pid);
3282 /* It should exist, because we are after the state update. */
3283 g_assert(process_child != NULL);
e92eabaf 3284
10a1069a 3285 birth = process_child->creation_time;
e92eabaf 3286
2da61677 3287 /* Cannot use current process, because this action is done by the parent
3288 * on its child. */
ac4e21cf 3289 hashed_process_data_child = processlist_get_process_data(process_list,
10a1069a 3290 child_pid,
40debf7b 3291 process_child->last_cpu_index,
10a1069a 3292 &birth,
ac4e21cf 3293 tfc->t_context->index);
1d1df11d 3294 if(likely(hashed_process_data_child == NULL))
10a1069a 3295 {
3296 g_assert(child_pid == 0 || child_pid != process_child->ppid);
3297 /* Process not present */
1c736ed5 3298 Drawing_t *drawing = control_flow_data->drawing;
aac69e70 3299 const gchar *name = g_quark_to_string(process_child->name);
4e86ae2e 3300 ProcessInfo *process_info;
10a1069a 3301 processlist_add(process_list,
1c736ed5 3302 drawing,
10a1069a 3303 child_pid,
40debf7b 3304 process_child->last_cpu_index,
10a1069a 3305 process_child->ppid,
3306 &birth,
3307 tfc->t_context->index,
3308 name,
3309 &pl_height,
4e86ae2e 3310 &process_info,
10a1069a 3311 &hashed_process_data_child);
1c736ed5 3312 gtk_widget_set_size_request(drawing->drawing_area,
3313 -1,
3314 pl_height);
3315 gtk_widget_queue_draw(drawing->drawing_area);
10a1069a 3316 }
e92eabaf 3317
40debf7b 3318
1d1df11d 3319 if(likely(ltt_time_compare(hashed_process_data_child->next_good_time,
3320 evtime) <= 0))
b2743953 3321 {
fd22065b 3322 TimeWindow time_window =
3323 lttvwindow_get_time_window(control_flow_data->tab);
3324
3325#ifdef EXTRA_CHECK
3326 if(ltt_time_compare(evtime, time_window.start_time) == -1
3327 || ltt_time_compare(evtime, time_window.end_time) == 1)
3328 return;
3329#endif //EXTRA_CHECK
d6fef890 3330 Drawing_t *drawing = control_flow_data->drawing;
96947fcf 3331 guint width = drawing->width;
b2743953 3332 guint new_x;
3333 convert_time_to_pixels(
3334 time_window,
3335 evtime,
3336 width,
3337 &new_x);
e72908ed 3338
1d1df11d 3339 if(likely(hashed_process_data_child->x.over != new_x)) {
b2743953 3340 hashed_process_data_child->x.over = new_x;
3341 hashed_process_data_child->x.over_used = FALSE;
3342 hashed_process_data_child->x.over_marked = FALSE;
3343 }
1d1df11d 3344 if(likely(hashed_process_data_child->x.middle != new_x)) {
b2743953 3345 hashed_process_data_child->x.middle = new_x;
3346 hashed_process_data_child->x.middle_used = FALSE;
3347 hashed_process_data_child->x.middle_marked = FALSE;
3348 }
1d1df11d 3349 if(likely(hashed_process_data_child->x.under != new_x)) {
b2743953 3350 hashed_process_data_child->x.under = new_x;
3351 hashed_process_data_child->x.under_used = FALSE;
3352 hashed_process_data_child->x.under_marked = FALSE;
3353 }
e72908ed 3354 }
23093869 3355
10a1069a 3356 } else if(sub_id == 3) { /* exit */
dbd243b1 3357
10a1069a 3358 /* Add process to process list (if not present) */
3359 LttvProcessState *process = tfs->process;
3360 guint pid = process->pid;
3361 LttTime birth;
1c736ed5 3362 guint pl_height = 0;
10a1069a 3363 HashedProcessData *hashed_process_data = NULL;
dbd243b1 3364
5c230fc4 3365 ProcessList *process_list = control_flow_data->process_list;
dbd243b1 3366
10a1069a 3367 /* It should exist, because we are after the state update. */
3368 g_assert(process != NULL);
dbd243b1 3369
10a1069a 3370 birth = process->creation_time;
dbd243b1 3371
2c82c4dc 3372 if(likely(process_list->current_hash_data[ltt_tracefile_num(tfc->tf)] != NULL) ){
3373 hashed_process_data = process_list->current_hash_data[ltt_tracefile_num(tfc->tf)];
40debf7b 3374 } else {
ac4e21cf 3375 hashed_process_data = processlist_get_process_data(process_list,
40debf7b 3376 pid,
3377 process->last_cpu_index,
3378 &birth,
ac4e21cf 3379 tfc->t_context->index);
1d1df11d 3380 if(unlikely(hashed_process_data == NULL))
40debf7b 3381 {
3382 g_assert(pid == 0 || pid != process->ppid);
3383 /* Process not present */
1c736ed5 3384 Drawing_t *drawing = control_flow_data->drawing;
40debf7b 3385 const gchar *name = g_quark_to_string(process->name);
3386 ProcessInfo *process_info;
3387 processlist_add(process_list,
1c736ed5 3388 drawing,
40debf7b 3389 pid,
3390 process->last_cpu_index,
3391 process->ppid,
3392 &birth,
3393 tfc->t_context->index,
3394 name,
3395 &pl_height,
3396 &process_info,
3397 &hashed_process_data);
1c736ed5 3398 gtk_widget_set_size_request(drawing->drawing_area,
3399 -1,
3400 pl_height);
3401 gtk_widget_queue_draw(drawing->drawing_area);
40debf7b 3402 }
3403
3404 /* Set the current process */
3405 process_list->current_hash_data[process->last_cpu_index] =
3406 hashed_process_data;
e92eabaf 3407 }
dbd243b1 3408
1d1df11d 3409 if(unlikely(ltt_time_compare(hashed_process_data->next_good_time,
3410 evtime) <= 0))
b2743953 3411 {
fd22065b 3412 TimeWindow time_window =
3413 lttvwindow_get_time_window(control_flow_data->tab);
3414
3415#ifdef EXTRA_CHECK
3416 if(ltt_time_compare(evtime, time_window.start_time) == -1
3417 || ltt_time_compare(evtime, time_window.end_time) == 1)
3418 return;
3419#endif //EXTRA_CHECK
d6fef890 3420 Drawing_t *drawing = control_flow_data->drawing;
96947fcf 3421 guint width = drawing->width;
b2743953 3422 guint new_x;
3423 convert_time_to_pixels(
3424 time_window,
3425 evtime,
3426 width,
3427 &new_x);
1d1df11d 3428 if(unlikely(hashed_process_data->x.middle != new_x)) {
b2743953 3429 hashed_process_data->x.middle = new_x;
3430 hashed_process_data->x.middle_used = FALSE;
3431 hashed_process_data->x.middle_marked = FALSE;
3432 }
e72908ed 3433 }
3434
e92eabaf 3435 }
3436 return 0;
3437
3438}
2c82c4dc 3439#endif //0
f7afe191 3440
f4b88a7d 3441/* Get the filename of the process to print */
3442int after_fs_exec_hook(void *hook_data, void *call_data)
3443{
3444 LttvTraceHookByFacility *thf = (LttvTraceHookByFacility*)hook_data;
3445 EventsRequest *events_request = (EventsRequest*)thf->hook_data;
3446 ControlFlowData *control_flow_data = events_request->viewer_data;
3447
3448 LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
3449
3450 LttvTracefileState *tfs = (LttvTracefileState *)call_data;
3451
3452 LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
3453
3454 guint cpu = ltt_tracefile_num(tfc->tf);
3455 LttvProcessState *process = ts->running_process[cpu];
3456 g_assert(process != NULL);
3457
3458 guint pid = process->pid;
3459
3460 /* Well, the process_out existed : we must get it in the process hash
3461 * or add it, and draw its items.
3462 */
3463 /* Add process to process list (if not present) */
3464 guint pl_height = 0;
3465 HashedProcessData *hashed_process_data = NULL;
3466 ProcessList *process_list = control_flow_data->process_list;
3467 LttTime birth = process->creation_time;
3468
3469 if(likely(process_list->current_hash_data[cpu] != NULL)) {
3470 hashed_process_data = process_list->current_hash_data[cpu];
3471 } else {
3472 hashed_process_data = processlist_get_process_data(process_list,
3473 pid,
3474 process->cpu,
3475 &birth,
3476 tfc->t_context->index);
3477 if(unlikely(hashed_process_data == NULL))
3478 {
3479 g_assert(pid == 0 || pid != process->ppid);
3480 ProcessInfo *process_info;
3481 /* Process not present */
3482 Drawing_t *drawing = control_flow_data->drawing;
3483 processlist_add(process_list,
3484 drawing,
3485 pid,
3486 process->cpu,
3487 process->ppid,
3488 &birth,
3489 tfc->t_context->index,
3490 process->name,
3491 &pl_height,
3492 &process_info,
3493 &hashed_process_data);
3494 gtk_widget_set_size_request(drawing->drawing_area,
3495 -1,
3496 pl_height);
3497 gtk_widget_queue_draw(drawing->drawing_area);
3498 }
3499 /* Set the current process */
3500 process_list->current_hash_data[process->cpu] =
3501 hashed_process_data;
3502 }
3503
3504 processlist_set_name(process_list, process->name, hashed_process_data);
3505
3506 return 0;
3507
3508}
3509
3510
3511
3512
1b238973 3513gint update_time_window_hook(void *hook_data, void *call_data)
f7afe191 3514{
a56a1ba4 3515 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
a43d67ba 3516 Drawing_t *drawing = control_flow_data->drawing;
1c736ed5 3517 ProcessList *process_list = control_flow_data->process_list;
a43d67ba 3518
224446ce 3519 const TimeWindowNotifyData *time_window_nofify_data =
3520 ((const TimeWindowNotifyData *)call_data);
3521
14963be0 3522 TimeWindow *old_time_window =
224446ce 3523 time_window_nofify_data->old_time_window;
3524 TimeWindow *new_time_window =
3525 time_window_nofify_data->new_time_window;
a56a1ba4 3526
3cb8b205 3527 /* Update the ruler */
3528 drawing_update_ruler(control_flow_data->drawing,
3529 new_time_window);
3530
3531
a56a1ba4 3532 /* Two cases : zoom in/out or scrolling */
3533
3534 /* In order to make sure we can reuse the old drawing, the scale must
3535 * be the same and the new time interval being partly located in the
3536 * currently shown time interval. (reuse is only for scrolling)
3537 */
3538
2eef04b5 3539 g_info("Old time window HOOK : %lu, %lu to %lu, %lu",
14963be0 3540 old_time_window->start_time.tv_sec,
3541 old_time_window->start_time.tv_nsec,
3542 old_time_window->time_width.tv_sec,
3543 old_time_window->time_width.tv_nsec);
a56a1ba4 3544
2eef04b5 3545 g_info("New time window HOOK : %lu, %lu to %lu, %lu",
14963be0 3546 new_time_window->start_time.tv_sec,
3547 new_time_window->start_time.tv_nsec,
3548 new_time_window->time_width.tv_sec,
3549 new_time_window->time_width.tv_nsec);
a56a1ba4 3550
14963be0 3551 if( new_time_window->time_width.tv_sec == old_time_window->time_width.tv_sec
3552 && new_time_window->time_width.tv_nsec == old_time_window->time_width.tv_nsec)
a56a1ba4 3553 {
3554 /* Same scale (scrolling) */
3555 g_info("scrolling");
14963be0 3556 LttTime *ns = &new_time_window->start_time;
20640e70 3557 LttTime *nw = &new_time_window->time_width;
14963be0 3558 LttTime *os = &old_time_window->start_time;
20640e70 3559 LttTime *ow = &old_time_window->time_width;
6f26fc38 3560 LttTime old_end = old_time_window->end_time;
3561 LttTime new_end = new_time_window->end_time;
a56a1ba4 3562 //if(ns<os+w<ns+w)
3563 //if(ns<os+w && os+w<ns+w)
3564 //if(ns<old_end && os<ns)
3565 if(ltt_time_compare(*ns, old_end) == -1
3566 && ltt_time_compare(*os, *ns) == -1)
3567 {
3568 g_info("scrolling near right");
3569 /* Scroll right, keep right part of the screen */
3570 guint x = 0;
51705146 3571 guint width = control_flow_data->drawing->width;
a56a1ba4 3572 convert_time_to_pixels(
a18124ff 3573 *old_time_window,
a56a1ba4 3574 *ns,
3575 width,
3576 &x);
3577
3578 /* Copy old data to new location */
1c736ed5 3579 copy_pixmap_region(process_list,
3580 NULL,
3581 control_flow_data->drawing->drawing_area->style->black_gc,
3582 NULL,
3583 x, 0,
3584 0, 0,
3585 control_flow_data->drawing->width-x+SAFETY, -1);
3586
6395d57c 3587 if(drawing->damage_begin == drawing->damage_end)
3588 drawing->damage_begin = control_flow_data->drawing->width-x;
3589 else
3590 drawing->damage_begin = 0;
3591
3592 drawing->damage_end = control_flow_data->drawing->width;
3593
a56a1ba4 3594 /* Clear the data request background, but not SAFETY */
1c736ed5 3595 rectangle_pixmap(process_list,
cfe526b1 3596 control_flow_data->drawing->drawing_area->style->black_gc,
a56a1ba4 3597 TRUE,
6395d57c 3598 drawing->damage_begin+SAFETY, 0,
3599 drawing->damage_end - drawing->damage_begin, // do not overlap
1c736ed5 3600 -1);
7abb23ad 3601 gtk_widget_queue_draw(drawing->drawing_area);
3602 //gtk_widget_queue_draw_area (drawing->drawing_area,
3603 // 0,0,
3604 // control_flow_data->drawing->width,
3605 // control_flow_data->drawing->height);
a43d67ba 3606
a56a1ba4 3607 /* Get new data for the rest. */
501d5405 3608 drawing_data_request(control_flow_data->drawing,
6395d57c 3609 drawing->damage_begin, 0,
3610 drawing->damage_end - drawing->damage_begin,
501d5405 3611 control_flow_data->drawing->height);
a56a1ba4 3612 } else {
3613 //if(ns<os<ns+w)
3614 //if(ns<os && os<ns+w)
3615 //if(ns<os && os<new_end)
3616 if(ltt_time_compare(*ns,*os) == -1
3617 && ltt_time_compare(*os,new_end) == -1)
3618 {
3619 g_info("scrolling near left");
3620 /* Scroll left, keep left part of the screen */
3621 guint x = 0;
51705146 3622 guint width = control_flow_data->drawing->width;
a56a1ba4 3623 convert_time_to_pixels(
a18124ff 3624 *new_time_window,
a56a1ba4 3625 *os,
3626 width,
3627 &x);
6395d57c 3628
a56a1ba4 3629 /* Copy old data to new location */
1c736ed5 3630 copy_pixmap_region (process_list,
3631 NULL,
cfe526b1 3632 control_flow_data->drawing->drawing_area->style->black_gc,
1c736ed5 3633 NULL,
a56a1ba4 3634 0, 0,
3635 x, 0,
3636 -1, -1);
3637
6395d57c 3638 if(drawing->damage_begin == drawing->damage_end)
3639 drawing->damage_end = x;
3640 else
3641 drawing->damage_end =
51705146 3642 control_flow_data->drawing->width;
6395d57c 3643
3644 drawing->damage_begin = 0;
3645
1c736ed5 3646 rectangle_pixmap (process_list,
cfe526b1 3647 control_flow_data->drawing->drawing_area->style->black_gc,
a56a1ba4 3648 TRUE,
6395d57c 3649 drawing->damage_begin, 0,
3650 drawing->damage_end - drawing->damage_begin, // do not overlap
1c736ed5 3651 -1);
a43d67ba 3652
7abb23ad 3653 gtk_widget_queue_draw(drawing->drawing_area);
3654 //gtk_widget_queue_draw_area (drawing->drawing_area,
3655 // 0,0,
3656 // control_flow_data->drawing->width,
3657 // control_flow_data->drawing->height);
a43d67ba 3658
6395d57c 3659
a56a1ba4 3660 /* Get new data for the rest. */
501d5405 3661 drawing_data_request(control_flow_data->drawing,
6395d57c 3662 drawing->damage_begin, 0,
3663 drawing->damage_end - drawing->damage_begin,
501d5405 3664 control_flow_data->drawing->height);
a56a1ba4 3665
a56a1ba4 3666 } else {
a43d67ba 3667 if(ltt_time_compare(*ns,*os) == 0)
3668 {
3669 g_info("not scrolling");
3670 } else {
3671 g_info("scrolling far");
3672 /* Cannot reuse any part of the screen : far jump */
3673
3674
1c736ed5 3675 rectangle_pixmap (process_list,
a43d67ba 3676 control_flow_data->drawing->drawing_area->style->black_gc,
3677 TRUE,
a56a1ba4 3678 0, 0,
a43d67ba 3679 control_flow_data->drawing->width+SAFETY, // do not overlap
1c736ed5 3680 -1);
a43d67ba 3681
7abb23ad 3682 //gtk_widget_queue_draw_area (drawing->drawing_area,
3683 // 0,0,
3684 // control_flow_data->drawing->width,
3685 // control_flow_data->drawing->height);
3686 gtk_widget_queue_draw(drawing->drawing_area);
a43d67ba 3687
6395d57c 3688 drawing->damage_begin = 0;
3689 drawing->damage_end = control_flow_data->drawing->width;
3690
a43d67ba 3691 drawing_data_request(control_flow_data->drawing,
a43d67ba 3692 0, 0,
3693 control_flow_data->drawing->width,
3694 control_flow_data->drawing->height);
3695
3696 }
a56a1ba4 3697 }
3698 }
3699 } else {
3700 /* Different scale (zoom) */
3701 g_info("zoom");
3702
1c736ed5 3703 rectangle_pixmap (process_list,
cfe526b1 3704 control_flow_data->drawing->drawing_area->style->black_gc,
a56a1ba4 3705 TRUE,
3706 0, 0,
501d5405 3707 control_flow_data->drawing->width+SAFETY, // do not overlap
1c736ed5 3708 -1);
a56a1ba4 3709
7abb23ad 3710 //gtk_widget_queue_draw_area (drawing->drawing_area,
3711 // 0,0,
3712 // control_flow_data->drawing->width,
3713 // control_flow_data->drawing->height);
3714 gtk_widget_queue_draw(drawing->drawing_area);
a56a1ba4 3715
6395d57c 3716 drawing->damage_begin = 0;
3717 drawing->damage_end = control_flow_data->drawing->width;
3718
501d5405 3719 drawing_data_request(control_flow_data->drawing,
a56a1ba4 3720 0, 0,
501d5405 3721 control_flow_data->drawing->width,
3722 control_flow_data->drawing->height);
a56a1ba4 3723 }
3724
3cb8b205 3725
3726
a56a1ba4 3727 return 0;
f7afe191 3728}
3729
6395d57c 3730gint traceset_notify(void *hook_data, void *call_data)
3731{
3732 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
3733 Drawing_t *drawing = control_flow_data->drawing;
6395d57c 3734
6395d57c 3735
b9a010a2 3736 drawing_clear(control_flow_data->drawing);
3737 processlist_clear(control_flow_data->process_list);
07390ec1 3738 gtk_widget_set_size_request(
3739 control_flow_data->drawing->drawing_area,
3740 -1, processlist_get_height(control_flow_data->process_list));
d9267eec 3741 redraw_notify(control_flow_data, NULL);
6395d57c 3742
d9267eec 3743 request_background_data(control_flow_data);
6395d57c 3744
3745 return FALSE;
3746}
3747
ca0f8a8e 3748gint redraw_notify(void *hook_data, void *call_data)
3749{
3750 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
3751 Drawing_t *drawing = control_flow_data->drawing;
3752 GtkWidget *widget = drawing->drawing_area;
3753
3754 drawing->damage_begin = 0;
51705146 3755 drawing->damage_end = drawing->width;
ca0f8a8e 3756
49217bd4 3757 /* fun feature, to be separated someday... */
3758 drawing_clear(control_flow_data->drawing);
3759 processlist_clear(control_flow_data->process_list);
07390ec1 3760 gtk_widget_set_size_request(
3761 control_flow_data->drawing->drawing_area,
3762 -1, processlist_get_height(control_flow_data->process_list));
1c736ed5 3763 // Clear the images
3764 rectangle_pixmap (control_flow_data->process_list,
ca0f8a8e 3765 widget->style->black_gc,
3766 TRUE,
3767 0, 0,
f3b7430d 3768 drawing->alloc_width,
1c736ed5 3769 -1);
ca0f8a8e 3770
f3b7430d 3771 gtk_widget_queue_draw(drawing->drawing_area);
ca0f8a8e 3772
3773 if(drawing->damage_begin < drawing->damage_end)
3774 {
3775 drawing_data_request(drawing,
ca0f8a8e 3776 drawing->damage_begin,
3777 0,
3778 drawing->damage_end-drawing->damage_begin,
51705146 3779 drawing->height);
ca0f8a8e 3780 }
3781
7abb23ad 3782 //gtk_widget_queue_draw_area(drawing->drawing_area,
3783 // 0,0,
3784 // drawing->width,
3785 // drawing->height);
ca0f8a8e 3786 return FALSE;
3787
3788}
3789
3790
3791gint continue_notify(void *hook_data, void *call_data)
a43d67ba 3792{
3793 ControlFlowData *control_flow_data = (ControlFlowData*) hook_data;
ca0f8a8e 3794 Drawing_t *drawing = control_flow_data->drawing;
a43d67ba 3795
6395d57c 3796 //g_assert(widget->allocation.width == drawing->damage_end);
ca0f8a8e 3797
3798 if(drawing->damage_begin < drawing->damage_end)
3799 {
3800 drawing_data_request(drawing,
ca0f8a8e 3801 drawing->damage_begin,
3802 0,
3803 drawing->damage_end-drawing->damage_begin,
51705146 3804 drawing->height);
ca0f8a8e 3805 }
3806
3807 return FALSE;
3808}
3809
3810
1b238973 3811gint update_current_time_hook(void *hook_data, void *call_data)
f7afe191 3812{
14963be0 3813 ControlFlowData *control_flow_data = (ControlFlowData*)hook_data;
a43d67ba 3814 Drawing_t *drawing = control_flow_data->drawing;
a56a1ba4 3815
224446ce 3816 LttTime current_time = *((LttTime*)call_data);
a56a1ba4 3817
ca0f8a8e 3818 TimeWindow time_window =
3819 lttvwindow_get_time_window(control_flow_data->tab);
a56a1ba4 3820
ca0f8a8e 3821 LttTime time_begin = time_window.start_time;
3822 LttTime width = time_window.time_width;
90ef7e4a 3823 LttTime half_width;
3824 {
3825 guint64 time_ll = ltt_time_to_uint64(width);
3826 time_ll = time_ll >> 1; /* divide by two */
3827 half_width = ltt_time_from_uint64(time_ll);
3828 }
a56a1ba4 3829 LttTime time_end = ltt_time_add(time_begin, width);
3830
3831 LttvTracesetContext * tsc =
ca0f8a8e 3832 lttvwindow_get_traceset_context(control_flow_data->tab);
a56a1ba4 3833
ca0f8a8e 3834 LttTime trace_start = tsc->time_span.start_time;
3835 LttTime trace_end = tsc->time_span.end_time;
a56a1ba4 3836
2eef04b5 3837 g_info("New current time HOOK : %lu, %lu", current_time.tv_sec,
224446ce 3838 current_time.tv_nsec);
a56a1ba4 3839
3840
3841
3842 /* If current time is inside time interval, just move the highlight
3843 * bar */
3844
3845 /* Else, we have to change the time interval. We have to tell it
3846 * to the main window. */
3847 /* The time interval change will take care of placing the current
3848 * time at the center of the visible area, or nearest possible if we are
3849 * at one end of the trace. */
3850
3851
dbc0ef8a 3852 if(ltt_time_compare(current_time, time_begin) < 0)
a56a1ba4 3853 {
224446ce 3854 TimeWindow new_time_window;
3855
3856 if(ltt_time_compare(current_time,
dbc0ef8a 3857 ltt_time_add(trace_start,half_width)) < 0)
a56a1ba4 3858 time_begin = trace_start;
3859 else
224446ce 3860 time_begin = ltt_time_sub(current_time,half_width);
a56a1ba4 3861
224446ce 3862 new_time_window.start_time = time_begin;
3863 new_time_window.time_width = width;
a18124ff 3864 new_time_window.time_width_double = ltt_time_to_double(width);
6f26fc38 3865 new_time_window.end_time = ltt_time_add(time_begin, width);
a56a1ba4 3866
e800cf84 3867 lttvwindow_report_time_window(control_flow_data->tab, new_time_window);
a56a1ba4 3868 }
dbc0ef8a 3869 else if(ltt_time_compare(current_time, time_end) > 0)
a56a1ba4 3870 {
224446ce 3871 TimeWindow new_time_window;
3872
dbc0ef8a 3873 if(ltt_time_compare(current_time, ltt_time_sub(trace_end, half_width)) > 0)
a56a1ba4 3874 time_begin = ltt_time_sub(trace_end,width);
3875 else
224446ce 3876 time_begin = ltt_time_sub(current_time,half_width);
a56a1ba4 3877
224446ce 3878 new_time_window.start_time = time_begin;
3879 new_time_window.time_width = width;
a18124ff 3880 new_time_window.time_width_double = ltt_time_to_double(width);
6f26fc38 3881 new_time_window.end_time = ltt_time_add(time_begin, width);
a56a1ba4 3882
e800cf84 3883 lttvwindow_report_time_window(control_flow_data->tab, new_time_window);
a56a1ba4 3884
3885 }
7abb23ad 3886 gtk_widget_queue_draw(control_flow_data->drawing->drawing_area);
3887
a56a1ba4 3888
3889 return 0;
f7afe191 3890}
3891
8b90e648 3892typedef struct _ClosureData {
ca0f8a8e 3893 EventsRequest *events_request;
d0cd7f09 3894 LttvTracesetState *tss;
b9a010a2 3895 LttTime end_time;
bc8d270b 3896 guint x_end;
8b90e648 3897} ClosureData;
a56a1ba4 3898
8b90e648 3899
e800cf84 3900void draw_closure(gpointer key, gpointer value, gpointer user_data)
3901{
a56a1ba4 3902 ProcessInfo *process_info = (ProcessInfo*)key;
3903 HashedProcessData *hashed_process_data = (HashedProcessData*)value;
3904 ClosureData *closure_data = (ClosureData*)user_data;
3905
e800cf84 3906 EventsRequest *events_request = closure_data->events_request;
3907 ControlFlowData *control_flow_data = events_request->viewer_data;
a56a1ba4 3908
e800cf84 3909 LttvTracesetState *tss = closure_data->tss;
d6fef890 3910 LttvTracesetContext *tsc = (LttvTracesetContext*)tss;
a56a1ba4 3911
e800cf84 3912 LttTime evtime = closure_data->end_time;
d0cd7f09 3913
e800cf84 3914 {
3915 /* For the process */
3916 /* First, check if the current process is in the state computation
3917 * process list. If it is there, that means we must add it right now and
3918 * draw items from the beginning of the read for it. If it is not
3919 * present, it's a new process and it was not present : it will
3920 * be added after the state update. */
31b6868d 3921#ifdef EXTRA_CHECK
e800cf84 3922 g_assert(lttv_traceset_number(tsc->ts) > 0);
31b6868d 3923#endif //EXTRA_CHECK
2c82c4dc 3924 LttvTraceContext *tc = tsc->traces[process_info->trace_num];
348c6ba8 3925 LttvTraceState *ts = (LttvTraceState*)tc;
2c82c4dc 3926
348c6ba8 3927#if 0
2c82c4dc 3928 //FIXME : optimize data structures.
3929 LttvTracefileState *tfs;
3930 LttvTracefileContext *tfc;
3931 guint i;
3932 for(i=0;i<tc->tracefiles->len;i++) {
3933 tfc = g_array_index(tc->tracefiles, LttvTracefileContext*, i);
3934 if(ltt_tracefile_name(tfc->tf) == LTT_NAME_CPU
3935 && ltt_tracefile_num(tfc->tf) == process_info->cpu)
3936 break;
3937
3938 }
3939 g_assert(i<tc->tracefiles->len);
3940 tfs = LTTV_TRACEFILE_STATE(tfc);
348c6ba8 3941#endif //0
2c82c4dc 3942 // LttvTracefileState *tfs =
3943 // (LttvTracefileState*)tsc->traces[process_info->trace_num]->
3944 // tracefiles[process_info->cpu];
2da61677 3945
e800cf84 3946 LttvProcessState *process;
348c6ba8 3947 process = lttv_state_find_process(ts, process_info->cpu,
e025a729 3948 process_info->pid);
a56a1ba4 3949
1d1df11d 3950 if(unlikely(process != NULL)) {
e800cf84 3951
3952 /* Only draw for processes that are currently in the trace states */
ad2e83ba 3953
5c230fc4 3954 ProcessList *process_list = control_flow_data->process_list;
1d1df11d 3955#ifdef EXTRA_CHECK
e800cf84 3956 /* Should be alike when background info is ready */
3957 if(control_flow_data->background_info_waiting==0)
3958 g_assert(ltt_time_compare(process->creation_time,
3959 process_info->birth) == 0);
1d1df11d 3960#endif //EXTRA_CHECK
e800cf84 3961
3962 /* Now, the process is in the state hash and our own process hash.
3963 * We definitely can draw the items related to the ending state.
3964 */
3965
1d1df11d 3966 if(unlikely(ltt_time_compare(hashed_process_data->next_good_time,
3967 evtime) <= 0))
e800cf84 3968 {
fd22065b 3969 TimeWindow time_window =
3970 lttvwindow_get_time_window(control_flow_data->tab);
3971
3972#ifdef EXTRA_CHECK
3973 if(ltt_time_compare(evtime, time_window.start_time) == -1
3974 || ltt_time_compare(evtime, time_window.end_time) == 1)
3975 return;
3976#endif //EXTRA_CHECK
d6fef890 3977 Drawing_t *drawing = control_flow_data->drawing;
96947fcf 3978 guint width = drawing->width;
a56a1ba4 3979
bc8d270b 3980 guint x = closure_data->x_end;
8b90e648 3981
4b7dc462 3982 DrawContext draw_context;
3983
e800cf84 3984 /* Now create the drawing context that will be used to draw
3985 * items related to the last state. */
1c736ed5 3986 draw_context.drawable = hashed_process_data->pixmap;
e800cf84 3987 draw_context.gc = drawing->gc;
3988 draw_context.pango_layout = drawing->pango_layout;
e800cf84 3989 draw_context.drawinfo.end.x = x;
3990
1c736ed5 3991 draw_context.drawinfo.y.over = 1;
3992 draw_context.drawinfo.y.middle = (hashed_process_data->height/2);
3993 draw_context.drawinfo.y.under = hashed_process_data->height;
e800cf84 3994
3995 draw_context.drawinfo.start.offset.over = 0;
3996 draw_context.drawinfo.start.offset.middle = 0;
3997 draw_context.drawinfo.start.offset.under = 0;
3998 draw_context.drawinfo.end.offset.over = 0;
3999 draw_context.drawinfo.end.offset.middle = 0;
4000 draw_context.drawinfo.end.offset.under = 0;
9a1ec01b 4001#if 0
4b7dc462 4002 /* Jump over draw if we are at the same x position */
4003 if(x == hashed_process_data->x.over)
e800cf84 4004 {
4b7dc462 4005 /* jump */
4006 } else {
23093869 4007 draw_context.drawinfo.start.x = hashed_process_data->x.over;
4008 /* Draw the line */
4009 PropertiesLine prop_line = prepare_execmode_line(process);
4010 draw_line((void*)&prop_line, (void*)&draw_context);
4011
4b7dc462 4012 hashed_process_data->x.over = x;
23093869 4013 }
9a1ec01b 4014#endif //0
4b7dc462 4015
1d1df11d 4016 if(unlikely(x == hashed_process_data->x.middle &&
4017 hashed_process_data->x.middle_used)) {
b2743953 4018#if 0 /* do not mark closure : not missing information */
e72908ed 4019 if(hashed_process_data->x.middle_marked == FALSE) {
4020 /* Draw collision indicator */
4021 gdk_gc_set_foreground(drawing->gc, &drawing_colors[COL_WHITE]);
4022 gdk_draw_point(drawing->pixmap,
4023 drawing->gc,
4024 x,
2c6618bc 4025 y+(height/2)-3);
de4ea1ad 4026 hashed_process_data->x.middle_marked = TRUE;
e72908ed 4027 }
b2743953 4028#endif //0
4b7dc462 4029 /* Jump */
4030 } else {
23093869 4031 draw_context.drawinfo.start.x = hashed_process_data->x.middle;
e800cf84 4032 /* Draw the line */
9a1ec01b 4033 PropertiesLine prop_line = prepare_s_e_line(process);
e800cf84 4034 draw_line((void*)&prop_line, (void*)&draw_context);
4035
4b7dc462 4036 /* become the last x position */
1d1df11d 4037 if(likely(x != hashed_process_data->x.middle)) {
e72908ed 4038 hashed_process_data->x.middle = x;
4039 /* but don't use the pixel */
4040 hashed_process_data->x.middle_used = FALSE;
b2743953 4041
4042 /* Calculate the next good time */
4043 convert_pixels_to_time(width, x+1, time_window,
4044 &hashed_process_data->next_good_time);
e72908ed 4045 }
e800cf84 4046 }
e800cf84 4047 }
4048 }
4049 }
4050 return;
8b90e648 4051}
4052
b9a010a2 4053int before_chunk(void *hook_data, void *call_data)
4054{
4055 EventsRequest *events_request = (EventsRequest*)hook_data;
16b9cadb 4056 LttvTracesetState *tss = (LttvTracesetState*)call_data;
7c0125e0 4057 ControlFlowData *cfd = (ControlFlowData*)events_request->viewer_data;
cd3892fe 4058#if 0
7c0125e0 4059 /* Desactivate sort */
4060 gtk_tree_sortable_set_sort_column_id(
4061 GTK_TREE_SORTABLE(cfd->process_list->list_store),
4062 TRACE_COLUMN,
4063 GTK_SORT_ASCENDING);
cd3892fe 4064#endif //0
b9a010a2 4065 drawing_chunk_begin(events_request, tss);
4066
4067 return 0;
4068}
4069
4070int before_request(void *hook_data, void *call_data)
ca0f8a8e 4071{
4072 EventsRequest *events_request = (EventsRequest*)hook_data;
16b9cadb 4073 LttvTracesetState *tss = (LttvTracesetState*)call_data;
7c0125e0 4074
ca0f8a8e 4075 drawing_data_request_begin(events_request, tss);
4076
4077 return 0;
4078}
4079
4080
8b90e648 4081/*
b9a010a2 4082 * after request is necessary in addition of after chunk in order to draw
4083 * lines until the end of the screen. after chunk just draws lines until
4084 * the last event.
4085 *
8b90e648 4086 * for each process
a56a1ba4 4087 * draw closing line
b9a010a2 4088 * expose
8b90e648 4089 */
b9a010a2 4090int after_request(void *hook_data, void *call_data)
8b90e648 4091{
ca0f8a8e 4092 EventsRequest *events_request = (EventsRequest*)hook_data;
4093 ControlFlowData *control_flow_data = events_request->viewer_data;
16b9cadb 4094 LttvTracesetState *tss = (LttvTracesetState*)call_data;
a56a1ba4 4095
5c230fc4 4096 ProcessList *process_list = control_flow_data->process_list;
b9a010a2 4097 LttTime end_time = events_request->end_time;
4098
4099 ClosureData closure_data;
4100 closure_data.events_request = (EventsRequest*)hook_data;
4101 closure_data.tss = tss;
4102 closure_data.end_time = end_time;
4103
bc8d270b 4104 TimeWindow time_window =
4105 lttvwindow_get_time_window(control_flow_data->tab);
4106 guint width = control_flow_data->drawing->width;
4107 convert_time_to_pixels(
4108 time_window,
4109 end_time,
4110 width,
4111 &closure_data.x_end);
4112
4113
b9a010a2 4114 /* Draw last items */
4115 g_hash_table_foreach(process_list->process_hash, draw_closure,
4116 (void*)&closure_data);
7c0125e0 4117
b9a010a2 4118
4119 /* Request expose */
4120 drawing_request_expose(events_request, tss, end_time);
4121 return 0;
4122}
4123
4124/*
4125 * for each process
4126 * draw closing line
e800cf84 4127 * expose
b9a010a2 4128 */
4129int after_chunk(void *hook_data, void *call_data)
4130{
4131 EventsRequest *events_request = (EventsRequest*)hook_data;
4132 ControlFlowData *control_flow_data = events_request->viewer_data;
16b9cadb 4133 LttvTracesetState *tss = (LttvTracesetState*)call_data;
4134 LttvTracesetContext *tsc = (LttvTracesetContext*)call_data;
b9a010a2 4135 LttvTracefileContext *tfc = lttv_traceset_context_get_current_tfc(tsc);
4136 LttTime end_time;
4137
5c230fc4 4138 ProcessList *process_list = control_flow_data->process_list;
b9a010a2 4139
40debf7b 4140 g_free(process_list->current_hash_data);
4141 process_list->current_hash_data = NULL;
4142
e800cf84 4143 if(tfc != NULL)
4144 end_time = LTT_TIME_MIN(tfc->timestamp, events_request->end_time);
0c5dbe3b 4145 else /* end of traceset, or position now out of request : end */
4146 end_time = events_request->end_time;
4147
a56a1ba4 4148 ClosureData closure_data;
ca0f8a8e 4149 closure_data.events_request = (EventsRequest*)hook_data;
4150 closure_data.tss = tss;
b9a010a2 4151 closure_data.end_time = end_time;
a56a1ba4 4152
bc8d270b 4153 TimeWindow time_window =
4154 lttvwindow_get_time_window(control_flow_data->tab);
4155 guint width = control_flow_data->drawing->width;
4156 convert_time_to_pixels(
4157 time_window,
4158 end_time,
4159 width,
4160 &closure_data.x_end);
4161
b9a010a2 4162 /* Draw last items */
14963be0 4163 g_hash_table_foreach(process_list->process_hash, draw_closure,
a56a1ba4 4164 (void*)&closure_data);
cd3892fe 4165#if 0
7c0125e0 4166 /* Reactivate sort */
4167 gtk_tree_sortable_set_sort_column_id(
4168 GTK_TREE_SORTABLE(control_flow_data->process_list->list_store),
4169 GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
4170 GTK_SORT_ASCENDING);
4171
4172 update_index_to_pixmap(control_flow_data->process_list);
cd3892fe 4173 /* Request a full expose : drawing scrambled */
4174 gtk_widget_queue_draw(control_flow_data->drawing->drawing_area);
4175#endif //0
4176 /* Request expose (updates damages zone also) */
b9a010a2 4177 drawing_request_expose(events_request, tss, end_time);
ca0f8a8e 4178
4179 return 0;
8b90e648 4180}
4181
This page took 0.271531 seconds and 4 git commands to generate.