* MA 02111-1307, USA.
*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
#include <lttv/lttv.h>
#include <lttv/module.h>
#include <ltt/type.h>
#include <stdio.h>
+#define PREALLOCATED_EXECUTION_STACK 10
+
+/* Facilities Quarks */
+
+GQuark
+ LTT_FACILITY_KERNEL,
+ LTT_FACILITY_PROCESS;
+
+/* Events Quarks */
+
+GQuark
+ LTT_EVENT_SYSCALL_ENTRY,
+ LTT_EVENT_SYSCALL_EXIT,
+ LTT_EVENT_TRAP_ENTRY,
+ LTT_EVENT_TRAP_EXIT,
+ LTT_EVENT_IRQ_ENTRY,
+ LTT_EVENT_IRQ_EXIT,
+ LTT_EVENT_SCHEDCHANGE,
+ LTT_EVENT_FORK,
+ LTT_EVENT_EXIT,
+ LTT_EVENT_FREE;
+
+/* Fields Quarks */
+
+GQuark
+ LTT_FIELD_SYSCALL_ID,
+ LTT_FIELD_TRAP_ID,
+ LTT_FIELD_IRQ_ID,
+ LTT_FIELD_OUT,
+ LTT_FIELD_IN,
+ LTT_FIELD_OUT_STATE,
+ LTT_FIELD_PARENT_PID,
+ LTT_FIELD_CHILD_PID,
+ LTT_FIELD_PID;
+
LttvExecutionMode
LTTV_STATE_MODE_UNKNOWN,
LTTV_STATE_USER_MODE,
LTTV_STATE_WAIT_FORK,
LTTV_STATE_WAIT_CPU,
LTTV_STATE_EXIT,
+ LTTV_STATE_ZOMBIE,
LTTV_STATE_WAIT,
LTTV_STATE_RUN;
LTTV_STATE_NAME_TABLES,
LTTV_STATE_TRACE_STATE_USE_COUNT;
-
static void create_max_time(LttvTraceState *tcs);
static void get_max_time(LttvTraceState *tcs);
}
-void lttv_state__state_saved_free(LttvTraceState *self,
+void lttv_state_state_saved_free(LttvTraceState *self,
LttvAttribute *container)
{
LTTV_TRACE_STATE_GET_CLASS(self)->state_saved_free(self, container);
guint process_hash(gconstpointer key)
{
- return ((LttvProcessState *)key)->pid;
+ guint pid = ((const LttvProcessState *)key)->pid;
+ return (pid>>8 ^ pid>>4 ^ pid>>2 ^ pid) ;
}
+/* If the hash table hash function is well distributed,
+ * the process_equal should compare different pid */
gboolean process_equal(gconstpointer a, gconstpointer b)
{
- LttvProcessState *process_a, *process_b;
-
- process_a = (LttvProcessState *)a;
- process_b = (LttvProcessState *)b;
+ const LttvProcessState *process_a, *process_b;
+ gboolean ret = TRUE;
+
+ process_a = (const LttvProcessState *)a;
+ process_b = (const LttvProcessState *)b;
+
+ if(likely(process_a->pid != process_b->pid)) ret = FALSE;
+ else if(likely(process_a->pid == 0 &&
+ process_a->last_cpu != process_b->last_cpu)) ret = FALSE;
- if(process_a->pid != process_b->pid) return FALSE;
- if(process_a->pid == 0 &&
- process_a->last_cpu != process_b->last_cpu) return FALSE;
- return TRUE;
+ return ret;
}
LttvTracefileState *tfcs;
- LttTime null_time = {0,0};
-
if(self->processes != NULL) lttv_state_free_process_table(self->processes);
self->processes = g_hash_table_new(process_hash, process_equal);
self->nb_event = 0;
- nb_tracefile = ltt_trace_control_tracefile_number(self->parent.t) +
- ltt_trace_per_cpu_tracefile_number(self->parent.t);
+ nb_tracefile = self->parent.tracefiles->len;
for(i = 0 ; i < nb_tracefile ; i++) {
- tfcs = LTTV_TRACEFILE_STATE(self->parent.tracefiles[i]);
- tfcs->parent.timestamp = null_time;
- tfcs->saved_position = 0;
+ tfcs =
+ LTTV_TRACEFILE_STATE(g_array_index(self->parent.tracefiles,
+ LttvTracefileContext*, i));
+ ltt_trace_time_span_get(self->parent.t, &tfcs->parent.timestamp, NULL);
+// tfcs->saved_position = 0;
tfcs->process = lttv_state_create_process(tfcs, NULL,0);
tfcs->process->state->s = LTTV_STATE_RUN;
tfcs->process->last_cpu = tfcs->cpu_name;
+ tfcs->process->last_cpu_index = ltt_tracefile_num(((LttvTracefileContext*)tfcs)->tf);
}
}
nb_trace = lttv_traceset_number(ts);
for(i = 0 ; i < nb_trace ; i++) {
tc = self->parent.traces[i];
- tcs = (LttvTraceState *)tc;
- tcs->save_interval = 50000;
+ tcs = LTTV_TRACE_STATE(tc);
+ tcs->save_interval = LTTV_STATE_SAVE_INTERVAL;
lttv_attribute_find(tcs->parent.t_a, LTTV_STATE_TRACE_STATE_USE_COUNT,
LTTV_UINT, &v);
(*v.v_uint)++;
get_name_tables(tcs);
get_max_time(tcs);
- nb_tracefile = ltt_trace_control_tracefile_number(tc->t) +
- ltt_trace_per_cpu_tracefile_number(tc->t);
+ nb_tracefile = tc->tracefiles->len;
for(j = 0 ; j < nb_tracefile ; j++) {
- tfcs = LTTV_TRACEFILE_STATE(tc->tracefiles[j]);
- tfcs->cpu_name= g_quark_from_string(ltt_tracefile_name(tfcs->parent.tf));
+ tfcs =
+ LTTV_TRACEFILE_STATE(g_array_index(tc->tracefiles,
+ LttvTracefileContext*, j));
+ tfcs->cpu_name = ltt_tracefile_name(tfcs->parent.tf);
}
tcs->processes = NULL;
restore_init_state(tcs);
static void
fini(LttvTracesetState *self)
{
- guint i, j, nb_trace;
+ guint i, nb_trace;
LttvTraceState *tcs;
tcs = (LttvTraceState *)(LTTV_TRACESET_CONTEXT(self)->traces[i]);
lttv_attribute_find(tcs->parent.t_a, LTTV_STATE_TRACE_STATE_USE_COUNT,
LTTV_UINT, &v);
+
+ g_assert(*(v.v_uint) != 0);
(*v.v_uint)--;
- g_assert(*(v.v_uint) >= 0);
if(*(v.v_uint) == 0) {
free_name_tables(tcs);
free_max_time(tcs);
void lttv_state_write(LttvTraceState *self, LttTime t, FILE *fp)
{
- guint i, nb_tracefile, nb_block, nb_event;
+ guint i, nb_tracefile, nb_block, offset;
+ guint64 tsc;
LttvTracefileState *tfcs;
g_hash_table_foreach(self->processes, write_process_state, fp);
- nb_tracefile = ltt_trace_control_tracefile_number(self->parent.t) +
- ltt_trace_per_cpu_tracefile_number(self->parent.t);
+ nb_tracefile = self->parent.tracefiles->len;
for(i = 0 ; i < nb_tracefile ; i++) {
- tfcs = (LttvTracefileState *)self->parent.tracefiles[i];
+ tfcs =
+ LTTV_TRACEFILE_STATE(g_array_index(self->parent.tracefiles,
+ LttvTracefileContext*, i));
fprintf(fp, " <TRACEFILE PID=%u TIMESTAMP_S=%lu TIMESTAMP_NS=%lu",
tfcs->process->pid, tfcs->parent.timestamp.tv_sec,
tfcs->parent.timestamp.tv_nsec);
- if(tfcs->parent.e == NULL) fprintf(fp,"/>\n");
+ LttEvent *e = ltt_tracefile_get_event(tfcs->parent.tf);
+ if(e == NULL) fprintf(fp,"/>\n");
else {
- ltt_event_position(tfcs->parent.e, ep);
- ltt_event_position_get(ep, &nb_block, &nb_event, &tf);
- fprintf(fp, " BLOCK=%u EVENT=%u/>\n", nb_block, nb_event);
+ ltt_event_position(e, ep);
+ ltt_event_position_get(ep, &tf, &nb_block, &offset, &tsc);
+ fprintf(fp, " BLOCK=%u OFFSET=%u TSC=%llu/>\n", nb_block, offset,
+ tsc);
}
}
g_free(ep);
process = (LttvProcessState *)value;
new_process = g_new(LttvProcessState, 1);
*new_process = *process;
- new_process->execution_stack = g_array_new(FALSE, FALSE,
- sizeof(LttvExecutionState));
- g_array_set_size(new_process->execution_stack,process->execution_stack->len);
+ new_process->execution_stack = g_array_sized_new(FALSE, FALSE,
+ sizeof(LttvExecutionState), PREALLOCATED_EXECUTION_STACK);
+ new_process->execution_stack =
+ g_array_set_size(new_process->execution_stack,
+ process->execution_stack->len);
for(i = 0 ; i < process->execution_stack->len; i++) {
g_array_index(new_process->execution_stack, LttvExecutionState, i) =
g_array_index(process->execution_stack, LttvExecutionState, i);
LTTV_POINTER);
*(value.v_pointer) = lttv_state_copy_process_table(self->processes);
- nb_tracefile = ltt_trace_control_tracefile_number(self->parent.t) +
- ltt_trace_per_cpu_tracefile_number(self->parent.t);
+ nb_tracefile = self->parent.tracefiles->len;
for(i = 0 ; i < nb_tracefile ; i++) {
- tfcs = (LttvTracefileState *)self->parent.tracefiles[i];
+ tfcs =
+ LTTV_TRACEFILE_STATE(g_array_index(self->parent.tracefiles,
+ LttvTracefileContext*, i));
tracefile_tree = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
value = lttv_attribute_add(tracefiles_tree, i,
LTTV_GOBJECT);
*(value.v_uint) = tfcs->process->pid;
value = lttv_attribute_add(tracefile_tree, LTTV_STATE_EVENT,
LTTV_POINTER);
- if(tfcs->parent.e == NULL) *(value.v_pointer) = NULL;
- else {
+ /* Only save the position of the tfs is in the pqueue */
+ if(!g_tree_lookup(self->parent.ts_context->pqueue, &tfcs->parent)) {
+ *(value.v_pointer) = NULL;
+ } else {
+ LttEvent *e = ltt_tracefile_get_event(tfcs->parent.tf);
ep = ltt_event_position_new();
- ltt_event_position(tfcs->parent.e, ep);
+ ltt_event_position(e, ep);
*(value.v_pointer) = ep;
- guint nb_block, nb_event;
+ guint nb_block, offset;
+ guint64 tsc;
LttTracefile *tf;
- ltt_event_position_get(ep, &nb_block, &nb_event, &tf);
- g_debug("Block %u event %u time %lu.%lu", nb_block, nb_event,
+ ltt_event_position_get(ep, &tf, &nb_block, &offset, &tsc);
+ g_debug("Block %u offset %u tsc %llu time %lu.%lu", nb_block, offset,
+ tsc,
tfcs->parent.timestamp.tv_sec, tfcs->parent.timestamp.tv_nsec);
}
}
LttEventPosition *ep;
+ LttvTracesetContext *tsc = self->parent.ts_context;
+
tracefiles_tree = lttv_attribute_find_subdir(container,
LTTV_STATE_TRACEFILES);
lttv_state_free_process_table(self->processes);
self->processes = lttv_state_copy_process_table(*(value.v_pointer));
- nb_tracefile = ltt_trace_control_tracefile_number(self->parent.t) +
- ltt_trace_per_cpu_tracefile_number(self->parent.t);
+ nb_tracefile = self->parent.tracefiles->len;
+ g_tree_destroy(tsc->pqueue);
+ tsc->pqueue = g_tree_new(compare_tracefile);
+
for(i = 0 ; i < nb_tracefile ; i++) {
- tfcs = (LttvTracefileState *)self->parent.tracefiles[i];
+ tfcs =
+ LTTV_TRACEFILE_STATE(g_array_index(self->parent.tracefiles,
+ LttvTracefileContext*, i));
type = lttv_attribute_get(tracefiles_tree, i, &name, &value);
g_assert(type == LTTV_GOBJECT);
tracefile_tree = *((LttvAttribute **)(value.v_gobject));
type = lttv_attribute_get_by_name(tracefile_tree, LTTV_STATE_EVENT,
&value);
g_assert(type == LTTV_POINTER);
- if(*(value.v_pointer) == NULL) tfcs->parent.e = NULL;
- else {
- ep = *(value.v_pointer);
- ltt_tracefile_seek_position(tfcs->parent.tf, ep);
- tfcs->parent.e = ltt_tracefile_read(tfcs->parent.tf);
- tfcs->parent.timestamp = ltt_event_time(tfcs->parent.e);
+ //g_assert(*(value.v_pointer) != NULL);
+ ep = *(value.v_pointer);
+ g_assert(tfcs->parent.t_context != NULL);
+
+ LttvTracefileContext *tfc = LTTV_TRACEFILE_CONTEXT(tfcs);
+
+ if(ep != NULL) {
+ g_assert(ltt_tracefile_seek_position(tfc->tf, ep) == 0);
+ tfc->timestamp = ltt_event_time(ltt_tracefile_get_event(tfc->tf));
+ g_assert(ltt_time_compare(tfc->timestamp, ltt_time_infinite) != 0);
+ g_tree_insert(tsc->pqueue, tfc, tfc);
+ } else {
+ tfc->timestamp = ltt_time_infinite;
}
}
}
tracefiles_tree = lttv_attribute_find_subdir(container,
LTTV_STATE_TRACEFILES);
+ g_object_ref(G_OBJECT(tracefiles_tree));
lttv_attribute_remove_by_name(container, LTTV_STATE_TRACEFILES);
type = lttv_attribute_get_by_name(container, LTTV_STATE_PROCESSES,
*(value.v_pointer) = NULL;
lttv_attribute_remove_by_name(container, LTTV_STATE_PROCESSES);
- nb_tracefile = ltt_trace_control_tracefile_number(self->parent.t) +
- ltt_trace_per_cpu_tracefile_number(self->parent.t);
+ nb_tracefile = self->parent.tracefiles->len;
for(i = 0 ; i < nb_tracefile ; i++) {
- tfcs = (LttvTracefileState *)self->parent.tracefiles[i];
+ tfcs =
+ LTTV_TRACEFILE_STATE(g_array_index(self->parent.tracefiles,
+ LttvTracefileContext*, i));
type = lttv_attribute_get(tracefiles_tree, i, &name, &value);
g_assert(type == LTTV_GOBJECT);
tracefile_tree = *((LttvAttribute **)(value.v_gobject));
g_assert(type == LTTV_POINTER);
if(*(value.v_pointer) != NULL) g_free(*(value.v_pointer));
}
- lttv_attribute_recursive_free(tracefiles_tree);
+ g_object_unref(G_OBJECT(tracefiles_tree));
}
}
lttv_attribute_remove_by_name(self->parent.t_a, LTTV_STATE_SAVED_STATES);
- lttv_attribute_recursive_free(saved_states);
}
typedef struct _LttvNameTables {
- GQuark *eventtype_names;
+ // FIXME GQuark *eventtype_names;
GQuark *syscall_names;
GQuark *trap_names;
GQuark *irq_names;
{
int i, nb;
- char *f_name, *e_name;
+ GQuark f_name, e_name;
LttvTraceHook h;
+ LttvTraceHookByFacility *thf;
+
LttEventType *et;
LttType *t;
LTTV_POINTER, &v);
g_assert(*(v.v_pointer) == NULL);
*(v.v_pointer) = name_tables;
-
+#if 0 // Use iteration over the facilities_by_name and then list all event
+ // types of each facility
nb = ltt_trace_eventtype_number(tcs->parent.t);
name_tables->eventtype_names = g_new(GQuark, nb);
for(i = 0 ; i < nb ; i++) {
g_string_printf(fe_name, "%s.%s", f_name, e_name);
name_tables->eventtype_names[i] = g_quark_from_string(fe_name->str);
}
-
- lttv_trace_find_hook(tcs->parent.t, "core", "syscall_entry",
- "syscall_id", NULL, NULL, NULL, &h);
- t = ltt_field_type(h.f1);
+#endif //0
+ if(lttv_trace_find_hook(tcs->parent.t,
+ LTT_FACILITY_KERNEL, LTT_EVENT_SYSCALL_ENTRY,
+ LTT_FIELD_SYSCALL_ID, 0, 0,
+ NULL, NULL, &h))
+ return;
+
+ thf = lttv_trace_hook_get_first(&h);
+
+ t = ltt_field_type(thf->f1);
nb = ltt_type_element_number(t);
+
+ lttv_trace_hook_destroy(&h);
- /* CHECK syscalls should be an emun but currently are not!
+ /* CHECK syscalls should be an enum but currently are not!
name_tables->syscall_names = g_new(GQuark, nb);
for(i = 0 ; i < nb ; i++) {
name_tables->syscall_names[i] = g_quark_from_string(fe_name->str);
}
- lttv_trace_find_hook(tcs->parent.t, "core", "trap_entry",
- "trap_id", NULL, NULL, NULL, &h);
- t = ltt_field_type(h.f1);
+ if(lttv_trace_find_hook(tcs->parent.t, LTT_FACILITY_KERNEL,
+ LTT_EVENT_TRAP_ENTRY,
+ LTT_FIELD_TRAP_ID, 0, 0,
+ NULL, NULL, &h))
+ return;
+
+ thf = lttv_trace_hook_get_first(&h);
+
+ t = ltt_field_type(thf->f1);
nb = ltt_type_element_number(t);
+ lttv_trace_hook_destroy(&h);
+
/*
name_tables->trap_names = g_new(GQuark, nb);
for(i = 0 ; i < nb ; i++) {
name_tables->trap_names[i] = g_quark_from_string(fe_name->str);
}
- lttv_trace_find_hook(tcs->parent.t, "core", "irq_entry",
- "irq_id", NULL, NULL, NULL, &h);
- t = ltt_field_type(h.f1);
+ if(lttv_trace_find_hook(tcs->parent.t,
+ LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_ENTRY,
+ LTT_FIELD_IRQ_ID, 0, 0,
+ NULL, NULL, &h))
+ return;
+
+ thf = lttv_trace_hook_get_first(&h);
+
+ t = ltt_field_type(thf->f1);
nb = ltt_type_element_number(t);
+ lttv_trace_hook_destroy(&h);
+
/*
name_tables->irq_names = g_new(GQuark, nb);
for(i = 0 ; i < nb ; i++) {
LTTV_POINTER, &v);
g_assert(*(v.v_pointer) != NULL);
name_tables = (LttvNameTables *)*(v.v_pointer);
- tcs->eventtype_names = name_tables->eventtype_names;
+ //tcs->eventtype_names = name_tables->eventtype_names;
tcs->syscall_names = name_tables->syscall_names;
tcs->trap_names = name_tables->trap_names;
tcs->irq_names = name_tables->irq_names;
name_tables = (LttvNameTables *)*(v.v_pointer);
*(v.v_pointer) = NULL;
- g_free(name_tables->eventtype_names);
+ // g_free(name_tables->eventtype_names);
g_free(name_tables->syscall_names);
g_free(name_tables->trap_names);
g_free(name_tables->irq_names);
g_free(name_tables);
}
-
static void push_state(LttvTracefileState *tfs, LttvExecutionMode t,
guint state_id)
{
guint depth = process->execution_stack->len;
- g_array_set_size(process->execution_stack, depth + 1);
+ process->execution_stack =
+ g_array_set_size(process->execution_stack, depth + 1);
+ /* Keep in sync */
+ process->state =
+ &g_array_index(process->execution_stack, LttvExecutionState, depth - 1);
+
es = &g_array_index(process->execution_stack, LttvExecutionState, depth);
es->t = t;
es->n = state_id;
guint depth = process->execution_stack->len;
if(process->state->t != t){
- g_info("Different execution mode type (%d.%09d): ignore it\n",
+ g_info("Different execution mode type (%lu.%09lu): ignore it\n",
tfs->parent.timestamp.tv_sec, tfs->parent.timestamp.tv_nsec);
g_info("process state has %s when pop_int is %s\n",
g_quark_to_string(process->state->t),
}
if(depth == 1){
- g_info("Trying to pop last state on stack (%d.%09d): ignore it\n",
+ g_info("Trying to pop last state on stack (%lu.%09lu): ignore it\n",
tfs->parent.timestamp.tv_sec, tfs->parent.timestamp.tv_nsec);
return;
}
- g_array_set_size(process->execution_stack, depth - 1);
+ process->execution_stack =
+ g_array_set_size(process->execution_stack, depth - 1);
process->state = &g_array_index(process->execution_stack, LttvExecutionState,
depth - 2);
process->state->change = tfs->parent.timestamp;
char buffer[128];
- tcs = ((LttvTraceState *)tc = tfs->parent.t_context);
+ tc = tfs->parent.t_context;
+ tcs = (LttvTraceState *)tc;
process->pid = pid;
process->last_cpu = tfs->cpu_name;
- g_warning("Process %u, core %p", process->pid, process);
+ process->last_cpu_index = ltt_tracefile_num(((LttvTracefileContext*)tfs)->tf);
+ g_info("Process %u, core %p", process->pid, process);
g_hash_table_insert(tcs->processes, process, process);
if(parent) {
process->creation_time.tv_nsec);
process->pid_time = g_quark_from_string(buffer);
process->last_cpu = tfs->cpu_name;
- process->execution_stack = g_array_new(FALSE, FALSE,
- sizeof(LttvExecutionState));
- g_array_set_size(process->execution_stack, 1);
+ process->last_cpu_index = ltt_tracefile_num(((LttvTracefileContext*)tfs)->tf);
+ process->execution_stack = g_array_sized_new(FALSE, FALSE,
+ sizeof(LttvExecutionState), PREALLOCATED_EXECUTION_STACK);
+ process->execution_stack = g_array_set_size(process->execution_stack, 1);
es = process->state = &g_array_index(process->execution_stack,
LttvExecutionState, 0);
es->t = LTTV_STATE_USER_MODE;
es->n = LTTV_STATE_SUBMODE_NONE;
es->entry = tfs->parent.timestamp;
+ g_assert(tfs->parent.timestamp.tv_sec != 0);
es->change = tfs->parent.timestamp;
es->s = LTTV_STATE_WAIT_FORK;
return process;
}
-
-LttvProcessState *
-lttv_state_find_process_from_trace(LttvTraceState *ts, GQuark cpu, guint pid)
+LttvProcessState *lttv_state_find_process(LttvTracefileState *tfs,
+ guint pid)
{
LttvProcessState key;
LttvProcessState *process;
+ LttvTraceState* ts = (LttvTraceState*)tfs->parent.t_context;
+
key.pid = pid;
- key.last_cpu = cpu;
+ key.last_cpu = tfs->cpu_name;
process = g_hash_table_lookup(ts->processes, &key);
return process;
}
-
-LttvProcessState *lttv_state_find_process(LttvTracefileState *tfs,
- guint pid)
-{
- LttvTraceState *ts =(LttvTraceState *)tfs->parent.t_context;
- return lttv_state_find_process_from_trace(ts, tfs->cpu_name, pid);
-}
-
-
LttvProcessState *
lttv_state_find_process_or_create(LttvTracefileState *tfs, guint pid)
{
LttvProcessState *process = lttv_state_find_process(tfs, pid);
- if(process == NULL) process = lttv_state_create_process(tfs, NULL, pid);
+ if(unlikely(process == NULL)) process = lttv_state_create_process(tfs, NULL, pid);
return process;
}
-
+/* FIXME : this function should be called when we receive an event telling that
+ * release_task has been called in the kernel. In happens generally when
+ * the parent waits for its child terminaison, but may also happen in special
+ * cases in the child's exit : when the parent ignores its children SIGCCHLD or
+ * has the flag SA_NOCLDWAIT. It can also happen when the child is part
+ * of a killed thread ground, but isn't the leader.
+ */
static void exit_process(LttvTracefileState *tfs, LttvProcessState *process)
{
LttvTraceState *ts = LTTV_TRACE_STATE(tfs->parent.t_context);
static gboolean syscall_entry(void *hook_data, void *call_data)
{
- LttField *f = ((LttvTraceHook *)hook_data)->f1;
-
LttvTracefileState *s = (LttvTracefileState *)call_data;
+ LttEvent *e = ltt_tracefile_get_event(s->parent.tf);
+ LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
+ LttField *f = thf->f1;
LttvExecutionSubmode submode;
submode = ((LttvTraceState *)(s->parent.t_context))->syscall_names[
- ltt_event_get_unsigned(s->parent.e, f)];
+ ltt_event_get_unsigned(e, f)];
push_state(s, LTTV_STATE_SYSCALL, submode);
return FALSE;
}
static gboolean trap_entry(void *hook_data, void *call_data)
{
- LttField *f = ((LttvTraceHook *)hook_data)->f1;
-
LttvTracefileState *s = (LttvTracefileState *)call_data;
+ LttEvent *e = ltt_tracefile_get_event(s->parent.tf);
+ LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
+ LttField *f = thf->f1;
LttvExecutionSubmode submode;
submode = ((LttvTraceState *)(s->parent.t_context))->trap_names[
- ltt_event_get_unsigned(s->parent.e, f)];
+ ltt_event_get_unsigned(e, f)];
push_state(s, LTTV_STATE_TRAP, submode);
return FALSE;
}
static gboolean irq_entry(void *hook_data, void *call_data)
{
- LttField *f = ((LttvTraceHook *)hook_data)->f1;
-
LttvTracefileState *s = (LttvTracefileState *)call_data;
+ LttEvent *e = ltt_tracefile_get_event(s->parent.tf);
+ guint8 fac_id = ltt_event_facility_id(e);
+ guint8 ev_id = ltt_event_eventtype_id(e);
+ LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
+ // g_assert(lttv_trace_hook_get_first((LttvTraceHook *)hook_data)->f1 != NULL);
+ g_assert(thf->f1 != NULL);
+ // g_assert(thf == lttv_trace_hook_get_first((LttvTraceHook *)hook_data));
+ LttField *f = thf->f1;
LttvExecutionSubmode submode;
submode = ((LttvTraceState *)(s->parent.t_context))->irq_names[
- ltt_event_get_unsigned(s->parent.e, f)];
+ ltt_event_get_unsigned(e, f)];
/* Do something with the info about being in user or system mode when int? */
push_state(s, LTTV_STATE_IRQ, submode);
static gboolean schedchange(void *hook_data, void *call_data)
{
- LttvTraceHook *h = (LttvTraceHook *)hook_data;
-
LttvTracefileState *s = (LttvTracefileState *)call_data;
+ LttEvent *e = ltt_tracefile_get_event(s->parent.tf);
+ LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
+ guint pid_in, pid_out;
+ gint state_out;
- guint pid_in, pid_out, state_out;
-
- pid_in = ltt_event_get_unsigned(s->parent.e, h->f1);
- pid_out = ltt_event_get_unsigned(s->parent.e, h->f2);
- state_out = ltt_event_get_unsigned(s->parent.e, h->f3);
+ pid_out = ltt_event_get_unsigned(e, thf->f1);
+ pid_in = ltt_event_get_unsigned(e, thf->f2);
+ state_out = ltt_event_get_int(e, thf->f3);
- if(s->process != NULL) {
+ if(likely(s->process != NULL)) {
/* We could not know but it was not the idle process executing.
This should only happen at the beginning, before the first schedule
is missing. It is not obvious how we could, after the fact, compensate
the wrongly attributed statistics. */
- if(s->process->pid != pid_out) {
- g_assert(s->process->pid == 0);
- }
-
- if(state_out == 0) s->process->state->s = LTTV_STATE_WAIT_CPU;
- else if(s->process->state->s == LTTV_STATE_EXIT)
- exit_process(s, s->process);
- else s->process->state->s = LTTV_STATE_WAIT;
+ //This test only makes sense once the state is known and if there is no
+ //missing events.
+ //if(unlikely(s->process->pid != pid_out)) {
+ // g_assert(s->process->pid == 0);
+ //}
+
+ if(unlikely(s->process->state->s == LTTV_STATE_EXIT)) {
+ s->process->state->s = LTTV_STATE_ZOMBIE;
+ } else {
+ if(unlikely(state_out == 0)) s->process->state->s = LTTV_STATE_WAIT_CPU;
+ else s->process->state->s = LTTV_STATE_WAIT;
+ } /* FIXME : we do not remove process here, because the kernel
+ * still has them : they may be zombies. We need to know
+ * exactly when release_task is executed on the PID to
+ * know when the zombie is destroyed.
+ */
+ //else
+ // exit_process(s, s->process);
s->process->state->change = s->parent.timestamp;
}
s->process = lttv_state_find_process_or_create(s, pid_in);
s->process->state->s = LTTV_STATE_RUN;
s->process->last_cpu = s->cpu_name;
+ s->process->last_cpu_index = ltt_tracefile_num(((LttvTracefileContext*)s)->tf);
s->process->state->change = s->parent.timestamp;
return FALSE;
}
-
static gboolean process_fork(void *hook_data, void *call_data)
{
- LttField *f = ((LttvTraceHook *)hook_data)->f1;
-
LttvTracefileState *s = (LttvTracefileState *)call_data;
-
+ LttEvent *e = ltt_tracefile_get_event(s->parent.tf);
+ LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
+ LttField *f;
+ guint parent_pid;
guint child_pid;
+ LttvProcessState *zombie_process;
+
+ /* Parent PID */
+ f = thf->f1;
+ parent_pid = ltt_event_get_unsigned(e, f);
+
+ /* Child PID */
+ f = thf->f2;
+ child_pid = ltt_event_get_unsigned(e, f);
+
+ zombie_process = lttv_state_find_process(s, child_pid);
- child_pid = ltt_event_get_unsigned(s->parent.e, f);
+ if(unlikely(zombie_process != NULL)) {
+ /* Reutilisation of PID. Only now we are sure that the old PID
+ * has been released. FIXME : should know when release_task happens instead.
+ */
+ exit_process(s, zombie_process);
+ }
+ g_assert(s->process->pid != child_pid);
+ // FIXME : Add this test in the "known state" section
+ // g_assert(s->process->pid == parent_pid);
lttv_state_create_process(s, s->process, child_pid);
+
return FALSE;
}
static gboolean process_exit(void *hook_data, void *call_data)
{
LttvTracefileState *s = (LttvTracefileState *)call_data;
+ LttEvent *e = ltt_tracefile_get_event(s->parent.tf);
+ LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
+ LttField *f;
+ guint pid;
+
+ pid = ltt_event_get_unsigned(e, thf->f1);
- if(s->process != NULL) {
+ // FIXME : Add this test in the "known state" section
+ // g_assert(s->process->pid == pid);
+
+ if(likely(s->process != NULL)) {
s->process->state->s = LTTV_STATE_EXIT;
}
return FALSE;
}
+static gboolean process_free(void *hook_data, void *call_data)
+{
+ LttvTracefileState *s = (LttvTracefileState *)call_data;
+ LttEvent *e = ltt_tracefile_get_event(s->parent.tf);
+ LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
+ guint release_pid;
+ LttvProcessState *process;
+
+ /* PID of the process to release */
+ release_pid = ltt_event_get_unsigned(e, thf->f1);
+
+ process = lttv_state_find_process(s, release_pid);
+
+ if(likely(process != NULL)) {
+ /* release_task is happening at kernel level : we can now safely release
+ * the data structure of the process */
+ exit_process(s, process);
+ }
+
+ return FALSE;
+}
+
+gint lttv_state_hook_add_event_hooks(void *hook_data, void *call_data)
+{
+ LttvTracesetState *tss = (LttvTracesetState*)(call_data);
+
+ lttv_state_add_event_hooks(tss);
+
+ return 0;
+}
void lttv_state_add_event_hooks(LttvTracesetState *self)
{
LttvTraceset *traceset = self->parent.ts;
- guint i, j, k, nb_trace, nb_tracefile;
+ guint i, j, k, l, nb_trace, nb_tracefile;
LttvTraceState *ts;
GArray *hooks;
- LttvTraceHook hook;
+ LttvTraceHookByFacility *thf;
+
+ LttvTraceHook *hook;
LttvAttributeValue val;
+ gint ret;
+
nb_trace = lttv_traceset_number(traceset);
for(i = 0 ; i < nb_trace ; i++) {
ts = (LttvTraceState *)self->parent.traces[i];
/* Find the eventtype id for the following events and register the
associated by id hooks. */
- hooks = g_array_new(FALSE, FALSE, sizeof(LttvTraceHook));
- g_array_set_size(hooks, 9);
-
- lttv_trace_find_hook(ts->parent.t, "core","syscall_entry","syscall_id",
- NULL, NULL, syscall_entry, &g_array_index(hooks, LttvTraceHook, 0));
-
- lttv_trace_find_hook(ts->parent.t, "core", "syscall_exit", NULL, NULL,
- NULL, syscall_exit, &g_array_index(hooks, LttvTraceHook, 1));
-
- lttv_trace_find_hook(ts->parent.t, "core", "trap_entry", "trap_id",
- NULL, NULL, trap_entry, &g_array_index(hooks, LttvTraceHook, 2));
-
- lttv_trace_find_hook(ts->parent.t, "core", "trap_exit", NULL, NULL, NULL,
- trap_exit, &g_array_index(hooks, LttvTraceHook, 3));
-
- lttv_trace_find_hook(ts->parent.t, "core", "irq_entry", "irq_id", NULL,
- NULL, irq_entry, &g_array_index(hooks, LttvTraceHook, 4));
-
- lttv_trace_find_hook(ts->parent.t, "core", "irq_exit", NULL, NULL, NULL,
- irq_exit, &g_array_index(hooks, LttvTraceHook, 5));
-
- lttv_trace_find_hook(ts->parent.t, "core", "schedchange", "in", "out",
- "out_state", schedchange, &g_array_index(hooks, LttvTraceHook, 6));
-
- lttv_trace_find_hook(ts->parent.t, "core", "process_fork", "child_pid",
- NULL, NULL, process_fork, &g_array_index(hooks, LttvTraceHook, 7));
-
- lttv_trace_find_hook(ts->parent.t, "core", "process_exit", NULL, NULL,
- NULL, process_exit, &g_array_index(hooks, LttvTraceHook, 8));
-
- /* Add these hooks to each before_event_by_id hooks list */
-
- nb_tracefile = ltt_trace_control_tracefile_number(ts->parent.t) +
- ltt_trace_per_cpu_tracefile_number(ts->parent.t);
+ hooks = g_array_sized_new(FALSE, FALSE, sizeof(LttvTraceHook), 10);
+ hooks = g_array_set_size(hooks, 10);
+
+ ret = lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_KERNEL, LTT_EVENT_SYSCALL_ENTRY,
+ LTT_FIELD_SYSCALL_ID, 0, 0,
+ syscall_entry, NULL, &g_array_index(hooks, LttvTraceHook, 0));
+ g_assert(!ret);
+
+ ret = lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_KERNEL, LTT_EVENT_SYSCALL_EXIT,
+ 0, 0, 0,
+ syscall_exit, NULL, &g_array_index(hooks, LttvTraceHook, 1));
+ g_assert(!ret);
+
+ ret = lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_KERNEL, LTT_EVENT_TRAP_ENTRY,
+ LTT_FIELD_TRAP_ID, 0, 0,
+ trap_entry, NULL, &g_array_index(hooks, LttvTraceHook, 2));
+ g_assert(!ret);
+
+ ret = lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_KERNEL, LTT_EVENT_TRAP_EXIT,
+ 0, 0, 0,
+ trap_exit, NULL, &g_array_index(hooks, LttvTraceHook, 3));
+ g_assert(!ret);
+
+ ret = lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_ENTRY,
+ LTT_FIELD_IRQ_ID, 0, 0,
+ irq_entry, NULL, &g_array_index(hooks, LttvTraceHook, 4));
+ g_assert(!ret);
+
+ ret = lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_KERNEL, LTT_EVENT_IRQ_EXIT,
+ 0, 0, 0,
+ irq_exit, NULL, &g_array_index(hooks, LttvTraceHook, 5));
+ g_assert(!ret);
+
+ ret = lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_PROCESS, LTT_EVENT_SCHEDCHANGE,
+ LTT_FIELD_OUT, LTT_FIELD_IN, LTT_FIELD_OUT_STATE,
+ schedchange, NULL, &g_array_index(hooks, LttvTraceHook, 6));
+ g_assert(!ret);
+
+ ret = lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_PROCESS, LTT_EVENT_FORK,
+ LTT_FIELD_PARENT_PID, LTT_FIELD_CHILD_PID, 0,
+ process_fork, NULL, &g_array_index(hooks, LttvTraceHook, 7));
+ g_assert(!ret);
+
+ ret = lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_PROCESS, LTT_EVENT_EXIT,
+ LTT_FIELD_PID, 0, 0,
+ process_exit, NULL, &g_array_index(hooks, LttvTraceHook, 8));
+ g_assert(!ret);
+
+ ret = lttv_trace_find_hook(ts->parent.t,
+ LTT_FACILITY_PROCESS, LTT_EVENT_FREE,
+ LTT_FIELD_PID, 0, 0,
+ process_free, NULL, &g_array_index(hooks, LttvTraceHook, 9));
+ g_assert(!ret);
+
+
+ /* Add these hooks to each event_by_id hooks list */
+
+ nb_tracefile = ts->parent.tracefiles->len;
for(j = 0 ; j < nb_tracefile ; j++) {
- tfs = LTTV_TRACEFILE_STATE(ts->parent.tracefiles[j]);
+ tfs =
+ LTTV_TRACEFILE_STATE(g_array_index(ts->parent.tracefiles,
+ LttvTracefileContext*, j));
for(k = 0 ; k < hooks->len ; k++) {
- hook = g_array_index(hooks, LttvTraceHook, k);
- lttv_hooks_add(lttv_hooks_by_id_find(tfs->parent.after_event_by_id,
- hook.id), hook.h, &g_array_index(hooks, LttvTraceHook, k));
+ hook = &g_array_index(hooks, LttvTraceHook, k);
+ for(l=0;l<hook->fac_list->len;l++) {
+ thf = g_array_index(hook->fac_list, LttvTraceHookByFacility*, l);
+ lttv_hooks_add(
+ lttv_hooks_by_id_find(tfs->parent.event_by_id, thf->id),
+ thf->h,
+ thf,
+ LTTV_PRIO_STATE);
+ }
}
}
lttv_attribute_find(self->parent.a, LTTV_STATE_HOOKS, LTTV_POINTER, &val);
}
}
+gint lttv_state_hook_remove_event_hooks(void *hook_data, void *call_data)
+{
+ LttvTracesetState *tss = (LttvTracesetState*)(call_data);
+
+ lttv_state_remove_event_hooks(tss);
+
+ return 0;
+}
void lttv_state_remove_event_hooks(LttvTracesetState *self)
{
LttvTraceset *traceset = self->parent.ts;
- guint i, j, k, nb_trace, nb_tracefile;
+ guint i, j, k, l, nb_trace, nb_tracefile;
LttvTraceState *ts;
GArray *hooks;
- LttvTraceHook hook;
+ LttvTraceHook *hook;
+
+ LttvTraceHookByFacility *thf;
LttvAttributeValue val;
lttv_attribute_find(self->parent.a, LTTV_STATE_HOOKS, LTTV_POINTER, &val);
hooks = *(val.v_pointer);
- /* Add these hooks to each before_event_by_id hooks list */
+ /* Remove these hooks from each event_by_id hooks list */
- nb_tracefile = ltt_trace_control_tracefile_number(ts->parent.t) +
- ltt_trace_per_cpu_tracefile_number(ts->parent.t);
+ nb_tracefile = ts->parent.tracefiles->len;
for(j = 0 ; j < nb_tracefile ; j++) {
- tfs = LTTV_TRACEFILE_STATE(ts->parent.tracefiles[j]);
+ tfs =
+ LTTV_TRACEFILE_STATE(g_array_index(ts->parent.tracefiles,
+ LttvTracefileContext*, j));
for(k = 0 ; k < hooks->len ; k++) {
- hook = g_array_index(hooks, LttvTraceHook, k);
- lttv_hooks_remove_data(
- lttv_hooks_by_id_find(tfs->parent.after_event_by_id,
- hook.id), hook.h, &g_array_index(hooks, LttvTraceHook, k));
+ hook = &g_array_index(hooks, LttvTraceHook, k);
+ for(l=0;l<hook->fac_list->len;l++) {
+ thf = g_array_index(hook->fac_list, LttvTraceHookByFacility*, l);
+
+ lttv_hooks_remove_data(
+ lttv_hooks_by_id_find(tfs->parent.event_by_id, thf->id),
+ thf->h,
+ thf);
+ }
}
}
+ for(k = 0 ; k < hooks->len ; k++)
+ lttv_trace_hook_destroy(&g_array_index(hooks, LttvTraceHook, k));
g_array_free(hooks, TRUE);
}
}
+static gboolean state_save_event_hook(void *hook_data, void *call_data)
+{
+ guint *event_count = (guint*)hook_data;
+
+ /* Only save at LTTV_STATE_SAVE_INTERVAL */
+ if(likely((*event_count)++ < LTTV_STATE_SAVE_INTERVAL))
+ return FALSE;
+ else
+ *event_count = 0;
+
+ LttvTracefileState *self = (LttvTracefileState *)call_data;
+
+ LttvTracefileState *tfcs;
+
+ LttvTraceState *tcs = (LttvTraceState *)(self->parent.t_context);
+
+ LttEventPosition *ep;
+
+ guint i;
+
+ LttTracefile *tf;
+
+ LttvAttribute *saved_states_tree, *saved_state_tree;
+
+ LttvAttributeValue value;
+
+ saved_states_tree = lttv_attribute_find_subdir(tcs->parent.t_a,
+ LTTV_STATE_SAVED_STATES);
+ saved_state_tree = g_object_new(LTTV_ATTRIBUTE_TYPE, NULL);
+ value = lttv_attribute_add(saved_states_tree,
+ lttv_attribute_get_number(saved_states_tree), LTTV_GOBJECT);
+ *(value.v_gobject) = (GObject *)saved_state_tree;
+ value = lttv_attribute_add(saved_state_tree, LTTV_STATE_TIME, LTTV_TIME);
+ *(value.v_time) = self->parent.timestamp;
+ lttv_state_save(tcs, saved_state_tree);
+ g_debug("Saving state at time %lu.%lu", self->parent.timestamp.tv_sec,
+ self->parent.timestamp.tv_nsec);
+
+ *(tcs->max_time_state_recomputed_in_seek) = self->parent.timestamp;
+
+ return FALSE;
+}
+
+#if 0
static gboolean block_start(void *hook_data, void *call_data)
{
LttvTracefileState *self = (LttvTracefileState *)call_data;
LttvAttributeValue value;
ep = ltt_event_position_new();
- nb_tracefile = ltt_trace_control_tracefile_number(tcs->parent.t) +
- ltt_trace_per_cpu_tracefile_number(tcs->parent.t);
+
+ nb_tracefile = tcs->parent.tracefiles->len;
/* Count the number of events added since the last block end in any
tracefile. */
for(i = 0 ; i < nb_tracefile ; i++) {
- tfcs = (LttvTracefileState *)tcs->parent.tracefiles[i];
+ tfcs =
+ LTTV_TRACEFILE_STATE(&g_array_index(tcs->parent.tracefiles,
+ LttvTracefileContext, i));
ltt_event_position(tfcs->parent.e, ep);
ltt_event_position_get(ep, &nb_block, &nb_event, &tf);
tcs->nb_event += nb_event - tfcs->saved_position;
*(tcs->max_time_state_recomputed_in_seek) = self->parent.timestamp;
return FALSE;
}
+#endif //0
-
+#if 0
static gboolean block_end(void *hook_data, void *call_data)
{
LttvTracefileState *self = (LttvTracefileState *)call_data;
self->saved_position = 0;
*(tcs->max_time_state_recomputed_in_seek) = self->parent.timestamp;
g_free(ep);
-}
-
+ return FALSE;
+}
+#endif //0
+#if 0
void lttv_state_save_add_event_hooks(LttvTracesetState *self)
{
LttvTraceset *traceset = self->parent.ts;
- guint i, j, k, nb_trace, nb_tracefile;
+ guint i, j, nb_trace, nb_tracefile;
LttvTraceState *ts;
nb_trace = lttv_traceset_number(traceset);
for(i = 0 ; i < nb_trace ; i++) {
ts = (LttvTraceState *)self->parent.traces[i];
+
lttv_trace_find_hook(ts->parent.t, "core","block_start",NULL,
NULL, NULL, block_start, &hook_start);
lttv_trace_find_hook(ts->parent.t, "core","block_end",NULL,
NULL, NULL, block_end, &hook_end);
- nb_tracefile = ltt_trace_control_tracefile_number(ts->parent.t) +
- ltt_trace_per_cpu_tracefile_number(ts->parent.t);
+ nb_tracefile = ts->parent.tracefiles->len;
+
+ for(j = 0 ; j < nb_tracefile ; j++) {
+ tfs =
+ LTTV_TRACEFILE_STATE(&g_array_index(ts->parent.tracefiles,
+ LttvTracefileContext, j));
+ lttv_hooks_add(lttv_hooks_by_id_find(tfs->parent.event_by_id,
+ hook_start.id), hook_start.h, NULL, LTTV_PRIO_STATE);
+ lttv_hooks_add(lttv_hooks_by_id_find(tfs->parent.event_by_id,
+ hook_end.id), hook_end.h, NULL, LTTV_PRIO_STATE);
+ }
+ }
+}
+#endif //0
+
+void lttv_state_save_add_event_hooks(LttvTracesetState *self)
+{
+ LttvTraceset *traceset = self->parent.ts;
+
+ guint i, j, nb_trace, nb_tracefile;
+
+ LttvTraceState *ts;
+
+ LttvTracefileState *tfs;
+
+
+ nb_trace = lttv_traceset_number(traceset);
+ for(i = 0 ; i < nb_trace ; i++) {
+
+ ts = (LttvTraceState *)self->parent.traces[i];
+ nb_tracefile = ts->parent.tracefiles->len;
for(j = 0 ; j < nb_tracefile ; j++) {
- tfs = LTTV_TRACEFILE_STATE(ts->parent.tracefiles[j]);
- lttv_hooks_add(lttv_hooks_by_id_find(tfs->parent.after_event_by_id,
- hook_start.id), hook_start.h, NULL);
- lttv_hooks_add(lttv_hooks_by_id_find(tfs->parent.after_event_by_id,
- hook_end.id), hook_end.h, NULL);
+ guint *event_count = g_new(guint, 1);
+ *event_count = 0;
+ tfs =
+ LTTV_TRACEFILE_STATE(g_array_index(ts->parent.tracefiles,
+ LttvTracefileContext*, j));
+ lttv_hooks_add(tfs->parent.event,
+ state_save_event_hook,
+ event_count,
+ LTTV_PRIO_STATE);
+
}
}
}
+gint lttv_state_save_hook_add_event_hooks(void *hook_data, void *call_data)
+{
+ LttvTracesetState *tss = (LttvTracesetState*)(call_data);
+
+ lttv_state_save_add_event_hooks(tss);
+
+ return 0;
+}
+
+#if 0
void lttv_state_save_remove_event_hooks(LttvTracesetState *self)
{
LttvTraceset *traceset = self->parent.ts;
- guint i, j, k, nb_trace, nb_tracefile;
+ guint i, j, nb_trace, nb_tracefile;
LttvTraceState *ts;
nb_trace = lttv_traceset_number(traceset);
for(i = 0 ; i < nb_trace ; i++) {
ts = LTTV_TRACE_STATE(self->parent.traces[i]);
+
lttv_trace_find_hook(ts->parent.t, "core","block_start",NULL,
NULL, NULL, block_start, &hook_start);
lttv_trace_find_hook(ts->parent.t, "core","block_end",NULL,
NULL, NULL, block_end, &hook_end);
- nb_tracefile = ltt_trace_control_tracefile_number(ts->parent.t) +
- ltt_trace_per_cpu_tracefile_number(ts->parent.t);
+ nb_tracefile = ts->parent.tracefiles->len;
for(j = 0 ; j < nb_tracefile ; j++) {
- tfs = LTTV_TRACEFILE_STATE(ts->parent.tracefiles[j]);
+ tfs =
+ LTTV_TRACEFILE_STATE(&g_array_index(ts->parent.tracefiles,
+ LttvTracefileContext, j));
lttv_hooks_remove_data(lttv_hooks_by_id_find(
- tfs->parent.after_event_by_id, hook_start.id), hook_start.h, NULL);
+ tfs->parent.event_by_id, hook_start.id), hook_start.h, NULL);
lttv_hooks_remove_data(lttv_hooks_by_id_find(
- tfs->parent.after_event_by_id, hook_end.id), hook_end.h, NULL);
+ tfs->parent.event_by_id, hook_end.id), hook_end.h, NULL);
+ }
+ }
+}
+#endif //0
+
+void lttv_state_save_remove_event_hooks(LttvTracesetState *self)
+{
+ LttvTraceset *traceset = self->parent.ts;
+
+ guint i, j, nb_trace, nb_tracefile;
+
+ LttvTraceState *ts;
+
+ LttvTracefileState *tfs;
+
+
+ nb_trace = lttv_traceset_number(traceset);
+ for(i = 0 ; i < nb_trace ; i++) {
+
+ ts = (LttvTraceState *)self->parent.traces[i];
+ nb_tracefile = ts->parent.tracefiles->len;
+
+ guint *event_count;
+
+ for(j = 0 ; j < nb_tracefile ; j++) {
+ tfs =
+ LTTV_TRACEFILE_STATE(g_array_index(ts->parent.tracefiles,
+ LttvTracefileContext*, j));
+ event_count = lttv_hooks_remove(tfs->parent.event,
+ state_save_event_hook);
+ g_free(event_count);
+
}
}
}
+gint lttv_state_save_hook_remove_event_hooks(void *hook_data, void *call_data)
+{
+ LttvTracesetState *tss = (LttvTracesetState*)(call_data);
+
+ lttv_state_save_remove_event_hooks(tss);
+
+ return 0;
+}
void lttv_state_traceset_seek_time_closest(LttvTracesetState *self, LttTime t)
{
LttvTraceset *traceset = self->parent.ts;
- guint i, j, nb_trace, nb_saved_state;
+ guint i, nb_trace;
int min_pos, mid_pos, max_pos;
NULL, /* class_data */
sizeof (LttvTracesetState),
0, /* n_preallocs */
- (GInstanceInitFunc) traceset_state_instance_init /* instance_init */
+ (GInstanceInitFunc) traceset_state_instance_init, /* instance_init */
+ NULL /* value handling */
};
type = g_type_register_static (LTTV_TRACESET_CONTEXT_TYPE, "LttvTracesetStateType",
NULL, /* class_data */
sizeof (LttvTraceState),
0, /* n_preallocs */
- (GInstanceInitFunc) trace_state_instance_init /* instance_init */
+ (GInstanceInitFunc) trace_state_instance_init, /* instance_init */
+ NULL /* value handling */
};
type = g_type_register_static (LTTV_TRACE_CONTEXT_TYPE,
NULL, /* class_data */
sizeof (LttvTracefileState),
0, /* n_preallocs */
- (GInstanceInitFunc) tracefile_state_instance_init /* instance_init */
+ (GInstanceInitFunc) tracefile_state_instance_init, /* instance_init */
+ NULL /* value handling */
};
type = g_type_register_static (LTTV_TRACEFILE_CONTEXT_TYPE,
LTTV_STATE_SUBMODE_NONE = g_quark_from_string("(no submode)");
LTTV_STATE_WAIT_CPU = g_quark_from_string("wait for cpu");
LTTV_STATE_EXIT = g_quark_from_string("exiting");
+ LTTV_STATE_ZOMBIE = g_quark_from_string("zombie");
LTTV_STATE_WAIT = g_quark_from_string("wait for I/O");
LTTV_STATE_RUN = g_quark_from_string("running");
LTTV_STATE_TRACEFILES = g_quark_from_string("tracefiles");
LTTV_STATE_NAME_TABLES = g_quark_from_string("name tables");
LTTV_STATE_TRACE_STATE_USE_COUNT =
g_quark_from_string("trace_state_use_count");
+
+
+ LTT_FACILITY_KERNEL = g_quark_from_string("kernel");
+ LTT_FACILITY_PROCESS = g_quark_from_string("process");
+
+
+ LTT_EVENT_SYSCALL_ENTRY = g_quark_from_string("syscall_entry");
+ LTT_EVENT_SYSCALL_EXIT = g_quark_from_string("syscall_exit");
+ LTT_EVENT_TRAP_ENTRY = g_quark_from_string("trap_entry");
+ LTT_EVENT_TRAP_EXIT = g_quark_from_string("trap_exit");
+ LTT_EVENT_IRQ_ENTRY = g_quark_from_string("irq_entry");
+ LTT_EVENT_IRQ_EXIT = g_quark_from_string("irq_exit");
+ LTT_EVENT_SCHEDCHANGE = g_quark_from_string("schedchange");
+ LTT_EVENT_FORK = g_quark_from_string("fork");
+ LTT_EVENT_EXIT = g_quark_from_string("exit");
+ LTT_EVENT_FREE = g_quark_from_string("free");
+
+
+ LTT_FIELD_SYSCALL_ID = g_quark_from_string("syscall_id");
+ LTT_FIELD_TRAP_ID = g_quark_from_string("trap_id");
+ LTT_FIELD_IRQ_ID = g_quark_from_string("irq_id");
+ LTT_FIELD_OUT = g_quark_from_string("out");
+ LTT_FIELD_IN = g_quark_from_string("in");
+ LTT_FIELD_OUT_STATE = g_quark_from_string("out_state");
+ LTT_FIELD_PARENT_PID = g_quark_from_string("parent_pid");
+ LTT_FIELD_CHILD_PID = g_quark_from_string("child_pid");
+ LTT_FIELD_PID = g_quark_from_string("pid");
+
}
static void module_destroy()