LttvProcessStatus
LTTV_STATE_UNNAMED,
- LTTV_STATE_UNBRANDED,
LTTV_STATE_WAIT_FORK,
LTTV_STATE_WAIT_CPU,
LTTV_STATE_EXIT,
LTTV_STATE_RUN,
LTTV_STATE_DEAD;
+GQuark
+ LTTV_STATE_UNBRANDED;
+
LttvProcessType
LTTV_STATE_USER_THREAD,
LTTV_STATE_KERNEL_THREAD;
&g_array_index(self->running_process[i]->execution_stack,
LttvExecutionState, 0);
es->t = LTTV_STATE_MODE_UNKNOWN;
+ es->s = LTTV_STATE_UNNAMED;
- self->running_process[i]->state->s = LTTV_STATE_RUN;
+ //self->running_process[i]->state->s = LTTV_STATE_RUN;
self->running_process[i]->cpu = i;
}
process->state = es =
&g_array_index(process->execution_stack, LttvExecutionState, 0);
es->t = LTTV_STATE_MODE_UNKNOWN;
+ es->s = LTTV_STATE_UNNAMED;
}
return process;
}
//if(unlikely(process->pid != pid_out)) {
// g_assert(process->pid == 0);
//}
- if(process->pid == 0 && process->state->t == LTTV_STATE_MODE_UNKNOWN) {
- /* Scheduling out of pid 0 at beginning of the trace :
- * we know for sure it is in syscall mode at this point. */
- g_assert(process->execution_stack->len == 1);
- process->state->t = LTTV_STATE_SYSCALL;
- }
- if(unlikely(process->state->s == LTTV_STATE_EXIT)) {
- process->state->s = LTTV_STATE_ZOMBIE;
- process->state->change = s->parent.timestamp;
+ if(process->pid == 0
+ && process->state->t == LTTV_STATE_MODE_UNKNOWN) {
+ if(pid_out == 0) {
+ /* Scheduling out of pid 0 at beginning of the trace :
+ * we know for sure it is in syscall mode at this point. */
+ g_assert(process->execution_stack->len == 1);
+ process->state->t = LTTV_STATE_SYSCALL;
+ process->state->s = LTTV_STATE_WAIT;
+ process->state->change = s->parent.timestamp;
+ }
} else {
- if(unlikely(state_out == 0)) process->state->s = LTTV_STATE_WAIT_CPU;
- else process->state->s = LTTV_STATE_WAIT;
- process->state->change = s->parent.timestamp;
+ if(unlikely(process->state->s == LTTV_STATE_EXIT)) {
+ process->state->s = LTTV_STATE_ZOMBIE;
+ process->state->change = s->parent.timestamp;
+ } else {
+ if(unlikely(state_out == 0)) process->state->s = LTTV_STATE_WAIT_CPU;
+ else process->state->s = LTTV_STATE_WAIT;
+ process->state->change = s->parent.timestamp;
+ }
+
+ if(state_out == 32)
+ exit_process(s, process); /* EXIT_DEAD */
+ /* see sched.h for states */
}
-
- if(state_out == 32)
- exit_process(s, process); /* EXIT_DEAD */
- /* see sched.h for states */
}
process = ts->running_process[cpu] =
lttv_state_find_process_or_create(
es = &g_array_index(process->execution_stack, LttvExecutionState, 0);
if(es->t == LTTV_STATE_MODE_UNKNOWN) {
es->t = LTTV_STATE_SYSCALL;
- es->s = LTTV_STATE_WAIT;
es->n = LTTV_STATE_SUBMODE_NONE;
es->entry = *timestamp;
es->change = *timestamp;
es->cum_cpu_time = ltt_time_zero;
+ if(es->s == LTTV_STATE_UNNAMED)
+ es->s = LTTV_STATE_WAIT;
}
} else {
es = &g_array_index(process->execution_stack, LttvExecutionState, 0);
//g_assert(timestamp->tv_sec != 0);
es->change = *timestamp;
es->cum_cpu_time = ltt_time_zero;
- es->s = LTTV_STATE_RUN;
+ if(es->s == LTTV_STATE_UNNAMED)
+ es->s = LTTV_STATE_RUN;
if(process->execution_stack->len == 1) {
/* Still in user mode, means never scheduled */
LttField *f4, *f5, *f6, *f7, *f8;
GQuark type, mode, submode, status;
LttvExecutionState *es;
+ guint i, nb_cpus;
/* PID */
pid = ltt_event_get_unsigned(e, thf->f1);
if(f8) tgid = ltt_event_get_unsigned(e, f8);
else tgid = 0;
- /* The process might exist if a process was forked while performing the state
- * dump. */
- process = lttv_state_find_process(ts, ANY_CPU, pid);
- if(process == NULL) {
- parent_process = lttv_state_find_process(ts, ANY_CPU, parent_pid);
- process = lttv_state_create_process(ts, parent_process, cpu,
- pid, tgid, g_quark_from_string(command),
- &s->parent.timestamp);
-
- /* Keep the stack bottom : a running user mode */
- /* Disabled because of inconsistencies in the current statedump states. */
- if(type == LTTV_STATE_KERNEL_THREAD) {
- /* Only keep the bottom
- * FIXME Kernel thread : can be in syscall or interrupt or trap. */
- /* Will cause expected trap when in fact being syscall (even after end of
- * statedump event)
- * Will cause expected interrupt when being syscall. (only before end of
- * statedump event) */
- // This will cause a "popping last state on stack, ignoring it."
- process->execution_stack = g_array_set_size(process->execution_stack, 1);
- es = process->state = &g_array_index(process->execution_stack,
- LttvExecutionState, 0);
+
+ if(pid == 0) {
+ nb_cpus = ltt_trace_get_num_cpu(ts->parent.t);
+ for(i=0; i<nb_cpus; i++) {
+ process = lttv_state_find_process(ts, i, pid);
+ g_assert(process != NULL);
+
+ process->ppid = parent_pid;
+ process->tgid = tgid;
+ process->name = g_quark_from_string(command);
+ es =
+ &g_array_index(process->execution_stack, LttvExecutionState, 0);
process->type = LTTV_STATE_KERNEL_THREAD;
- es->t = LTTV_STATE_MODE_UNKNOWN;
- es->s = LTTV_STATE_UNNAMED;
- es->n = LTTV_STATE_SUBMODE_UNKNOWN;
-#if 0
- es->t = LTTV_STATE_SYSCALL;
- es->s = status;
- es->n = submode;
-#endif //0
+ }
+
+ } else {
+ /* The process might exist if a process was forked while performing the
+ * state dump. */
+ process = lttv_state_find_process(ts, ANY_CPU, pid);
+ if(process == NULL) {
+ parent_process = lttv_state_find_process(ts, ANY_CPU, parent_pid);
+ process = lttv_state_create_process(ts, parent_process, cpu,
+ pid, tgid, g_quark_from_string(command),
+ &s->parent.timestamp);
+
+ /* Keep the stack bottom : a running user mode */
+ /* Disabled because of inconsistencies in the current statedump states. */
+ if(type == LTTV_STATE_KERNEL_THREAD) {
+ /* Only keep the bottom
+ * FIXME Kernel thread : can be in syscall or interrupt or trap. */
+ /* Will cause expected trap when in fact being syscall (even after end of
+ * statedump event)
+ * Will cause expected interrupt when being syscall. (only before end of
+ * statedump event) */
+ // This will cause a "popping last state on stack, ignoring it."
+ process->execution_stack = g_array_set_size(process->execution_stack, 1);
+ es = process->state = &g_array_index(process->execution_stack,
+ LttvExecutionState, 0);
+ process->type = LTTV_STATE_KERNEL_THREAD;
+ es->t = LTTV_STATE_MODE_UNKNOWN;
+ es->s = LTTV_STATE_UNNAMED;
+ es->n = LTTV_STATE_SUBMODE_UNKNOWN;
+ #if 0
+ es->t = LTTV_STATE_SYSCALL;
+ es->s = status;
+ es->n = submode;
+ #endif //0
+ } else {
+ /* User space process :
+ * bottom : user mode
+ * either currently running or scheduled out.
+ * can be scheduled out because interrupted in (user mode or in syscall)
+ * or because of an explicit call to the scheduler in syscall. Note that
+ * the scheduler call comes after the irq_exit, so never in interrupt
+ * context. */
+ // temp workaround : set size to 1 : only have user mode bottom of stack.
+ // will cause g_info message of expected syscall mode when in fact being
+ // in user mode. Can also cause expected trap when in fact being user
+ // mode in the event of a page fault reenabling interrupts in the handler.
+ // Expected syscall and trap can also happen after the end of statedump
+ // This will cause a "popping last state on stack, ignoring it."
+ 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_MODE_UNKNOWN;
+ es->s = LTTV_STATE_UNNAMED;
+ es->n = LTTV_STATE_SUBMODE_UNKNOWN;
+ #if 0
+ es->t = LTTV_STATE_USER_MODE;
+ es->s = status;
+ es->n = submode;
+ #endif //0
+ }
+ #if 0
+ /* UNKNOWN STATE */
+ {
+ es = process->state = &g_array_index(process->execution_stack,
+ LttvExecutionState, 1);
+ es->t = LTTV_STATE_MODE_UNKNOWN;
+ es->s = LTTV_STATE_UNNAMED;
+ es->n = LTTV_STATE_SUBMODE_UNKNOWN;
+ }
+ #endif //0
} else {
- /* User space process :
- * bottom : user mode
- * either currently running or scheduled out.
- * can be scheduled out because interrupted in (user mode or in syscall)
- * or because of an explicit call to the scheduler in syscall. Note that
- * the scheduler call comes after the irq_exit, so never in interrupt
- * context. */
- // temp workaround : set size to 1 : only have user mode bottom of stack.
- // will cause g_info message of expected syscall mode when in fact being
- // in user mode. Can also cause expected trap when in fact being user
- // mode in the event of a page fault reenabling interrupts in the handler.
- // Expected syscall and trap can also happen after the end of statedump
- // This will cause a "popping last state on stack, ignoring it."
- 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_MODE_UNKNOWN;
- es->s = LTTV_STATE_UNNAMED;
- es->n = LTTV_STATE_SUBMODE_UNKNOWN;
+ /* The process has already been created :
+ * Probably was forked while dumping the process state or
+ * was simply scheduled in prior to get the state dump event.
+ */
+ process->ppid = parent_pid;
+ process->tgid = tgid;
+ process->name = g_quark_from_string(command);
+ process->type = type;
+ es =
+ &g_array_index(process->execution_stack, LttvExecutionState, 0);
#if 0
- es->t = LTTV_STATE_USER_MODE;
- es->s = status;
- es->n = submode;
+ if(es->t == LTTV_STATE_MODE_UNKNOWN) {
+ if(type == LTTV_STATE_KERNEL_THREAD)
+ es->t = LTTV_STATE_SYSCALL;
+ else
+ es->t = LTTV_STATE_USER_MODE;
+ }
#endif //0
+ /* Don't mess around with the stack, it will eventually become
+ * ok after the end of state dump. */
}
-#if 0
- /* UNKNOWN STATE */
- {
- es = process->state = &g_array_index(process->execution_stack,
- LttvExecutionState, 1);
- es->t = LTTV_STATE_MODE_UNKNOWN;
- es->s = LTTV_STATE_UNNAMED;
- es->n = LTTV_STATE_SUBMODE_UNKNOWN;
- }
-#endif //0
- } else {
- /* The process has already been created :
- * Probably was forked while dumping the process state or
- * was simply scheduled in prior to get the state dump event.
- * We know for sure if it is a user space thread.
- */
- process->ppid = parent_pid;
- process->tgid = tgid;
- process->name = g_quark_from_string(command);
- es =
- &g_array_index(process->execution_stack, LttvExecutionState, 0);
- if(type != LTTV_STATE_KERNEL_THREAD)
- es->t = LTTV_STATE_USER_MODE;
- /* Don't mess around with the stack, it will eventually become
- * ok after the end of state dump. */
}
return FALSE;
}
static void lttv_stats_cleanup_process_state(gpointer key, gpointer value,
- gpointer user_data)
-{
- LttvTraceStats *tcs = (LttvTraceStats *)user_data;
- LttvTraceState *ts = (LttvTraceState *)user_data;
- LttvTracesetContext *tsc = ts->parent.ts_context;
- LttvProcessState *process = (LttvProcessState *)value;
- int i;
- LttvTracefileStats **tfs = (LttvTracefileStats **)
- &g_array_index(ts->parent.tracefiles, LttvTracefileContext*,
- process->cpu);
- int cleanup_empty = 0;
- LttTime nested_delta = ltt_time_zero;
- /* FIXME : ok, this is a hack. The time is infinite here :( */
- LttTime save_time = (*tfs)->parent.parent.timestamp;
- LttTime start, end;
- ltt_trace_time_span_get(ts->parent.t, &start, &end);
- (*tfs)->parent.parent.timestamp = end;
-
- do {
- if(ltt_time_compare(process->state->cum_cpu_time, ltt_time_zero) != 0) {
- find_event_tree(*tfs, process->pid_time,
- process->cpu,
- process->current_function,
- process->state->t, process->state->n, &((*tfs)->current_events_tree),
- &((*tfs)->current_event_types_tree));
- mode_end(*tfs);
- nested_delta = process->state->cum_cpu_time;
- }
- cleanup_empty = lttv_state_pop_state_cleanup(process,
- (LttvTracefileState *)*tfs);
- process->state->cum_cpu_time = ltt_time_add(process->state->cum_cpu_time,
- nested_delta);
-
- } while(cleanup_empty != 1);
-
- (*tfs)->parent.parent.timestamp = save_time;
+ gpointer user_data)
+{
+ LttvTraceStats *tcs = (LttvTraceStats *)user_data;
+ LttvTraceState *ts = (LttvTraceState *)user_data;
+ LttvTracesetContext *tsc = ts->parent.ts_context;
+ LttvProcessState *process = (LttvProcessState *)value;
+ int i;
+ LttvTracefileStats **tfs = (LttvTracefileStats **)
+ &g_array_index(ts->parent.tracefiles, LttvTracefileContext*,
+ process->cpu);
+ int cleanup_empty = 0;
+ LttTime nested_delta = ltt_time_zero;
+ /* FIXME : ok, this is a hack. The time is infinite here :( */
+ LttTime save_time = (*tfs)->parent.parent.timestamp;
+ LttTime start, end;
+ ltt_trace_time_span_get(ts->parent.t, &start, &end);
+ (*tfs)->parent.parent.timestamp = end;
+
+ do {
+ if(ltt_time_compare(process->state->cum_cpu_time, ltt_time_zero) != 0) {
+ find_event_tree(*tfs, process->pid_time,
+ process->cpu,
+ process->current_function,
+ process->state->t, process->state->n, &((*tfs)->current_events_tree),
+ &((*tfs)->current_event_types_tree));
+ /* if it is a running mode, we must count its cpu time */
+ if(process->state->s == LTTV_STATE_RUN)
+ mode_end(*tfs);
+ nested_delta = process->state->cum_cpu_time;
+ }
+ cleanup_empty = lttv_state_pop_state_cleanup(process,
+ (LttvTracefileState *)*tfs);
+ process->state->cum_cpu_time = ltt_time_add(process->state->cum_cpu_time,
+ nested_delta);
+
+ } while(cleanup_empty != 1);
+
+ (*tfs)->parent.parent.timestamp = save_time;
}
/* For each process in the state, for each of their stacked states,
static void lttv_stats_cleanup_state(LttvTraceStats *tcs)
{
LttvTraceState *ts = (LttvTraceState *)tcs;
-
- /* Does not work correctly FIXME. */
- g_hash_table_foreach(ts->processes, lttv_stats_cleanup_process_state,
- tcs);
+
+ /* Does not work correctly FIXME. */
+ g_hash_table_foreach(ts->processes, lttv_stats_cleanup_process_state,
+ tcs);
}
void
LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
+ guint first_cpu, nb_cpus, cpu;
+
LttEvent *e;
e = ltt_tracefile_get_event(tfc->tf);
{
pid_in = ltt_event_get_long_unsigned(e, thf->f1);
}
+
+ if(pid_in == 0) {
+ first_cpu = 0;
+ nb_cpus = ltt_trace_get_num_cpu(ts->parent.t);
+ } else {
+ first_cpu = ANY_CPU;
+ nb_cpus = ANY_CPU+1;
+ }
-
- /* Find process pid_in in the list... */
- process_in = lttv_state_find_process(ts, ANY_CPU, pid_in);
- //process_in = tfs->process;
- //guint cpu = tfs->cpu;
- //guint trace_num = ts->parent.index;
- //process_in = ts->running_process[cpu];
- /* It should exist, because we are after the state update. */
-#ifdef EXTRA_CHECK
- //g_assert(process_in != NULL);
-#endif //EXTRA_CHECK
- birth = process_in->creation_time;
-
- hashed_process_data_in = processlist_get_process_data(process_list,
+ for(cpu = first_cpu; cpu < nb_cpus; cpu++) {
+ /* Find process pid_in in the list... */
+ process_in = lttv_state_find_process(ts, cpu, pid_in);
+ //process_in = tfs->process;
+ //guint cpu = tfs->cpu;
+ //guint trace_num = ts->parent.index;
+ //process_in = ts->running_process[cpu];
+ /* It should exist, because we are after the state update. */
+ #ifdef EXTRA_CHECK
+ //g_assert(process_in != NULL);
+ #endif //EXTRA_CHECK
+ birth = process_in->creation_time;
+
+ hashed_process_data_in = processlist_get_process_data(process_list,
+ pid_in,
+ process_in->cpu,
+ &birth,
+ trace_num);
+ if(hashed_process_data_in == NULL)
+ {
+ if(pid_in != 0 && pid_in == process_in->ppid)
+ g_critical("TEST %u , %u", pid_in, process_in->ppid);
+ g_assert(pid_in == 0 || pid_in != process_in->ppid);
+ ProcessInfo *process_info;
+ Drawing_t *drawing = control_flow_data->drawing;
+ /* Process not present */
+ processlist_add(process_list,
+ drawing,
pid_in,
+ process_in->tgid,
process_in->cpu,
+ process_in->ppid,
&birth,
- trace_num);
- if(hashed_process_data_in == NULL)
- {
- if(pid_in != 0 && pid_in == process_in->ppid)
- g_critical("TEST %u , %u", pid_in, process_in->ppid);
- g_assert(pid_in == 0 || pid_in != process_in->ppid);
- ProcessInfo *process_info;
- Drawing_t *drawing = control_flow_data->drawing;
- /* Process not present */
- processlist_add(process_list,
- drawing,
- pid_in,
- process_in->tgid,
- process_in->cpu,
- process_in->ppid,
- &birth,
- trace_num,
- process_in->name,
- process_in->brand,
- &pl_height,
- &process_info,
- &hashed_process_data_in);
- gtk_widget_set_size_request(drawing->drawing_area,
- -1,
- pl_height);
- gtk_widget_queue_draw(drawing->drawing_area);
- } else {
- processlist_set_name(process_list, process_in->name,
- hashed_process_data_in);
- processlist_set_ppid(process_list, process_in->ppid,
- hashed_process_data_in);
- processlist_set_tgid(process_list, process_in->tgid,
- hashed_process_data_in);
- }
+ trace_num,
+ process_in->name,
+ process_in->brand,
+ &pl_height,
+ &process_info,
+ &hashed_process_data_in);
+ gtk_widget_set_size_request(drawing->drawing_area,
+ -1,
+ pl_height);
+ gtk_widget_queue_draw(drawing->drawing_area);
+ } else {
+ processlist_set_name(process_list, process_in->name,
+ hashed_process_data_in);
+ processlist_set_ppid(process_list, process_in->ppid,
+ hashed_process_data_in);
+ processlist_set_tgid(process_list, process_in->tgid,
+ hashed_process_data_in);
+ }
+ }
return 0;
}
} else {
draw_context.drawinfo.start.x = hashed_process_data->x.middle;
/* Draw the line */
- if(dodraw) {
- PropertiesLine prop_line = prepare_s_e_line(process);
- draw_line((void*)&prop_line, (void*)&draw_context);
- }
+ if(dodraw) {
+ PropertiesLine prop_line = prepare_s_e_line(process);
+ draw_line((void*)&prop_line, (void*)&draw_context);
+ }
/* become the last x position */
if(likely(x != hashed_process_data->x.middle)) {