multiple traces/tracefiles change
[lttv.git] / ltt / branches / poly / lttv / main / state.c
CommitLineData
9c312311 1/* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Michel Dagenais
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
dc877563 19
20#include <lttv/state.h>
ba576a78 21#include <ltt/facility.h>
22#include <ltt/trace.h>
308711e5 23#include <ltt/event.h>
a5dcde2f 24#include <ltt/type.h>
dc877563 25
b445142a 26LttvExecutionMode
27 LTTV_STATE_MODE_UNKNOWN,
ffd54a90 28 LTTV_STATE_USER_MODE,
29 LTTV_STATE_SYSCALL,
30 LTTV_STATE_TRAP,
31 LTTV_STATE_IRQ;
32
b445142a 33LttvExecutionSubmode
34 LTTV_STATE_SUBMODE_UNKNOWN,
35 LTTV_STATE_SUBMODE_NONE;
ffd54a90 36
37LttvProcessStatus
38 LTTV_STATE_UNNAMED,
39 LTTV_STATE_WAIT_FORK,
40 LTTV_STATE_WAIT_CPU,
41 LTTV_STATE_EXIT,
42 LTTV_STATE_WAIT,
43 LTTV_STATE_RUN;
44
ba576a78 45static GQuark
308711e5 46 LTTV_STATE_TRACEFILES,
47 LTTV_STATE_PROCESSES,
48 LTTV_STATE_PROCESS,
49 LTTV_STATE_EVENT,
50 LTTV_STATE_SAVED_STATES,
51 LTTV_STATE_TIME,
ba576a78 52 LTTV_STATE_HOOKS;
53
b445142a 54
55static void fill_name_tables(LttvTraceState *tcs);
56
57static void free_name_tables(LttvTraceState *tcs);
58
308711e5 59static void lttv_state_free_process_table(GHashTable *processes);
ba576a78 60
308711e5 61static LttvProcessState *create_process(LttvTracefileState *tfs,
3d27549e 62 LttvProcessState *parent, guint pid);
dc877563 63
d0cd7f09 64static LttvProcessState *create_process_from_trace(LttvTraceState *ts,
65 LttvProcessState *parent, guint pid);
66
308711e5 67void lttv_state_save(LttvTraceState *self, LttvAttribute *container)
68{
69 LTTV_TRACE_STATE_GET_CLASS(self)->state_save(self, container);
70}
71
72
73void lttv_state_restore(LttvTraceState *self, LttvAttribute *container)
74{
75 LTTV_TRACE_STATE_GET_CLASS(self)->state_restore(self, container);
76}
77
78
79void lttv_state_saved_state_free(LttvTraceState *self,
80 LttvAttribute *container)
81{
82 LTTV_TRACE_STATE_GET_CLASS(self)->state_restore(self, container);
83}
84
85
86static void
87restore_init_state(LttvTraceState *self)
88{
89 guint i, nb_control, nb_per_cpu, nb_tracefile;
90
91 LttvTracefileState *tfcs;
92
93 LttTime null_time = {0,0};
94
95 if(self->processes != NULL) lttv_state_free_process_table(self->processes);
96 self->processes = g_hash_table_new(g_direct_hash, g_direct_equal);
97 self->nb_event = 0;
98
99 nb_control = ltt_trace_control_tracefile_number(self->parent.t);
100 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(self->parent.t);
101 nb_tracefile = nb_control + nb_per_cpu;
102 for(i = 0 ; i < nb_tracefile ; i++) {
103 if(i < nb_control) {
104 tfcs = LTTV_TRACEFILE_STATE(self->parent.control_tracefiles[i]);
105 }
106 else {
107 tfcs = LTTV_TRACEFILE_STATE(self->parent.per_cpu_tracefiles[i - nb_control]);
108 }
109
110 tfcs->parent.timestamp = null_time;
111 tfcs->saved_position = 0;
112 tfcs->process = create_process(tfcs, NULL,0);
113 }
114}
115
116
dc877563 117static void
118init(LttvTracesetState *self, LttvTraceset *ts)
119{
b445142a 120 guint i, j, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
dc877563 121
ffd54a90 122 LttvTraceContext *tc;
dc877563 123
ffd54a90 124 LttvTraceState *tcs;
125
ffd54a90 126 LttvTracefileState *tfcs;
3d27549e 127
b445142a 128 LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_CONTEXT_TYPE))->
129 init((LttvTracesetContext *)self, ts);
dc877563 130
131 nb_trace = lttv_traceset_number(ts);
132 for(i = 0 ; i < nb_trace ; i++) {
b445142a 133 tc = self->parent.traces[i];
134 tcs = (LttvTraceState *)tc;
308711e5 135 tcs->save_interval = 100000;
9444deae 136 tcs->recompute_state_in_seek = TRUE;
137 tcs->saved_state_ready = FALSE;
b445142a 138 fill_name_tables(tcs);
dc877563 139
b445142a 140 nb_control = ltt_trace_control_tracefile_number(tc->t);
141 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(tc->t);
142 nb_tracefile = nb_control + nb_per_cpu;
dc877563 143 for(j = 0 ; j < nb_tracefile ; j++) {
b445142a 144 if(j < nb_control) {
145 tfcs = LTTV_TRACEFILE_STATE(tc->control_tracefiles[j]);
146 }
147 else {
148 tfcs = LTTV_TRACEFILE_STATE(tc->per_cpu_tracefiles[j - nb_control]);
149 }
b445142a 150 tfcs->cpu_name= g_quark_from_string(ltt_tracefile_name(tfcs->parent.tf));
dc877563 151 }
308711e5 152 tcs->processes = NULL;
153 restore_init_state(tcs);
dc877563 154 }
155}
156
157
158static void
159fini(LttvTracesetState *self)
160{
161 guint i, j, nb_trace, nb_tracefile;
162
ffd54a90 163 LttvTraceState *tcs;
dc877563 164
ffd54a90 165 LttvTracefileState *tfcs;
dc877563 166
ffd54a90 167 nb_trace = lttv_traceset_number(LTTV_TRACESET_CONTEXT(self)->ts);
dc877563 168 for(i = 0 ; i < nb_trace ; i++) {
ffd54a90 169 tcs = (LttvTraceState *)(LTTV_TRACESET_CONTEXT(self)->traces[i]);
308711e5 170 lttv_state_free_process_table(tcs->processes);
171 tcs->processes = NULL;
b445142a 172 free_name_tables(tcs);
dc877563 173 }
b445142a 174 LTTV_TRACESET_CONTEXT_CLASS(g_type_class_peek(LTTV_TRACESET_CONTEXT_TYPE))->
175 fini((LttvTracesetContext *)self);
dc877563 176}
177
178
c432246e 179static LttvTracesetContext *
dc877563 180new_traceset_context(LttvTracesetContext *self)
181{
ffd54a90 182 return LTTV_TRACESET_CONTEXT(g_object_new(LTTV_TRACESET_STATE_TYPE, NULL));
dc877563 183}
184
185
c432246e 186static LttvTraceContext *
dc877563 187new_trace_context(LttvTracesetContext *self)
188{
ffd54a90 189 return LTTV_TRACE_CONTEXT(g_object_new(LTTV_TRACE_STATE_TYPE, NULL));
dc877563 190}
191
192
c432246e 193static LttvTracefileContext *
dc877563 194new_tracefile_context(LttvTracesetContext *self)
195{
ffd54a90 196 return LTTV_TRACEFILE_CONTEXT(g_object_new(LTTV_TRACEFILE_STATE_TYPE, NULL));
197}
198
199
308711e5 200static void copy_process_state(gpointer key, gpointer value,gpointer user_data)
ffd54a90 201{
308711e5 202 LttvProcessState *process, *new_process;
ffd54a90 203
308711e5 204 GHashTable *new_processes = (GHashTable *)user_data;
ffd54a90 205
308711e5 206 guint i;
207
208 process = (LttvProcessState *)value;
209 new_process = g_new(LttvProcessState, 1);
210 *new_process = *process;
211 new_process->execution_stack = g_array_new(FALSE, FALSE,
212 sizeof(LttvExecutionState));
213 g_array_set_size(new_process->execution_stack,process->execution_stack->len);
214 for(i = 0 ; i < process->execution_stack->len; i++) {
215 g_array_index(new_process->execution_stack, LttvExecutionState, i) =
216 g_array_index(process->execution_stack, LttvExecutionState, i);
217 }
218 new_process->state = &g_array_index(new_process->execution_stack,
219 LttvExecutionState, new_process->execution_stack->len - 1);
220 g_hash_table_insert(new_processes, GUINT_TO_POINTER(new_process->pid),
221 new_process);
ffd54a90 222}
223
224
308711e5 225static GHashTable *lttv_state_copy_process_table(GHashTable *processes)
ffd54a90 226{
308711e5 227 GHashTable *new_processes = g_hash_table_new(g_direct_hash, g_direct_equal);
ffd54a90 228
308711e5 229 g_hash_table_foreach(processes, copy_process_state, new_processes);
230 return new_processes;
dc877563 231}
232
233
308711e5 234/* The saved state for each trace contains a member "processes", which
235 stores a copy of the process table, and a member "tracefiles" with
236 one entry per tracefile. Each tracefile has a "process" member pointing
237 to the current process and a "position" member storing the tracefile
238 position (needed to seek to the current "next" event. */
239
240static void state_save(LttvTraceState *self, LttvAttribute *container)
dc877563 241{
308711e5 242 guint i, nb_control, nb_per_cpu, nb_tracefile;
dc877563 243
308711e5 244 LttvTracefileState *tfcs;
245
246 LttvAttribute *tracefiles_tree, *tracefile_tree;
247
248 LttvAttributeType type;
249
250 LttvAttributeValue value;
251
252 LttvAttributeName name;
253
254 LttEventPosition *ep;
255
256 tracefiles_tree = lttv_attribute_find_subdir(container,
257 LTTV_STATE_TRACEFILES);
258
259 value = lttv_attribute_add(container, LTTV_STATE_PROCESSES,
260 LTTV_POINTER);
261 *(value.v_pointer) = lttv_state_copy_process_table(self->processes);
262
263 nb_control = ltt_trace_control_tracefile_number(self->parent.t);
264 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(self->parent.t);
265 nb_tracefile = nb_control + nb_per_cpu;
266
267 for(i = 0 ; i < nb_tracefile ; i++) {
268 if(i < nb_control)
269 tfcs = (LttvTracefileState *)self->parent.control_tracefiles[i];
270 else tfcs = (LttvTracefileState *)
271 self->parent.per_cpu_tracefiles[i - nb_control];
272
273 tracefile_tree = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
274 value = lttv_attribute_add(tracefiles_tree, i,
275 LTTV_GOBJECT);
276 *(value.v_gobject) = (GObject *)tracefile_tree;
277 value = lttv_attribute_add(tracefile_tree, LTTV_STATE_PROCESS,
278 LTTV_UINT);
279 *(value.v_uint) = tfcs->process->pid;
280 value = lttv_attribute_add(tracefile_tree, LTTV_STATE_EVENT,
281 LTTV_POINTER);
282 if(tfcs->parent.e == NULL) *(value.v_pointer) = NULL;
283 else {
a5dcde2f 284 ep = ltt_event_position_new();
308711e5 285 ltt_event_position(tfcs->parent.e, ep);
286 *(value.v_pointer) = ep;
287 }
dc877563 288 }
dc877563 289}
290
291
308711e5 292static void state_restore(LttvTraceState *self, LttvAttribute *container)
dc877563 293{
308711e5 294 guint i, nb_control, nb_per_cpu, nb_tracefile;
dc877563 295
308711e5 296 LttvTracefileState *tfcs;
dc877563 297
308711e5 298 LttvAttribute *tracefiles_tree, *tracefile_tree;
dc877563 299
308711e5 300 LttvAttributeType type;
dc877563 301
308711e5 302 LttvAttributeValue value;
dc877563 303
308711e5 304 LttvAttributeName name;
dc877563 305
308711e5 306 LttEventPosition *ep;
dc877563 307
308711e5 308 tracefiles_tree = lttv_attribute_find_subdir(container,
309 LTTV_STATE_TRACEFILES);
dc877563 310
308711e5 311 type = lttv_attribute_get_by_name(container, LTTV_STATE_PROCESSES,
312 &value);
313 g_assert(type == LTTV_POINTER);
314 lttv_state_free_process_table(self->processes);
315 self->processes = lttv_state_copy_process_table(*(value.v_pointer));
316
317 nb_control = ltt_trace_control_tracefile_number(self->parent.t);
318 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(self->parent.t);
319 nb_tracefile = nb_control + nb_per_cpu;
320
321 for(i = 0 ; i < nb_tracefile ; i++) {
322 if(i < nb_control) tfcs = (LttvTracefileState *)
323 self->parent.control_tracefiles[i];
324 else tfcs = (LttvTracefileState *)
325 self->parent.per_cpu_tracefiles[i - nb_control];
326
327 type = lttv_attribute_get(tracefiles_tree, i, &name, &value);
328 g_assert(type == LTTV_GOBJECT);
329 tracefile_tree = *((LttvAttribute **)(value.v_gobject));
330
331 type = lttv_attribute_get_by_name(tracefile_tree, LTTV_STATE_PROCESS,
332 &value);
333 g_assert(type == LTTV_UINT);
334 tfcs->process = lttv_state_find_process(tfcs, *(value.v_uint));
335 type = lttv_attribute_get_by_name(tracefile_tree, LTTV_STATE_EVENT,
336 &value);
337 g_assert(type == LTTV_POINTER);
338 if(*(value.v_pointer) == NULL) tfcs->parent.e = NULL;
339 else {
340 ep = *(value.v_pointer);
341 ltt_tracefile_seek_position(tfcs->parent.tf, ep);
342 tfcs->parent.e = ltt_tracefile_read(tfcs->parent.tf);
343 tfcs->parent.timestamp = ltt_event_time(tfcs->parent.e);
344 }
dc877563 345 }
dc877563 346}
347
348
308711e5 349static void state_saved_free(LttvTraceState *self, LttvAttribute *container)
dc877563 350{
308711e5 351 guint i, nb_control, nb_per_cpu, nb_tracefile;
dc877563 352
308711e5 353 LttvTracefileState *tfcs;
dc877563 354
308711e5 355 LttvAttribute *tracefiles_tree, *tracefile_tree;
dc877563 356
308711e5 357 LttvAttributeType type;
dc877563 358
308711e5 359 LttvAttributeValue value;
dc877563 360
308711e5 361 LttvAttributeName name;
dc877563 362
308711e5 363 LttEventPosition *ep;
dc877563 364
308711e5 365 tracefiles_tree = lttv_attribute_find_subdir(container,
366 LTTV_STATE_TRACEFILES);
367 lttv_attribute_remove_by_name(container, LTTV_STATE_TRACEFILES);
dc877563 368
308711e5 369 type = lttv_attribute_get_by_name(container, LTTV_STATE_PROCESSES,
370 &value);
371 g_assert(type == LTTV_POINTER);
372 lttv_state_free_process_table(*(value.v_pointer));
373 *(value.v_pointer) = NULL;
374 lttv_attribute_remove_by_name(container, LTTV_STATE_PROCESSES);
375
376 nb_control = ltt_trace_control_tracefile_number(self->parent.t);
377 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(self->parent.t);
378 nb_tracefile = nb_control + nb_per_cpu;
379
380 for(i = 0 ; i < nb_tracefile ; i++) {
381 if(i < nb_control) tfcs = (LttvTracefileState *)
382 self->parent.control_tracefiles[i];
383 else tfcs = (LttvTracefileState *)
384 self->parent.per_cpu_tracefiles[i - nb_control];
385
386 type = lttv_attribute_get(tracefiles_tree, i, &name, &value);
387 g_assert(type == LTTV_GOBJECT);
388 tracefile_tree = *((LttvAttribute **)(value.v_gobject));
389
390 type = lttv_attribute_get_by_name(tracefile_tree, LTTV_STATE_EVENT,
391 &value);
392 g_assert(type == LTTV_POINTER);
393 if(*(value.v_pointer) != NULL) g_free(*(value.v_pointer));
dc877563 394 }
308711e5 395 lttv_attribute_recursive_free(tracefiles_tree);
dc877563 396}
397
398
b445142a 399static void
400fill_name_tables(LttvTraceState *tcs)
401{
402 int i, nb;
dc877563 403
b445142a 404 char *f_name, *e_name;
dc877563 405
b445142a 406 LttvTraceHook h;
407
408 LttEventType *et;
409
410 LttType *t;
411
412 GString *fe_name = g_string_new("");
413
414 nb = ltt_trace_eventtype_number(tcs->parent.t);
415 tcs->eventtype_names = g_new(GQuark, nb);
416 for(i = 0 ; i < nb ; i++) {
417 et = ltt_trace_eventtype_get(tcs->parent.t, i);
418 e_name = ltt_eventtype_name(et);
419 f_name = ltt_facility_name(ltt_eventtype_facility(et));
420 g_string_printf(fe_name, "%s.%s", f_name, e_name);
421 tcs->eventtype_names[i] = g_quark_from_string(fe_name->str);
422 }
dc877563 423
b445142a 424 lttv_trace_find_hook(tcs->parent.t, "core", "syscall_entry",
425 "syscall_id", NULL, NULL, NULL, &h);
426 t = ltt_field_type(h.f1);
427 nb = ltt_type_element_number(t);
428
429 /* CHECK syscalls should be an emun but currently are not!
430 tcs->syscall_names = g_new(GQuark, nb);
431
432 for(i = 0 ; i < nb ; i++) {
433 tcs->syscall_names[i] = g_quark_from_string(ltt_enum_string_get(t, i));
434 }
435 */
436
437 tcs->syscall_names = g_new(GQuark, 256);
438 for(i = 0 ; i < 256 ; i++) {
439 g_string_printf(fe_name, "syscall %d", i);
440 tcs->syscall_names[i] = g_quark_from_string(fe_name->str);
441 }
442
443 lttv_trace_find_hook(tcs->parent.t, "core", "trap_entry",
444 "trap_id", NULL, NULL, NULL, &h);
445 t = ltt_field_type(h.f1);
446 nb = ltt_type_element_number(t);
447
448 /*
449 tcs->trap_names = g_new(GQuark, nb);
450 for(i = 0 ; i < nb ; i++) {
451 tcs->trap_names[i] = g_quark_from_string(ltt_enum_string_get(t, i));
452 }
453 */
454
455 tcs->trap_names = g_new(GQuark, 256);
456 for(i = 0 ; i < 256 ; i++) {
457 g_string_printf(fe_name, "trap %d", i);
458 tcs->trap_names[i] = g_quark_from_string(fe_name->str);
459 }
460
461 lttv_trace_find_hook(tcs->parent.t, "core", "irq_entry",
462 "irq_id", NULL, NULL, NULL, &h);
463 t = ltt_field_type(h.f1);
464 nb = ltt_type_element_number(t);
465
466 /*
467 tcs->irq_names = g_new(GQuark, nb);
468 for(i = 0 ; i < nb ; i++) {
469 tcs->irq_names[i] = g_quark_from_string(ltt_enum_string_get(t, i));
470 }
471 */
472
473 tcs->irq_names = g_new(GQuark, 256);
474 for(i = 0 ; i < 256 ; i++) {
475 g_string_printf(fe_name, "irq %d", i);
476 tcs->irq_names[i] = g_quark_from_string(fe_name->str);
477 }
478
479 g_string_free(fe_name, TRUE);
480}
481
482
483static void
484free_name_tables(LttvTraceState *tcs)
485{
486 g_free(tcs->eventtype_names);
487 g_free(tcs->syscall_names);
488 g_free(tcs->trap_names);
489 g_free(tcs->irq_names);
490}
dc877563 491
b445142a 492
493static void push_state(LttvTracefileState *tfs, LttvExecutionMode t,
ffd54a90 494 guint state_id)
dc877563 495{
b445142a 496 LttvExecutionState *es;
dc877563 497
498 LttvProcessState *process = tfs->process;
499
b445142a 500 guint depth = process->execution_stack->len;
dc877563 501
b445142a 502 g_array_set_size(process->execution_stack, depth + 1);
503 es = &g_array_index(process->execution_stack, LttvExecutionState, depth);
504 es->t = t;
505 es->n = state_id;
506 es->entry = es->change = tfs->parent.timestamp;
507 es->s = process->state->s;
508 process->state = es;
dc877563 509}
510
511
b445142a 512static void pop_state(LttvTracefileState *tfs, LttvExecutionMode t)
dc877563 513{
514 LttvProcessState *process = tfs->process;
515
b445142a 516 guint depth = process->execution_stack->len - 1;
dc877563 517
3d27549e 518 if(process->state->t != t){
b445142a 519 g_warning("Different execution mode type (%d.%09d): ignore it\n",
520 tfs->parent.timestamp.tv_sec, tfs->parent.timestamp.tv_nsec);
8e8e6b64 521 g_warning("process state has %s when pop_int is %s\n",
522 g_quark_to_string(process->state->t),
523 g_quark_to_string(t));
524 g_warning("{ %u, %u, %s, %s }\n",
525 process->pid,
526 process->ppid,
527 g_quark_to_string(process->name),
528 g_quark_to_string(process->state->s));
3d27549e 529 return;
530 }
b445142a 531
532 if(depth == 0){
533 g_warning("Trying to pop last state on stack (%d.%09d): ignore it\n",
534 tfs->parent.timestamp.tv_sec, tfs->parent.timestamp.tv_nsec);
535 return;
536 }
537
538 g_array_remove_index(process->execution_stack, depth);
dc877563 539 depth--;
b445142a 540 process->state = &g_array_index(process->execution_stack, LttvExecutionState,
dc877563 541 depth);
b445142a 542 process->state->change = tfs->parent.timestamp;
dc877563 543}
544
545
308711e5 546static LttvProcessState *create_process(LttvTracefileState *tfs,
ffd54a90 547 LttvProcessState *parent, guint pid)
dc877563 548{
549 LttvProcessState *process = g_new(LttvProcessState, 1);
550
b445142a 551 LttvExecutionState *es;
dc877563 552
ffd54a90 553 LttvTraceContext *tc;
554
ba576a78 555 LttvTraceState *tcs;
556
b445142a 557 char buffer[128];
ffd54a90 558
b445142a 559 tcs = (LttvTraceState *)tc = tfs->parent.t_context;
60b53e4f 560
ffd54a90 561 g_hash_table_insert(tcs->processes, GUINT_TO_POINTER(pid), process);
dc877563 562 process->pid = pid;
b445142a 563
564 if(parent) {
565 process->ppid = parent->pid;
566 process->name = parent->name;
567 }
568 else {
569 process->ppid = 0;
570 process->name = LTTV_STATE_UNNAMED;
571 }
572
573 process->creation_time = tfs->parent.timestamp;
574 sprintf(buffer,"%d-%lu.%lu",pid, process->creation_time.tv_sec,
575 process->creation_time.tv_nsec);
576 process->pid_time = g_quark_from_string(buffer);
577 process->execution_stack = g_array_new(FALSE, FALSE,
578 sizeof(LttvExecutionState));
579 g_array_set_size(process->execution_stack, 1);
580 es = process->state = &g_array_index(process->execution_stack,
581 LttvExecutionState, 0);
582 es->t = LTTV_STATE_USER_MODE;
583 es->n = LTTV_STATE_SUBMODE_NONE;
584 es->entry = tfs->parent.timestamp;
585 es->change = tfs->parent.timestamp;
586 es->s = LTTV_STATE_WAIT_FORK;
cbe7c836 587
588 return process;
dc877563 589}
590
d0cd7f09 591static LttvProcessState *create_process_from_trace(LttvTraceState *tcs,
592 LttvProcessState *parent, guint pid)
593{
594 LttvProcessState *process = g_new(LttvProcessState, 1);
595
596 LttvExecutionState *es;
597
598 LttvTraceContext *tc = (LttvTraceContext *)tcs;
599
600 char buffer[128];
601
602 g_hash_table_insert(tcs->processes, GUINT_TO_POINTER(pid), process);
603 process->pid = pid;
604
605 if(parent) {
606 process->ppid = parent->pid;
607 process->name = parent->name;
608 }
609 else {
610 process->ppid = 0;
611 process->name = LTTV_STATE_UNNAMED;
612 }
613
614 //FIXME timestamp should come from trace
615 process->creation_time.tv_sec = 0;
616 process->creation_time.tv_nsec = 0;
617 sprintf(buffer,"%d-%lu.%lu",pid, process->creation_time.tv_sec,
618 process->creation_time.tv_nsec);
619 process->pid_time = g_quark_from_string(buffer);
620 process->execution_stack = g_array_new(FALSE, FALSE,
621 sizeof(LttvExecutionState));
622 g_array_set_size(process->execution_stack, 1);
623 es = process->state = &g_array_index(process->execution_stack,
624 LttvExecutionState, 0);
625 es->t = LTTV_STATE_USER_MODE;
626 es->n = LTTV_STATE_SUBMODE_NONE;
627 //FIXME es->entry = tfs->parent.timestamp;
628 es->entry.tv_sec = 0;
629 es->entry.tv_nsec = 0;
630 //FIXME es->change = tfs->parent.timestamp;
631 es->change.tv_sec = 0;
632 es->change.tv_nsec = 0;
633 es->s = LTTV_STATE_WAIT_FORK;
634
635 return process;
636}
637
638
dc877563 639
308711e5 640LttvProcessState *lttv_state_find_process(LttvTracefileState *tfs,
641 guint pid)
dc877563 642{
ba576a78 643 LttvTraceState *ts =(LttvTraceState *)LTTV_TRACEFILE_CONTEXT(tfs)->t_context;
644 LttvProcessState *process = g_hash_table_lookup(ts->processes,
645 GUINT_TO_POINTER(pid));
dc877563 646 if(process == NULL) process = create_process(tfs, NULL, pid);
647 return process;
648}
649
d0cd7f09 650LttvProcessState *lttv_state_find_process_from_trace(LttvTraceState *ts,
651 guint pid)
652{
653 LttvProcessState *process = g_hash_table_lookup(ts->processes,
654 GUINT_TO_POINTER(pid));
655
656 if(process == NULL) process = create_process_from_trace(ts, NULL, pid);
657 return process;
658}
659
660
dc877563 661
b445142a 662static void exit_process(LttvTracefileState *tfs, LttvProcessState *process)
dc877563 663{
ba576a78 664 LttvTraceState *ts = LTTV_TRACE_STATE(tfs->parent.t_context);
665
666 g_hash_table_remove(ts->processes, GUINT_TO_POINTER(process->pid));
b445142a 667 g_array_free(process->execution_stack, TRUE);
dc877563 668 g_free(process);
669}
670
671
b445142a 672static void free_process_state(gpointer key, gpointer value,gpointer user_data)
dc877563 673{
b445142a 674 g_array_free(((LttvProcessState *)value)->execution_stack, TRUE);
dc877563 675 g_free(value);
676}
677
678
308711e5 679static void lttv_state_free_process_table(GHashTable *processes)
dc877563 680{
681 g_hash_table_foreach(processes, free_process_state, NULL);
308711e5 682 g_hash_table_destroy(processes);
dc877563 683}
684
685
b445142a 686static gboolean syscall_entry(void *hook_data, void *call_data)
dc877563 687{
b445142a 688 LttField *f = ((LttvTraceHook *)hook_data)->f1;
dc877563 689
ba576a78 690 LttvTracefileState *s = (LttvTracefileState *)call_data;
dc877563 691
b445142a 692 LttvExecutionSubmode submode;
693
694 submode = ((LttvTraceState *)(s->parent.t_context))->syscall_names[
695 ltt_event_get_unsigned(s->parent.e, f)];
696 push_state(s, LTTV_STATE_SYSCALL, submode);
dc877563 697 return FALSE;
698}
699
700
b445142a 701static gboolean syscall_exit(void *hook_data, void *call_data)
dc877563 702{
ba576a78 703 LttvTracefileState *s = (LttvTracefileState *)call_data;
dc877563 704
ffd54a90 705 pop_state(s, LTTV_STATE_SYSCALL);
dc877563 706 return FALSE;
707}
708
709
b445142a 710static gboolean trap_entry(void *hook_data, void *call_data)
dc877563 711{
b445142a 712 LttField *f = ((LttvTraceHook *)hook_data)->f1;
dc877563 713
ba576a78 714 LttvTracefileState *s = (LttvTracefileState *)call_data;
dc877563 715
b445142a 716 LttvExecutionSubmode submode;
717
718 submode = ((LttvTraceState *)(s->parent.t_context))->trap_names[
719 ltt_event_get_unsigned(s->parent.e, f)];
720 push_state(s, LTTV_STATE_TRAP, submode);
dc877563 721 return FALSE;
722}
723
724
b445142a 725static gboolean trap_exit(void *hook_data, void *call_data)
dc877563 726{
ba576a78 727 LttvTracefileState *s = (LttvTracefileState *)call_data;
dc877563 728
ffd54a90 729 pop_state(s, LTTV_STATE_TRAP);
dc877563 730 return FALSE;
731}
732
733
b445142a 734static gboolean irq_entry(void *hook_data, void *call_data)
dc877563 735{
b445142a 736 LttField *f = ((LttvTraceHook *)hook_data)->f1;
dc877563 737
ba576a78 738 LttvTracefileState *s = (LttvTracefileState *)call_data;
dc877563 739
b445142a 740 LttvExecutionSubmode submode;
741
742 submode = ((LttvTraceState *)(s->parent.t_context))->irq_names[
743 ltt_event_get_unsigned(s->parent.e, f)];
744
dc877563 745 /* Do something with the info about being in user or system mode when int? */
b445142a 746 push_state(s, LTTV_STATE_IRQ, submode);
dc877563 747 return FALSE;
748}
749
750
b445142a 751static gboolean irq_exit(void *hook_data, void *call_data)
dc877563 752{
ba576a78 753 LttvTracefileState *s = (LttvTracefileState *)call_data;
dc877563 754
ffd54a90 755 pop_state(s, LTTV_STATE_IRQ);
dc877563 756 return FALSE;
757}
758
759
b445142a 760static gboolean schedchange(void *hook_data, void *call_data)
dc877563 761{
b445142a 762 LttvTraceHook *h = (LttvTraceHook *)hook_data;
dc877563 763
ba576a78 764 LttvTracefileState *s = (LttvTracefileState *)call_data;
dc877563 765
766 guint pid_in, pid_out, state_out;
767
3d27549e 768 pid_in = ltt_event_get_unsigned(s->parent.e, h->f1);
769 pid_out = ltt_event_get_unsigned(s->parent.e, h->f2);
770 state_out = ltt_event_get_unsigned(s->parent.e, h->f3);
b445142a 771
dc877563 772 if(s->process != NULL) {
b445142a 773
ffd54a90 774 if(state_out == 0) s->process->state->s = LTTV_STATE_WAIT_CPU;
775 else if(s->process->state->s == LTTV_STATE_EXIT)
ba576a78 776 exit_process(s, s->process);
ffd54a90 777 else s->process->state->s = LTTV_STATE_WAIT;
3d27549e 778
779 if(s->process->pid == 0)
90ffd2ad 780 s->process->pid = pid_out;
b445142a 781
782 s->process->state->change = s->parent.timestamp;
dc877563 783 }
b445142a 784 s->process = lttv_state_find_process(s, pid_in);
ffd54a90 785 s->process->state->s = LTTV_STATE_RUN;
b445142a 786 s->process->state->change = s->parent.timestamp;
dc877563 787 return FALSE;
788}
789
790
b445142a 791static gboolean process_fork(void *hook_data, void *call_data)
dc877563 792{
b445142a 793 LttField *f = ((LttvTraceHook *)hook_data)->f1;
dc877563 794
ba576a78 795 LttvTracefileState *s = (LttvTracefileState *)call_data;
dc877563 796
797 guint child_pid;
798
3d27549e 799 child_pid = ltt_event_get_unsigned(s->parent.e, f);
ba576a78 800 create_process(s, s->process, child_pid);
dc877563 801 return FALSE;
802}
803
804
b445142a 805static gboolean process_exit(void *hook_data, void *call_data)
dc877563 806{
ba576a78 807 LttvTracefileState *s = (LttvTracefileState *)call_data;
dc877563 808
809 if(s->process != NULL) {
ffd54a90 810 s->process->state->s = LTTV_STATE_EXIT;
dc877563 811 }
812 return FALSE;
813}
814
815
308711e5 816void lttv_state_add_event_hooks(LttvTracesetState *self)
dc877563 817{
ba576a78 818 LttvTraceset *traceset = self->parent.ts;
dc877563 819
ba576a78 820 guint i, j, k, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
dc877563 821
ba576a78 822 LttvTraceState *ts;
dc877563 823
ba576a78 824 LttvTracefileState *tfs;
dc877563 825
dc877563 826 GArray *hooks;
827
b445142a 828 LttvTraceHook hook;
dc877563 829
830 LttvAttributeValue val;
831
ba576a78 832 nb_trace = lttv_traceset_number(traceset);
dc877563 833 for(i = 0 ; i < nb_trace ; i++) {
ba576a78 834 ts = (LttvTraceState *)self->parent.traces[i];
dc877563 835
836 /* Find the eventtype id for the following events and register the
837 associated by id hooks. */
838
b445142a 839 hooks = g_array_new(FALSE, FALSE, sizeof(LttvTraceHook));
840 g_array_set_size(hooks, 9);
841
842 lttv_trace_find_hook(ts->parent.t, "core","syscall_entry","syscall_id",
843 NULL, NULL, syscall_entry, &g_array_index(hooks, LttvTraceHook, 0));
cbe7c836 844
b445142a 845 lttv_trace_find_hook(ts->parent.t, "core", "syscall_exit", NULL, NULL,
846 NULL, syscall_exit, &g_array_index(hooks, LttvTraceHook, 1));
cbe7c836 847
b445142a 848 lttv_trace_find_hook(ts->parent.t, "core", "trap_entry", "trap_id",
849 NULL, NULL, trap_entry, &g_array_index(hooks, LttvTraceHook, 2));
cbe7c836 850
b445142a 851 lttv_trace_find_hook(ts->parent.t, "core", "trap_exit", NULL, NULL, NULL,
852 trap_exit, &g_array_index(hooks, LttvTraceHook, 3));
cbe7c836 853
b445142a 854 lttv_trace_find_hook(ts->parent.t, "core", "irq_entry", "irq_id", NULL,
855 NULL, irq_entry, &g_array_index(hooks, LttvTraceHook, 4));
cbe7c836 856
b445142a 857 lttv_trace_find_hook(ts->parent.t, "core", "irq_exit", NULL, NULL, NULL,
858 irq_exit, &g_array_index(hooks, LttvTraceHook, 5));
cbe7c836 859
b445142a 860 lttv_trace_find_hook(ts->parent.t, "core", "schedchange", "in", "out",
861 "out_state", schedchange, &g_array_index(hooks, LttvTraceHook, 6));
cbe7c836 862
b445142a 863 lttv_trace_find_hook(ts->parent.t, "core", "process_fork", "child_pid",
864 NULL, NULL, process_fork, &g_array_index(hooks, LttvTraceHook, 7));
cbe7c836 865
b445142a 866 lttv_trace_find_hook(ts->parent.t, "core", "process_exit", NULL, NULL,
867 NULL, process_exit, &g_array_index(hooks, LttvTraceHook, 8));
dc877563 868
869 /* Add these hooks to each before_event_by_id hooks list */
870
ba576a78 871 nb_control = ltt_trace_control_tracefile_number(ts->parent.t);
cbe7c836 872 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(ts->parent.t);
dc877563 873 nb_tracefile = nb_control + nb_per_cpu;
874 for(j = 0 ; j < nb_tracefile ; j++) {
875 if(j < nb_control) {
ba576a78 876 tfs = LTTV_TRACEFILE_STATE(ts->parent.control_tracefiles[j]);
dc877563 877 }
878 else {
cbe7c836 879 tfs = LTTV_TRACEFILE_STATE(ts->parent.per_cpu_tracefiles[j-nb_control]);
dc877563 880 }
881
882 for(k = 0 ; k < hooks->len ; k++) {
b445142a 883 hook = g_array_index(hooks, LttvTraceHook, k);
884 lttv_hooks_add(lttv_hooks_by_id_find(tfs->parent.after_event_by_id,
885 hook.id), hook.h, &g_array_index(hooks, LttvTraceHook, k));
ffd54a90 886 }
dc877563 887 }
ba576a78 888 lttv_attribute_find(self->parent.a, LTTV_STATE_HOOKS, LTTV_POINTER, &val);
889 *(val.v_pointer) = hooks;
dc877563 890 }
891}
892
893
308711e5 894void lttv_state_remove_event_hooks(LttvTracesetState *self)
dc877563 895{
ba576a78 896 LttvTraceset *traceset = self->parent.ts;
dc877563 897
ba576a78 898 guint i, j, k, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
dc877563 899
ba576a78 900 LttvTraceState *ts;
dc877563 901
ba576a78 902 LttvTracefileState *tfs;
dc877563 903
dc877563 904 GArray *hooks;
905
b445142a 906 LttvTraceHook hook;
dc877563 907
908 LttvAttributeValue val;
909
ba576a78 910 nb_trace = lttv_traceset_number(traceset);
dc877563 911 for(i = 0 ; i < nb_trace ; i++) {
ba576a78 912 ts = LTTV_TRACE_STATE(self->parent.traces[i]);
913 lttv_attribute_find(self->parent.a, LTTV_STATE_HOOKS, LTTV_POINTER, &val);
914 hooks = *(val.v_pointer);
dc877563 915
916 /* Add these hooks to each before_event_by_id hooks list */
917
ba576a78 918 nb_control = ltt_trace_control_tracefile_number(ts->parent.t);
cbe7c836 919 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(ts->parent.t);
dc877563 920 nb_tracefile = nb_control + nb_per_cpu;
921 for(j = 0 ; j < nb_tracefile ; j++) {
922 if(j < nb_control) {
ba576a78 923 tfs = LTTV_TRACEFILE_STATE(ts->parent.control_tracefiles[j]);
dc877563 924 }
925 else {
cbe7c836 926 tfs = LTTV_TRACEFILE_STATE(ts->parent.per_cpu_tracefiles[j-nb_control]);
dc877563 927 }
928
929 for(k = 0 ; k < hooks->len ; k++) {
b445142a 930 hook = g_array_index(hooks, LttvTraceHook, k);
ba576a78 931 lttv_hooks_remove_data(
b445142a 932 lttv_hooks_by_id_find(tfs->parent.after_event_by_id,
933 hook.id), hook.h, &g_array_index(hooks, LttvTraceHook, k));
ffd54a90 934 }
dc877563 935 }
936 g_array_free(hooks, TRUE);
937 }
938}
939
940
308711e5 941static gboolean block_end(void *hook_data, void *call_data)
942{
943 LttvTracefileState *tfcs = (LttvTracefileState *)call_data;
944
945 LttvTraceState *tcs = (LttvTraceState *)(tfcs->parent.t_context);
946
a5dcde2f 947 LttEventPosition *ep = ltt_event_position_new();
308711e5 948
949 guint nb_block, nb_event;
950
951 LttTracefile *tf;
952
953 LttvAttribute *saved_states_tree, *saved_state_tree;
954
955 LttvAttributeValue value;
956
a5dcde2f 957 ltt_event_position(tfcs->parent.e, ep);
308711e5 958
a5dcde2f 959 ltt_event_position_get(ep, &nb_block, &nb_event, &tf);
308711e5 960 tcs->nb_event += nb_event - tfcs->saved_position;
961 tfcs->saved_position = 0;
962 if(tcs->nb_event >= tcs->save_interval) {
963 saved_states_tree = lttv_attribute_find_subdir(tcs->parent.t_a,
964 LTTV_STATE_SAVED_STATES);
965 saved_state_tree = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
966 value = lttv_attribute_add(saved_states_tree,
967 lttv_attribute_get_number(saved_states_tree), LTTV_GOBJECT);
968 *(value.v_gobject) = (GObject *)saved_state_tree;
969 value = lttv_attribute_add(saved_state_tree, LTTV_STATE_TIME, LTTV_TIME);
970 *(value.v_time) = tfcs->parent.timestamp;
971 lttv_state_save(tcs, saved_state_tree);
972 tcs->nb_event = 0;
973 }
974 return FALSE;
975}
976
977
978void lttv_state_save_add_event_hooks(LttvTracesetState *self)
979{
980 LttvTraceset *traceset = self->parent.ts;
981
982 guint i, j, k, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
983
984 LttvTraceState *ts;
985
986 LttvTracefileState *tfs;
987
988 LttvTraceHook hook;
989
990 nb_trace = lttv_traceset_number(traceset);
991 for(i = 0 ; i < nb_trace ; i++) {
992 ts = (LttvTraceState *)self->parent.traces[i];
993 lttv_trace_find_hook(ts->parent.t, "core","block_end",NULL,
994 NULL, NULL, block_end, &hook);
995
996 nb_control = ltt_trace_control_tracefile_number(ts->parent.t);
997 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(ts->parent.t);
998 nb_tracefile = nb_control + nb_per_cpu;
999 for(j = 0 ; j < nb_tracefile ; j++) {
1000 if(j < nb_control) {
1001 tfs = LTTV_TRACEFILE_STATE(ts->parent.control_tracefiles[j]);
1002 }
1003 else {
1004 tfs =LTTV_TRACEFILE_STATE(ts->parent.per_cpu_tracefiles[j-nb_control]);
1005 }
1006
1007 lttv_hooks_add(lttv_hooks_by_id_find(tfs->parent.after_event_by_id,
1008 hook.id), hook.h, NULL);
1009 }
1010 }
1011}
1012
1013
1014void lttv_state_save_remove_event_hooks(LttvTracesetState *self)
1015{
1016 LttvTraceset *traceset = self->parent.ts;
1017
1018 guint i, j, k, nb_trace, nb_control, nb_per_cpu, nb_tracefile;
1019
1020 LttvTraceState *ts;
1021
1022 LttvTracefileState *tfs;
1023
1024 LttvTraceHook hook;
1025
1026 nb_trace = lttv_traceset_number(traceset);
1027 for(i = 0 ; i < nb_trace ; i++) {
1028 ts = LTTV_TRACE_STATE(self->parent.traces[i]);
1029 lttv_trace_find_hook(ts->parent.t, "core","block_end",NULL,
1030 NULL, NULL, block_end, &hook);
1031
1032 nb_control = ltt_trace_control_tracefile_number(ts->parent.t);
1033 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(ts->parent.t);
1034 nb_tracefile = nb_control + nb_per_cpu;
1035 for(j = 0 ; j < nb_tracefile ; j++) {
1036 if(j < nb_control) {
1037 tfs = LTTV_TRACEFILE_STATE(ts->parent.control_tracefiles[j]);
1038 }
1039 else {
1040 tfs =LTTV_TRACEFILE_STATE(ts->parent.per_cpu_tracefiles[j-nb_control]);
1041 }
1042
1043 lttv_hooks_remove_data(lttv_hooks_by_id_find(
1044 tfs->parent.after_event_by_id, hook.id), hook.h, NULL);
1045 }
1046 }
1047}
1048
1049
dd025f91 1050void lttv_state_traceset_seek_time_closest(LttvTracesetState *self, LttTime t)
308711e5 1051{
1052 LttvTraceset *traceset = self->parent.ts;
1053
1054 guint i, j, nb_trace, nb_saved_state;
1055
1056 int min_pos, mid_pos, max_pos;
1057
1058 LttvTraceState *tcs;
1059
1060 LttvAttributeValue value;
1061
1062 LttvAttributeType type;
1063
1064 LttvAttributeName name;
1065
1066 LttvAttribute *saved_states_tree, *saved_state_tree, *closest_tree;
1067
1068 nb_trace = lttv_traceset_number(traceset);
1069 for(i = 0 ; i < nb_trace ; i++) {
1070 tcs = (LttvTraceState *)self->parent.traces[i];
1071
dd025f91 1072 if(tcs->recompute_state_in_seek) {
1073 if(tcs->saved_state_available) {
1074 saved_states_tree = lttv_attribute_find_subdir(tcs->parent.t_a,
1075 LTTV_STATE_SAVED_STATES);
1076 min_pos = -1;
1077 max_pos = lttv_attribute_get_number(saved_states_tree) - 1;
1078 mid_pos = max_pos / 2;
1079 while(min_pos < max_pos) {
1080 type = lttv_attribute_get(saved_states_tree, mid_pos, &name, &value);
1081 g_assert(type == LTTV_GOBJECT);
1082 saved_state_tree = *((LttvAttribute **)(value.v_gobject));
1083 type = lttv_attribute_get_by_name(saved_state_tree, LTTV_STATE_TIME,
1084 &value);
1085 g_assert(type == LTTV_TIME);
1086 if(ltt_time_compare(*(value.v_time), t) < 0) {
1087 min_pos = mid_pos;
1088 closest_tree = saved_state_tree;
1089 }
1090 else max_pos = mid_pos - 1;
1091
1092 mid_pos = (min_pos + max_pos + 1) / 2;
1093 }
1094
1095 /* restore the closest earlier saved state */
1096 if(min_pos != -1) lttv_state_restore(tcs, closest_tree);
1097
9444deae 1098 }
dd025f91 1099 /* There is no saved state yet we want to have it. Restart at T0 */
1100 else {
1101 restore_init_state(tcs);
1102 lttv_process_trace_seek_time(&(tcs->parent), ltt_time_zero);
308711e5 1103 }
9444deae 1104 }
dd025f91 1105 /* We want to seek quickly without restoring/updating the state */
1106 else {
308711e5 1107 restore_init_state(tcs);
dd025f91 1108 lttv_process_trace_seek_time(&(tcs->parent), t);
308711e5 1109 }
308711e5 1110 }
1111}
1112
1113
1114static void
1115traceset_state_instance_init (GTypeInstance *instance, gpointer g_class)
1116{
1117}
1118
1119
1120static void
1121traceset_state_finalize (LttvTracesetState *self)
1122{
1123 G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACESET_CONTEXT_TYPE))->
1124 finalize(G_OBJECT(self));
1125}
1126
1127
1128static void
1129traceset_state_class_init (LttvTracesetContextClass *klass)
1130{
1131 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
1132
1133 gobject_class->finalize = (void (*)(GObject *self)) traceset_state_finalize;
1134 klass->init = (void (*)(LttvTracesetContext *self, LttvTraceset *ts))init;
1135 klass->fini = (void (*)(LttvTracesetContext *self))fini;
1136 klass->new_traceset_context = new_traceset_context;
1137 klass->new_trace_context = new_trace_context;
1138 klass->new_tracefile_context = new_tracefile_context;
1139}
1140
1141
1142GType
1143lttv_traceset_state_get_type(void)
1144{
1145 static GType type = 0;
1146 if (type == 0) {
1147 static const GTypeInfo info = {
1148 sizeof (LttvTracesetStateClass),
1149 NULL, /* base_init */
1150 NULL, /* base_finalize */
1151 (GClassInitFunc) traceset_state_class_init, /* class_init */
1152 NULL, /* class_finalize */
1153 NULL, /* class_data */
1154 sizeof (LttvTracesetContext),
1155 0, /* n_preallocs */
1156 (GInstanceInitFunc) traceset_state_instance_init /* instance_init */
1157 };
1158
1159 type = g_type_register_static (LTTV_TRACESET_CONTEXT_TYPE, "LttvTracesetStateType",
1160 &info, 0);
1161 }
1162 return type;
1163}
1164
1165
1166static void
1167trace_state_instance_init (GTypeInstance *instance, gpointer g_class)
1168{
1169}
1170
1171
1172static void
1173trace_state_finalize (LttvTraceState *self)
1174{
1175 G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACE_CONTEXT_TYPE))->
1176 finalize(G_OBJECT(self));
1177}
1178
1179
1180static void
1181trace_state_class_init (LttvTraceStateClass *klass)
1182{
1183 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
1184
1185 gobject_class->finalize = (void (*)(GObject *self)) trace_state_finalize;
1186 klass->state_save = state_save;
1187 klass->state_restore = state_restore;
1188 klass->state_saved_free = state_saved_free;
1189}
1190
1191
1192GType
1193lttv_trace_state_get_type(void)
1194{
1195 static GType type = 0;
1196 if (type == 0) {
1197 static const GTypeInfo info = {
1198 sizeof (LttvTraceStateClass),
1199 NULL, /* base_init */
1200 NULL, /* base_finalize */
1201 (GClassInitFunc) trace_state_class_init, /* class_init */
1202 NULL, /* class_finalize */
1203 NULL, /* class_data */
1204 sizeof (LttvTraceState),
1205 0, /* n_preallocs */
1206 (GInstanceInitFunc) trace_state_instance_init /* instance_init */
1207 };
1208
1209 type = g_type_register_static (LTTV_TRACE_CONTEXT_TYPE,
1210 "LttvTraceStateType", &info, 0);
1211 }
1212 return type;
1213}
1214
1215
1216static void
1217tracefile_state_instance_init (GTypeInstance *instance, gpointer g_class)
1218{
1219}
1220
1221
1222static void
1223tracefile_state_finalize (LttvTracefileState *self)
1224{
1225 G_OBJECT_CLASS(g_type_class_peek(LTTV_TRACEFILE_CONTEXT_TYPE))->
1226 finalize(G_OBJECT(self));
1227}
1228
1229
1230static void
1231tracefile_state_class_init (LttvTracefileStateClass *klass)
1232{
1233 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
1234
1235 gobject_class->finalize = (void (*)(GObject *self)) tracefile_state_finalize;
1236}
1237
1238
1239GType
1240lttv_tracefile_state_get_type(void)
1241{
1242 static GType type = 0;
1243 if (type == 0) {
1244 static const GTypeInfo info = {
1245 sizeof (LttvTracefileStateClass),
1246 NULL, /* base_init */
1247 NULL, /* base_finalize */
1248 (GClassInitFunc) tracefile_state_class_init, /* class_init */
1249 NULL, /* class_finalize */
1250 NULL, /* class_data */
1251 sizeof (LttvTracefileState),
1252 0, /* n_preallocs */
1253 (GInstanceInitFunc) tracefile_state_instance_init /* instance_init */
1254 };
1255
1256 type = g_type_register_static (LTTV_TRACEFILE_CONTEXT_TYPE,
1257 "LttvTracefileStateType", &info, 0);
1258 }
1259 return type;
1260}
1261
1262
ffd54a90 1263void lttv_state_init(int argc, char **argv)
1264{
1265 LTTV_STATE_UNNAMED = g_quark_from_string("unnamed");
b445142a 1266 LTTV_STATE_MODE_UNKNOWN = g_quark_from_string("unknown execution mode");
ffd54a90 1267 LTTV_STATE_USER_MODE = g_quark_from_string("user mode");
1268 LTTV_STATE_WAIT_FORK = g_quark_from_string("wait fork");
1269 LTTV_STATE_SYSCALL = g_quark_from_string("system call");
1270 LTTV_STATE_TRAP = g_quark_from_string("trap");
1271 LTTV_STATE_IRQ = g_quark_from_string("irq");
b445142a 1272 LTTV_STATE_SUBMODE_UNKNOWN = g_quark_from_string("unknown submode");
1273 LTTV_STATE_SUBMODE_NONE = g_quark_from_string("(no submode)");
ffd54a90 1274 LTTV_STATE_WAIT_CPU = g_quark_from_string("wait for cpu");
1275 LTTV_STATE_EXIT = g_quark_from_string("exiting");
1276 LTTV_STATE_WAIT = g_quark_from_string("wait for I/O");
1277 LTTV_STATE_RUN = g_quark_from_string("running");
308711e5 1278 LTTV_STATE_TRACEFILES = g_quark_from_string("tracefiles");
1279 LTTV_STATE_PROCESSES = g_quark_from_string("processes");
1280 LTTV_STATE_PROCESS = g_quark_from_string("process");
1281 LTTV_STATE_EVENT = g_quark_from_string("event");
1282 LTTV_STATE_SAVED_STATES = g_quark_from_string("saved states");
1283 LTTV_STATE_TIME = g_quark_from_string("time");
ffd54a90 1284 LTTV_STATE_HOOKS = g_quark_from_string("saved state hooks");
1285}
dc877563 1286
ffd54a90 1287void lttv_state_destroy()
1288{
1289}
dc877563 1290
1291
1292
1293
This page took 0.084799 seconds and 4 git commands to generate.