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