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