X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=lttv%2Flttv%2Fstate.c;h=513c1bf3bb03ec7a1775975fc43cb030208236ed;hb=b9ce0bad7daf7c0a2333c91fdb1e35d602afe17f;hp=792e3cbe2a7ac9bff2eb4eb000a80f0fb92d12d6;hpb=7a4bdb546094fea3343bfc80e3744ea26a08dd22;p=lttv.git diff --git a/lttv/lttv/state.c b/lttv/lttv/state.c index 792e3cbe..513c1bf3 100644 --- a/lttv/lttv/state.c +++ b/lttv/lttv/state.c @@ -12,8 +12,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. */ #define _GNU_SOURCE @@ -27,9 +27,12 @@ #include #include #include +#include +#include #include #include #include +#include #define PREALLOCATED_EXECUTION_STACK 10 @@ -80,7 +83,6 @@ GQuark LTT_EVENT_STATEDUMP_END, LTT_EVENT_FUNCTION_ENTRY, LTT_EVENT_FUNCTION_EXIT, - LTT_EVENT_THREAD_BRAND, LTT_EVENT_REQUEST_ISSUE, LTT_EVENT_REQUEST_COMPLETE, LTT_EVENT_LIST_INTERRUPT, @@ -152,9 +154,6 @@ LttvProcessStatus LTTV_STATE_RUN, LTTV_STATE_DEAD; -GQuark - LTTV_STATE_UNBRANDED; - LttvProcessType LTTV_STATE_USER_THREAD, LTTV_STATE_KERNEL_THREAD; @@ -212,16 +211,18 @@ static void free_name_tables(LttvTraceState *tcs); static void free_saved_state(LttvTraceState *tcs); static void lttv_state_free_process_table(GHashTable *processes); - +#ifdef BABEL_CLEANUP static void lttv_trace_states_read_raw(LttvTraceState *tcs, FILE *fp, GPtrArray *quarktable); - +#endif /* Resource function prototypes */ +#ifdef BABEL_CLEANUP static LttvBdevState *get_hashed_bdevstate(LttvTraceState *ts, guint32 devcode); static LttvBdevState *bdevstate_new(void); static void bdevstate_free(LttvBdevState *); static void bdevstate_free_cb(gpointer key, gpointer value, gpointer user_data); static LttvBdevState *bdevstate_copy(LttvBdevState *bds); +#endif void lttv_state_add_event_hooks(LttvTraceset *traceset); #if (__WORDSIZE == 32) @@ -299,7 +300,7 @@ static void fill_name_table(LttvTraceState *ts, GQuark *table, guint nb, } g_string_free(fe_name, TRUE); } - +#ifdef BABEL_CLEANUP static void expand_kprobe_table(LttvTraceState *ts, guint64 ip, char *symbol) { LttvNameTables *nt = ts->name_tables; @@ -336,7 +337,7 @@ static void expand_trap_table(LttvTraceState *ts, int id) /* Update the table size */ nt->nb_traps = new_nb; } - +#endif static void expand_irq_table(LttvTraceState *ts, int id) { LttvNameTables *nt = ts->name_tables; @@ -393,7 +394,7 @@ static void restore_init_state(LttvTraceState *self) //LttvTracefileState *tfcs; - //LttTime start_time, end_time; + LttTime start_time; /* Free the process tables */ if(self->processes != NULL) lttv_state_free_process_table(self->processes); @@ -407,8 +408,10 @@ static void restore_init_state(LttvTraceState *self) //g_tree_destroy(self->parent.ts_context->pqueue); //self->parent.ts_context->pqueue = g_tree_new(compare_tracefile); - //TODO use babeltrace one. - //ltt_trace_time_span_get(self->parent.t, &start_time, &end_time); + start_time = ltt_time_from_uint64( + bt_trace_handle_get_timestamp_begin(self->trace->traceset->context, + self->trace->id,BT_CLOCK_REAL)); + //lttv_process_trace_seek_time(&self->parent, ltt_time_zero); @@ -421,8 +424,7 @@ static void restore_init_state(LttvTraceState *self) for(i=0; i< nb_cpus; i++) { LttvExecutionState *es; self->running_process[i] = lttv_state_create_process(self, NULL, i, 0, 0, - //TODO use &start_time... - LTTV_STATE_UNNAMED, <t_time_zero); + LTTV_STATE_UNNAMED, &start_time); /* We are not sure is it's a kernel thread or normal thread, put the * bottom stack state to unknown */ self->running_process[i]->execution_stack = @@ -470,10 +472,12 @@ static void restore_init_state(LttvTraceState *self) self->trap_states[i].running = 0; } +#ifdef BABEL_CLEANUP /* reset bdev states */ g_hash_table_foreach(self->bdev_states, bdevstate_free_cb, NULL); //g_hash_table_steal_all(self->bdev_states); g_hash_table_foreach_steal(self->bdev_states, rettrue, NULL); +#endif #if 0 nb_tracefile = self->parent.tracefiles->len; @@ -672,7 +676,7 @@ static void write_process_state(gpointer key, gpointer value, guint64 address; process = (LttvProcessState *)value; - fprintf(fp," \n", + fprintf(fp," \n", process, process->pid, process->tgid, process->ppid, g_quark_to_string(process->type), process->creation_time.tv_sec, @@ -680,7 +684,6 @@ static void write_process_state(gpointer key, gpointer value, process->insertion_time.tv_sec, process->insertion_time.tv_nsec, g_quark_to_string(process->name), - g_quark_to_string(process->brand), process->cpu, process->free_events); for(i = 0 ; i < process->execution_stack->len; i++) { @@ -770,9 +773,7 @@ static void write_process_state_raw(gpointer key, gpointer value, //fprintf(fp, "%s", g_quark_to_string(process->name)); //fputc('\0', fp); fwrite(&process->name, sizeof(process->name), 1, fp); - //fprintf(fp, "%s", g_quark_to_string(process->brand)); //fputc('\0', fp); - fwrite(&process->brand, sizeof(process->brand), 1, fp); fwrite(&process->pid, sizeof(process->pid), 1, fp); fwrite(&process->free_events, sizeof(process->free_events), 1, fp); fwrite(&process->tgid, sizeof(process->tgid), 1, fp); @@ -782,7 +783,7 @@ static void write_process_state_raw(gpointer key, gpointer value, fwrite(&process->insertion_time, sizeof(process->insertion_time), 1, fp); #if 0 - fprintf(fp," \n", + fprintf(fp," \n", process, process->pid, process->tgid, process->ppid, g_quark_to_string(process->type), process->creation_time.tv_sec, @@ -790,7 +791,6 @@ static void write_process_state_raw(gpointer key, gpointer value, process->insertion_time.tv_sec, process->insertion_time.tv_nsec, g_quark_to_string(process->name), - g_quark_to_string(process->brand), process->cpu); #endif //0 @@ -905,7 +905,6 @@ static void read_process_state_raw(LttvTraceState *self, FILE *fp, res = fread(&tmp.type, sizeof(tmp.type), 1, fp); res += fread(&tmp.name, sizeof(tmp.name), 1, fp); - res += fread(&tmp.brand, sizeof(tmp.brand), 1, fp); res += fread(&tmp.pid, sizeof(tmp.pid), 1, fp); res += fread(&tmp.free_events, sizeof(tmp.free_events), 1, fp); res += fread(&tmp.tgid, sizeof(tmp.tgid), 1, fp); @@ -935,8 +934,6 @@ static void read_process_state_raw(LttvTraceState *self, FILE *fp, (gchar*)g_ptr_array_index(quarktable, tmp.type)); process->tgid = tmp.tgid; process->ppid = tmp.ppid; - process->brand = g_quark_from_string( - (gchar*)g_ptr_array_index(quarktable, tmp.brand)); process->name = g_quark_from_string((gchar*)g_ptr_array_index(quarktable, tmp.name)); process->free_events = tmp.free_events; @@ -1341,7 +1338,7 @@ static void lttv_state_free_trap_states(LttvTrapState *states, guint n) { g_free(states); } - +#ifdef BABEL_CLEANUP /* bdevstate stuff */ static LttvBdevState *get_hashed_bdevstate(LttvTraceState *ts, guint32 devcode) @@ -1361,7 +1358,7 @@ static LttvBdevState *get_hashed_bdevstate(LttvTraceState *ts, guint32 devcode) return bdev; } - +#endif static LttvBdevState *bdevstate_new(void) { LttvBdevState *retval; @@ -1459,7 +1456,7 @@ void lttv_state_save(LttvTraceState *self, LttvAttribute *container) /* Save the current position */ value = lttv_attribute_add(container, LTTV_STATE_POSITION, LTTV_POINTER); - *(value.v_pointer) = lttv_traceset_create_position(lttv_trace_get_traceset(self->trace)); + *(value.v_pointer) = lttv_traceset_create_current_position(lttv_trace_get_traceset(self->trace)); #ifdef BABEL_CLEANUP nb_tracefile = self->parent.tracefiles->len; @@ -1682,7 +1679,7 @@ void lttv_state_saved_free(LttvTraceState *self, LttvAttribute *container) running_process = *(value.v_pointer); g_free(running_process); - /* free cpu resource states */ + /* free cpu resources */ type = lttv_attribute_get_by_name(container, LTTV_STATE_RESOURCE_CPUS_COUNT, &value); g_assert(type == LTTV_UINT); nb_cpus = *value.v_uint; @@ -2012,7 +2009,7 @@ static void cpu_pop_mode(LttvCPUState *cpust) else g_array_set_size(cpust->mode_stack, cpust->mode_stack->len - 1); } - +#ifdef BABEL_CLEANUP /* clears the stack and sets the state passed as argument */ static void bdev_set_base_mode(LttvBdevState *bdevst, LttvBdevMode state) { @@ -2033,7 +2030,7 @@ static void bdev_pop_mode(LttvBdevState *bdevst) else g_array_set_size(bdevst->mode_stack, bdevst->mode_stack->len - 1); } - +#endif static void irq_set_base_mode(LttvIRQState *irqst, LttvIRQMode state) { g_array_set_size(irqst->mode_stack, 1); @@ -2125,11 +2122,10 @@ static void pop_state(LttvEvent *event, g_info("process state has %s when pop_int is %s\n", g_quark_to_string(process->state->t), g_quark_to_string(t)); - g_info("{ %u, %u, %s, %s, %s }\n", + g_info("{ %u, %u, %s, %s }\n", process->pid, process->ppid, g_quark_to_string(process->name), - g_quark_to_string(process->brand), g_quark_to_string(process->state->s)); return; } @@ -2144,9 +2140,16 @@ static void pop_state(LttvEvent *event, 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 = lttv_event_get_timestamp(event); + + if((process->state->t == LTTV_STATE_MODE_UNKNOWN) && (t == LTTV_STATE_SYSCALL)) { + //Force state at running + process->state->t = LTTV_STATE_USER_MODE; + process->state->s = LTTV_STATE_RUN; + } } struct search_result { @@ -2170,7 +2173,6 @@ LttvProcessState *lttv_state_create_process(LttvTraceState *tcs, process->tgid = tgid; process->cpu = cpu; process->name = name; - process->brand = LTTV_STATE_UNBRANDED; //process->last_cpu = tfs->cpu_name; //process->last_cpu_index = ltt_tracefile_num(((LttvTracefileContext*)tfs)->tf); process->type = LTTV_STATE_USER_THREAD; @@ -2438,7 +2440,7 @@ static gboolean irq_entry(void *hook_data, void *call_data) ts = event->state; nt = ts->name_tables; - irq = lttv_event_get_long_unsigned(event, "irq"); + irq = lttv_event_get_long(event, "irq"); expand_irq_table(ts, irq); @@ -2558,7 +2560,7 @@ static gboolean soft_irq_entry(void *hook_data, void *call_data) event = (LttvEvent *) call_data; if (strcmp(lttv_traceset_get_name_from_event(event), - "softirq_exit") != 0) + "softirq_entry") != 0) return FALSE; cpu = lttv_traceset_get_cpuid_from_event(event); @@ -2750,7 +2752,7 @@ static gboolean sched_try_wakeup(void *hook_data, void *call_data) ts = event->state; woken_pid = lttv_event_get_long(event, "tid"); - woken_cpu = lttv_event_get_long_unsigned(event, "target_cpu"); + woken_cpu = lttv_event_get_long(event, "target_cpu"); timestamp = lttv_event_get_timestamp(event); process = lttv_state_find_process_or_create( @@ -2781,6 +2783,8 @@ static gboolean schedchange(void *hook_data, void *call_data) guint pid_in, pid_out; gint64 state_out; + //TODO ybrosseau 2012-07-13: manage this 20 in a constact or dynamically + char next_comm[20]; LttTime timestamp; event = (LttvEvent *) call_data; if (strcmp(lttv_traceset_get_name_from_event(event), @@ -2790,10 +2794,13 @@ static gboolean schedchange(void *hook_data, void *call_data) cpu = lttv_traceset_get_cpuid_from_event(event); ts = event->state; process = ts->running_process[cpu]; - pid_out = lttv_event_get_long_unsigned(event, "prev_tid"); - pid_in = lttv_event_get_long_unsigned(event, "next_tid"); + pid_out = lttv_event_get_long(event, "prev_tid"); + pid_in = lttv_event_get_long(event, "next_tid"); state_out = lttv_event_get_long(event, "prev_state"); + strncpy(next_comm, lttv_event_get_string(event, "next_comm"), 20); + next_comm[20-1] = '\0'; + timestamp = lttv_event_get_timestamp(event); if(likely(process != NULL)) { @@ -2851,6 +2858,7 @@ static gboolean schedchange(void *hook_data, void *call_data) process->cpu = cpu; // process->last_cpu_index = ltt_tracefile_num(((LttvTracefileContext*)s)->tf); process->state->change = timestamp; + process->name = g_quark_from_string(next_comm); /* update cpu status */ if(pid_in == 0) @@ -2894,7 +2902,7 @@ static gboolean process_fork(void *hook_data, void *call_data) /* Skip Parent PID param */ /* Child PID */ - child_pid = lttv_event_get_long_unsigned(event, "child_tid"); + child_pid = lttv_event_get_long(event, "child_tid"); //ts->target_pid = child_pid; /* Child TGID */ @@ -2954,7 +2962,6 @@ static gboolean process_fork(void *hook_data, void *call_data) } g_assert(child_process->name == LTTV_STATE_UNNAMED); child_process->name = process->name; - child_process->brand = process->brand; return FALSE; } @@ -3007,7 +3014,7 @@ static gboolean process_exit(void *hook_data, void *call_data) ts = event->state; process = ts->running_process[cpu]; - pid = lttv_event_get_long_unsigned(event, "tid"); + pid = lttv_event_get_long(event, "tid"); //s->parent.target_pid = pid; // FIXME : Add this test in the "known state" section @@ -3037,7 +3044,7 @@ static gboolean process_free(void *hook_data, void *call_data) process = ts->running_process[cpu]; /* PID of the process to release */ - release_pid = lttv_event_get_long_unsigned(event, "_tid"); + release_pid = lttv_event_get_long(event, "_tid"); //s->parent.target_pid = release_pid; g_assert(release_pid != 0); @@ -3112,27 +3119,9 @@ static gboolean process_exec(void *hook_data, void *call_data) process->name = g_quark_from_string(lttv_event_get_string(event, "filename")); - process->brand = LTTV_STATE_UNBRANDED; //g_free(null_term_name); return FALSE; } -#ifdef BABEL_CLEANUP -static gboolean thread_brand(void *hook_data, void *call_data) -{ - LttvTracefileState *s = (LttvTracefileState *)call_data; - LttvTraceState *ts = (LttvTraceState*)s->parent.t_context; - LttEvent *e = ltt_tracefile_get_event(s->parent.tf); - LttvTraceHook *th = (LttvTraceHook *)hook_data; - gchar *name; - guint cpu = s->cpu; - LttvProcessState *process = ts->running_process[cpu]; - - name = ltt_event_get_string(e, lttv_trace_get_hook_field(th, 0)); - process->brand = g_quark_from_string(name); - - return FALSE; -} -#endif #if 0 // TODO We only have sys_open, without the FD // manage to do somehting better @@ -3290,18 +3279,18 @@ static gboolean enum_process_state(void *hook_data, void *call_data) timestamp = lttv_event_get_timestamp(event); /* PID */ - pid = lttv_event_get_long_unsigned(event, "tid"); + pid = lttv_event_get_long(event, "tid"); //s->parent.target_pid = pid; /* Parent PID */ - parent_pid = lttv_event_get_long_unsigned(event, "ppid"); + parent_pid = lttv_event_get_long(event, "ppid"); /* Command name */ command = lttv_event_get_string(event, "name"); /* type */ - type = lttv_event_get_long_unsigned(event, "type"); + type = lttv_event_get_long(event, "type"); //FIXME: type is rarely used, enum must match possible types. @@ -3310,9 +3299,8 @@ static gboolean enum_process_state(void *hook_data, void *call_data) /* Skip submode 5th param */ /* Skip status 6th param */ - /* TGID */ - tgid = lttv_event_get_long_unsigned(event, "pid"); + tgid = lttv_event_get_long(event, "pid"); if(pid == 0) { nb_cpus = lttv_trace_get_num_cpu(ts->trace); @@ -3429,15 +3417,10 @@ gint lttv_state_hook_add_event_hooks(void *hook_data, void *call_data) void lttv_state_add_event_hooks(LttvTraceset *traceset) { - gboolean result; - - LttvAttributeValue value; LttvHooks*event_hook; - LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes()); - result = lttv_iattribute_find_by_path(attributes, "hooks/event", - LTTV_POINTER, &value); - g_assert(result); - event_hook = *(value.v_pointer); + + //Use traceset hooks + event_hook = lttv_traceset_get_hooks(traceset); g_assert(event_hook); lttv_hooks_add(event_hook,syscall_entry , NULL, LTTV_PRIO_STATE); @@ -3450,314 +3433,53 @@ void lttv_state_add_event_hooks(LttvTraceset *traceset) lttv_hooks_add(event_hook,schedchange , NULL, LTTV_PRIO_STATE); lttv_hooks_add(event_hook,sched_try_wakeup , NULL, LTTV_PRIO_STATE); lttv_hooks_add(event_hook,process_exit , NULL, LTTV_PRIO_STATE); - lttv_hooks_add(event_hook,process_free , NULL, LTTV_PRIO_STATE); + lttv_hooks_add(event_hook,process_free , NULL, LTTV_PRIO_STATE); + lttv_hooks_add(event_hook,process_fork , NULL, LTTV_PRIO_STATE); lttv_hooks_add(event_hook,process_exec , NULL, LTTV_PRIO_STATE); lttv_hooks_add(event_hook,enum_process_state , NULL, LTTV_PRIO_STATE); lttv_hooks_add(event_hook,statedump_end , NULL, LTTV_PRIO_STATE); lttv_hooks_add(event_hook,enum_interrupt , NULL, LTTV_PRIO_STATE); -#ifdef BABEL_CLEANUP //For the whole function this time - guint i, j, k, nb_trace; - LttvTraceState *ts; - GArray *hooks; - // LttvTraceHook *th; - LttvAttributeValue val; - - nb_trace = lttv_traceset_number(traceset); - for (i = 0 ; i < nb_trace ; i++) { - ts = lttv_traceset_get(traceset, i)-; - - /* Find the eventtype id for the following events and register the - associated by id hooks. */ - - hooks = g_array_sized_new(FALSE, FALSE, sizeof(LttvTraceHook), 20); - //hooks = g_array_set_size(hooks, 19); // Max possible number of hooks. - //hn = 0; - - lttv_trace_find_hook(tss->parent.t, - LTT_CHANNEL_KERNEL, - LTT_EVENT_SYSCALL_ENTRY, - FIELD_ARRAY(LTT_FIELD_SYSCALL_ID), - syscall_entry, NULL, &hooks); - - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_KERNEL, - LTT_EVENT_SYSCALL_EXIT, - NULL, - syscall_exit, NULL, &hooks); - -#ifdef BABEL_CLEANUP - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_KERNEL, - LTT_EVENT_TRAP_ENTRY, - FIELD_ARRAY(LTT_FIELD_TRAP_ID), - trap_entry, NULL, &hooks); - - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_KERNEL, - LTT_EVENT_TRAP_EXIT, - NULL, - trap_exit, NULL, &hooks); -#endif /* BABEL_CLEANUP */ - - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_KERNEL, - LTT_EVENT_PAGE_FAULT_ENTRY, - FIELD_ARRAY(LTT_FIELD_TRAP_ID), - trap_entry, NULL, &hooks); - - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_KERNEL, - LTT_EVENT_PAGE_FAULT_EXIT, - NULL, - trap_exit, NULL, &hooks); - -#ifdef BABEL_CLEANUP - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_KERNEL, - LTT_EVENT_PAGE_FAULT_NOSEM_ENTRY, - FIELD_ARRAY(LTT_FIELD_TRAP_ID), - trap_entry, NULL, &hooks); - - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_KERNEL, - LTT_EVENT_PAGE_FAULT_NOSEM_EXIT, - NULL, - trap_exit, NULL, &hooks); -#endif /* BABEL_CLEANUP */ - - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_KERNEL, - LTT_EVENT_IRQ_ENTRY, - FIELD_ARRAY(LTT_FIELD_IRQ_ID), - irq_entry, NULL, &hooks); - - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_KERNEL, - LTT_EVENT_IRQ_EXIT, - NULL, - irq_exit, NULL, &hooks); - - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_KERNEL, - LTT_EVENT_SOFT_IRQ_RAISE, - FIELD_ARRAY(LTT_FIELD_SOFT_IRQ_ID), - soft_irq_raise, NULL, &hooks); - - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_KERNEL, - LTT_EVENT_SOFT_IRQ_ENTRY, - FIELD_ARRAY(LTT_FIELD_SOFT_IRQ_ID), - soft_irq_entry, NULL, &hooks); - - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_KERNEL, - LTT_EVENT_SOFT_IRQ_EXIT, - NULL, - soft_irq_exit, NULL, &hooks); - - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_KERNEL, - LTT_EVENT_SCHED_SCHEDULE, - FIELD_ARRAY(LTT_FIELD_PREV_PID, LTT_FIELD_NEXT_PID, - LTT_FIELD_PREV_STATE), - schedchange, NULL, &hooks); - - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_KERNEL, - LTT_EVENT_SCHED_TRY_WAKEUP, - FIELD_ARRAY(LTT_FIELD_PID, LTT_FIELD_CPU_ID, LTT_FIELD_STATE), - sched_try_wakeup, NULL, &hooks); - - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_KERNEL, - LTT_EVENT_PROCESS_FORK, - FIELD_ARRAY(LTT_FIELD_PARENT_PID, LTT_FIELD_CHILD_PID, - LTT_FIELD_CHILD_TGID), - process_fork, NULL, &hooks); - - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_KERNEL, - LTT_EVENT_KTHREAD_CREATE, - FIELD_ARRAY(LTT_FIELD_PID), - process_kernel_thread, NULL, &hooks); - - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_KERNEL, - LTT_EVENT_PROCESS_EXIT, - FIELD_ARRAY(LTT_FIELD_PID), - process_exit, NULL, &hooks); - - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_KERNEL, - LTT_EVENT_PROCESS_FREE, - FIELD_ARRAY(LTT_FIELD_PID), - process_free, NULL, &hooks); - - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_FS, - LTT_EVENT_EXEC, - FIELD_ARRAY(LTT_FIELD_FILENAME), - process_exec, NULL, &hooks); - - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_USERSPACE, - LTT_EVENT_THREAD_BRAND, - FIELD_ARRAY(LTT_FIELD_NAME), - thread_brand, NULL, &hooks); - - /* statedump-related hooks */ - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_TASK_STATE, - LTT_EVENT_PROCESS_STATE, - FIELD_ARRAY(LTT_FIELD_PID, LTT_FIELD_PARENT_PID, LTT_FIELD_NAME, - LTT_FIELD_TYPE, LTT_FIELD_MODE, LTT_FIELD_SUBMODE, - LTT_FIELD_STATUS, LTT_FIELD_TGID), - enum_process_state, NULL, &hooks); - - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_GLOBAL_STATE, - LTT_EVENT_STATEDUMP_END, - NULL, - statedump_end, NULL, &hooks); - - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_IRQ_STATE, - LTT_EVENT_LIST_INTERRUPT, - FIELD_ARRAY(LTT_FIELD_ACTION, LTT_FIELD_IRQ_ID), - enum_interrupt, NULL, &hooks); - - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_BLOCK, - LTT_EVENT_REQUEST_ISSUE, - FIELD_ARRAY(LTT_FIELD_MAJOR, LTT_FIELD_MINOR, LTT_FIELD_OPERATION), - bdev_request_issue, NULL, &hooks); - - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_BLOCK, - LTT_EVENT_REQUEST_COMPLETE, - FIELD_ARRAY(LTT_FIELD_MAJOR, LTT_FIELD_MINOR, LTT_FIELD_OPERATION), - bdev_request_complete, NULL, &hooks); - - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_USERSPACE, - LTT_EVENT_FUNCTION_ENTRY, - FIELD_ARRAY(LTT_FIELD_THIS_FN, LTT_FIELD_CALL_SITE), - function_entry, NULL, &hooks); - - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_USERSPACE, - LTT_EVENT_FUNCTION_EXIT, - FIELD_ARRAY(LTT_FIELD_THIS_FN, LTT_FIELD_CALL_SITE), - function_exit, NULL, &hooks); - - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_SYSCALL_STATE, - LTT_EVENT_SYS_CALL_TABLE, - FIELD_ARRAY(LTT_FIELD_ID, LTT_FIELD_ADDRESS, LTT_FIELD_SYMBOL), - dump_syscall, NULL, &hooks); - - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_KPROBE_STATE, - LTT_EVENT_KPROBE_TABLE, - FIELD_ARRAY(LTT_FIELD_IP, LTT_FIELD_SYMBOL), - dump_kprobe, NULL, &hooks); - - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_SOFTIRQ_STATE, - LTT_EVENT_SOFTIRQ_VEC, - FIELD_ARRAY(LTT_FIELD_ID, LTT_FIELD_ADDRESS, LTT_FIELD_SYMBOL), - dump_softirq, NULL, &hooks); - - lttv_trace_find_hook(ts->parent.t, - LTT_CHANNEL_FS, - LTT_EVENT_OPEN, - FIELD_ARRAY(LTT_FIELD_FD, LTT_FIELD_FILENAME), - fs_open, NULL, &hooks); - - /* 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(g_array_index(ts->parent.tracefiles, - LttvTracefileContext*, j)); - - for(k = 0 ; k < hooks->len ; k++) { - th = &g_array_index(hooks, LttvTraceHook, k); - if (th->mdata == tfs->parent.tf->mdata) - lttv_hooks_add( - lttv_hooks_by_id_find(tfs->parent.event_by_id, th->id), - th->h, - th, - LTTV_PRIO_STATE); - } - } - lttv_attribute_find(ts->parent.a, LTTV_STATE_HOOKS, LTTV_POINTER, &val); - *(val.v_pointer) = hooks; - } -#endif } gint lttv_state_hook_remove_event_hooks(void *hook_data, void *call_data) { - //TODO ybrosseau 2012-05-11 Reactivate the remove -#if 0 - LttvTracesetState *tss = (LttvTracesetState*)(call_data); - - lttv_state_remove_event_hooks(tss); -#endif - return 0; -} -#if 0 -void lttv_state_remove_event_hooks(LttvTracesetState *self) -{ - LttvTraceset *traceset = self->parent.ts; - guint i, j, k, nb_trace, nb_tracefile; + LttvTraceset *traceset = (LttvTraceset*)(call_data); - LttvTraceState *ts; + lttv_state_remove_event_hooks(traceset); - LttvTracefileState *tfs; + return 0; +} - GArray *hooks; +void lttv_state_remove_event_hooks(LttvTraceset *traceset) +{ - LttvTraceHook *th; + LttvHooks*event_hook; - LttvAttributeValue val; + event_hook = lttv_traceset_get_hooks(traceset); - nb_trace = lttv_traceset_number(traceset); - for(i = 0 ; i < nb_trace ; i++) { - ts = LTTV_TRACE_STATE(self->parent.traces[i]); + g_assert(event_hook); - lttv_attribute_find(ts->parent.a, LTTV_STATE_HOOKS, LTTV_POINTER, &val); - hooks = *(val.v_pointer); - /* Remove these hooks from each event_by_id hooks list */ + lttv_hooks_remove(event_hook,syscall_entry ); + lttv_hooks_remove(event_hook,syscall_exit); + lttv_hooks_remove(event_hook,irq_entry ); + lttv_hooks_remove(event_hook,irq_exit ); + lttv_hooks_remove(event_hook,soft_irq_raise); + lttv_hooks_remove(event_hook,soft_irq_entry); + lttv_hooks_remove(event_hook,soft_irq_exit); + lttv_hooks_remove(event_hook,schedchange); + lttv_hooks_remove(event_hook,sched_try_wakeup); + lttv_hooks_remove(event_hook,process_exit); + lttv_hooks_remove(event_hook,process_free); + lttv_hooks_remove(event_hook,process_exec); + lttv_hooks_remove(event_hook,enum_process_state); + lttv_hooks_remove(event_hook,statedump_end); + lttv_hooks_remove(event_hook,enum_interrupt); +} - 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)); - - for(k = 0 ; k < hooks->len ; k++) { - th = &g_array_index(hooks, LttvTraceHook, k); - if (th->mdata == tfs->parent.tf->mdata) - lttv_hooks_remove_data( - lttv_hooks_by_id_find(tfs->parent.event_by_id, th->id), - th->h, - th); - } - } - lttv_trace_hook_remove_all(&hooks); - g_array_free(hooks, TRUE); - } -} -#endif -#ifdef BABEL_CLEANUP static gboolean state_save_event_hook(void *hook_data, void *call_data) { guint *event_count = (guint*)hook_data; @@ -3768,40 +3490,54 @@ static gboolean state_save_event_hook(void *hook_data, void *call_data) else *event_count = 0; - LttvTracefileState *self = (LttvTracefileState *)call_data; + LttvEvent *event = (LttvEvent *)call_data; - LttvTraceState *tcs = (LttvTraceState *)(self->parent.t_context); + LttvTraceset *traceset = lttv_trace_get_traceset(event->state->trace); LttvAttribute *saved_states_tree, *saved_state_tree; LttvAttributeValue value; + LttTime currentTime; + guint i; + currentTime = lttv_event_get_timestamp(event); + int nb_trace = lttv_traceset_number(traceset); + for(i = 0 ; i < nb_trace ; i++) { - 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); + LttvTrace *trace = lttv_traceset_get(traceset, i); + LttvTraceState *tstate = trace->state; + saved_states_tree = lttv_attribute_find_subdir(trace->a, + LTTV_STATE_SAVED_STATES); - *(tcs->max_time_state_recomputed_in_seek) = self->parent.timestamp; + 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) = currentTime; + + lttv_state_save(tstate, saved_state_tree); + g_debug("Saving state at time %lu.%lu", currentTime.tv_sec, + currentTime.tv_nsec); + *(tstate->max_time_state_recomputed_in_seek) = currentTime; + } return FALSE; } static gboolean state_save_after_trace_hook(void *hook_data, void *call_data) { - LttvTraceState *tcs = (LttvTraceState *)(call_data); +#warning "Would we move max_time to traceset" + LttvTrace *trace = (LttvTrace *)(call_data); + LttvTraceState *tcs = trace->state; + TimeInterval time_span = lttv_traceset_get_time_span_real(lttv_trace_get_traceset(trace)); - *(tcs->max_time_state_recomputed_in_seek) = tcs->parent.time_span.end_time; + *(tcs->max_time_state_recomputed_in_seek) = time_span.end_time; return FALSE; } - +#ifdef BABEL_CLEANUP guint lttv_state_current_cpu(LttvTracefileState *tfs) { return tfs->cpu; @@ -3925,105 +3661,40 @@ void lttv_state_save_add_event_hooks(LttvTracesetState *self) } } #endif //0 -#ifdef BABEL_CLEANUP -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; - - if(ts->has_precomputed_states) continue; +void lttv_state_save_add_event_hooks(LttvTraceset *traceset) +{ + if(!traceset->has_precomputed_states) { guint *event_count = g_new(guint, 1); + *event_count = 0; - - for(j = 0 ; j < nb_tracefile ; j++) { - 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); - - } + lttv_hooks_add(traceset->event_hooks, + state_save_event_hook, + event_count, + LTTV_PRIO_STATE); + + lttv_process_traceset_begin(traceset, + NULL, NULL, NULL); } - lttv_process_traceset_begin(&self->parent, - NULL, NULL, NULL, NULL, NULL); - } gint lttv_state_save_hook_add_event_hooks(void *hook_data, void *call_data) { - LttvTracesetState *tss = (LttvTracesetState*)(call_data); + LttvTraceset *ts = (LttvTraceset*)(call_data); - lttv_state_save_add_event_hooks(tss); + lttv_state_save_add_event_hooks(ts); return 0; } -#endif - -#if 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; - LttvTraceHook hook_start, hook_end; - 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 = 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_remove_data(lttv_hooks_by_id_find( - tfs->parent.event_by_id, hook_start.id), hook_start.h, NULL); - lttv_hooks_remove_data(lttv_hooks_by_id_find( - tfs->parent.event_by_id, hook_end.id), hook_end.h, NULL); - } - } -} -#endif //0 -#ifdef BABEL_CLEANUP -void lttv_state_save_remove_event_hooks(LttvTracesetState *self) +void lttv_state_save_remove_event_hooks(LttvTraceset *traceset) { - LttvTraceset *traceset = self->parent.ts; - - guint i, j, nb_trace, nb_tracefile; - - LttvTraceState *ts; - - LttvTracefileState *tfs; LttvHooks *after_trace = lttv_hooks_new(); + guint *event_count = NULL; lttv_hooks_add(after_trace, state_save_after_trace_hook, @@ -4031,52 +3702,58 @@ void lttv_state_save_remove_event_hooks(LttvTracesetState *self) LTTV_PRIO_STATE); - lttv_process_traceset_end(&self->parent, - NULL, after_trace, NULL, NULL, NULL); + lttv_process_traceset_end(traceset, + NULL, after_trace, NULL); lttv_hooks_destroy(after_trace); - 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; - - if(ts->has_precomputed_states) continue; - - guint *event_count = NULL; + //nb_trace = lttv_traceset_number(traceset); - 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, + event_count = lttv_hooks_remove(traceset->event_hooks, state_save_event_hook); - } - if(event_count) g_free(event_count); - } + + if(event_count) g_free(event_count); + } gint lttv_state_save_hook_remove_event_hooks(void *hook_data, void *call_data) { - LttvTracesetState *tss = (LttvTracesetState*)(call_data); + LttvTraceset *ts = (LttvTraceset*)(call_data); - lttv_state_save_remove_event_hooks(tss); + lttv_state_save_remove_event_hooks(ts); return 0; } -void lttv_state_traceset_seek_time_closest(LttvTracesetState *self, LttTime t) + +void lttv_state_traceset_seek_time(LttvTraceset *traceset, LttTime t) { - LttvTraceset *traceset = self->parent.ts; + lttv_state_traceset_seek_time_closest(traceset, + t); + lttv_process_traceset_middle(traceset, t, G_MAXUINT, + NULL); +} + +void lttv_state_traceset_seek_position(LttvTraceset *traceset, LttvTracesetPosition *position) +{ + LttTime t = lttv_traceset_position_get_time(position); + + lttv_state_traceset_seek_time_closest(traceset, + t); + lttv_process_traceset_middle(traceset, + ltt_time_infinite, + G_MAXUINT, + position); +} +void lttv_state_traceset_seek_time_closest(LttvTraceset *traceset, LttTime t) +{ guint i, nb_trace; int min_pos, mid_pos, max_pos; - guint call_rest = 0; - - LttvTraceState *tcs; + guint resto_start = 0; + guint resto_at = 0; LttvAttributeValue value; @@ -4087,18 +3764,23 @@ void lttv_state_traceset_seek_time_closest(LttvTracesetState *self, LttTime t) gboolean is_named; LttvAttribute *saved_states_tree, *saved_state_tree, *closest_tree = NULL; + + LttTime closest_tree_time, restored_time; + guint first_restored_time = 1; //g_tree_destroy(self->parent.pqueue); //self->parent.pqueue = g_tree_new(compare_tracefile); - g_info("Entering seek_time_closest for time %lu.%lu", t.tv_sec, t.tv_nsec); + g_debug("Entering seek_time_closest for time %lu.%lu", t.tv_sec, t.tv_nsec); nb_trace = lttv_traceset_number(traceset); for(i = 0 ; i < nb_trace ; i++) { - tcs = (LttvTraceState *)self->parent.traces[i]; - if(ltt_time_compare(t, *(tcs->max_time_state_recomputed_in_seek)) < 0) { - saved_states_tree = lttv_attribute_find_subdir(tcs->parent.t_a, + LttvTrace *trace = lttv_traceset_get(traceset, i); + LttvTraceState *tstate = trace->state; + + if(ltt_time_compare(t, *(tstate->max_time_state_recomputed_in_seek)) < 0) { + saved_states_tree = lttv_attribute_find_subdir(trace->a, LTTV_STATE_SAVED_STATES); min_pos = -1; @@ -4116,6 +3798,7 @@ void lttv_state_traceset_seek_time_closest(LttvTracesetState *self, LttTime t) if(ltt_time_compare(*(value.v_time), t) < 0) { min_pos = mid_pos; closest_tree = saved_state_tree; + closest_tree_time = *(value.v_time); } else max_pos = mid_pos - 1; @@ -4125,25 +3808,63 @@ void lttv_state_traceset_seek_time_closest(LttvTracesetState *self, LttTime t) /* restore the closest earlier saved state */ if(min_pos != -1) { - lttv_state_restore(tcs, closest_tree); - call_rest = 1; + if(first_restored_time || (ltt_time_compare(restored_time, closest_tree_time) == 0)) { + first_restored_time = 0; + lttv_state_restore(tstate, closest_tree); + + restored_time = closest_tree_time; + } else { + g_debug("State: restored time mismatch between traces"); + resto_start = 1; + break; + } + } /* There is no saved state, yet we want to have it. Restart at T0 */ else { - restore_init_state(tcs); - lttv_process_trace_seek_time(&(tcs->parent), ltt_time_zero); + resto_start = 1; + break; } } /* We want to seek quickly without restoring/updating the state */ else { - restore_init_state(tcs); - lttv_process_trace_seek_time(&(tcs->parent), t); + resto_at = 1; + break; + } + } + + if(resto_start || resto_at) { + // Restore init state and seek so + for(i = 0 ; i < nb_trace ; i++) { + + LttvTrace *trace = lttv_traceset_get(traceset, i); + LttvTraceState *tstate = trace->state; + + restore_init_state(tstate); + } + + // If t > max saved state + if(resto_at) { + lttv_process_traceset_seek_time(traceset, t); + } else if (resto_start) { + // If no saved state + lttv_process_traceset_seek_time(traceset, ltt_time_zero); + } else { + g_assert(FALSE); } + g_info("NOT Calling restore"); + + } else { + // Seek at checkpoint + lttv_process_traceset_seek_time(traceset, restored_time); + + } - if(!call_rest) g_info("NOT Calling restore"); + + } -#endif + #ifdef BABEL_CLEANUP static void traceset_state_instance_init (GTypeInstance *instance, gpointer g_class) { @@ -4290,7 +4011,6 @@ GType lttv_tracefile_state_get_type(void) static void module_init(void) { LTTV_STATE_UNNAMED = g_quark_from_string(""); - LTTV_STATE_UNBRANDED = g_quark_from_string(""); LTTV_STATE_MODE_UNKNOWN = g_quark_from_string("MODE_UNKNOWN"); LTTV_STATE_USER_MODE = g_quark_from_string("USER_MODE"); LTTV_STATE_MAYBE_USER_MODE = g_quark_from_string("MAYBE_USER_MODE"); @@ -4371,7 +4091,6 @@ static void module_init(void) LTT_EVENT_STATEDUMP_END = g_quark_from_string("statedump_end"); LTT_EVENT_FUNCTION_ENTRY = g_quark_from_string("function_entry"); LTT_EVENT_FUNCTION_EXIT = g_quark_from_string("function_exit"); - LTT_EVENT_THREAD_BRAND = g_quark_from_string("thread_brand"); LTT_EVENT_REQUEST_ISSUE = g_quark_from_string("_blk_request_issue"); LTT_EVENT_REQUEST_COMPLETE = g_quark_from_string("_blk_request_complete"); LTT_EVENT_LIST_INTERRUPT = g_quark_from_string("interrupt");