LTTV_STATE_EXIT,
LTTV_STATE_ZOMBIE,
LTTV_STATE_WAIT,
- LTTV_STATE_RUN;
+ LTTV_STATE_RUN,
+ LTTV_STATE_DEAD;
static GQuark
LTTV_STATE_TRACEFILES,
nb_tracefile = self->parent.tracefiles->len;
- g_tree_destroy(tsc->pqueue);
- tsc->pqueue = g_tree_new(compare_tracefile);
+ //g_tree_destroy(tsc->pqueue);
+ //tsc->pqueue = g_tree_new(compare_tracefile);
for(i = 0 ; i < nb_tracefile ; i++) {
tfcs =
g_assert(tfcs->parent.t_context != NULL);
LttvTracefileContext *tfc = LTTV_TRACEFILE_CONTEXT(tfcs);
+ g_tree_remove(tsc->pqueue, tfc);
if(ep != NULL) {
g_assert(ltt_tracefile_seek_position(tfc->tf, ep) == 0);
//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);
+ process->execution_stack = g_array_set_size(process->execution_stack, 2);
es = process->state = &g_array_index(process->execution_stack,
LttvExecutionState, 0);
es->t = LTTV_STATE_USER_MODE;
es->entry = *timestamp;
//g_assert(timestamp->tv_sec != 0);
es->change = *timestamp;
+ es->s = LTTV_STATE_RUN;
+
+ es = process->state = &g_array_index(process->execution_stack,
+ LttvExecutionState, 1);
+ es->t = LTTV_STATE_SYSCALL;
+ es->n = LTTV_STATE_SUBMODE_NONE;
+ es->entry = *timestamp;
+ //g_assert(timestamp->tv_sec != 0);
+ es->change = *timestamp;
es->s = LTTV_STATE_WAIT_FORK;
return process;
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;
- } /* 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, process);
-
- process->state->change = s->parent.timestamp;
+ process->state->change = s->parent.timestamp;
+ }
+
+ 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(
/* Mathieu : it seems like the process might have been scheduled in before the
* fork, and, in a rare case, might be the current process. This might happen
- * in a SMP case where we don't have enough precision on the clocks */
-#if 0
+ * in a SMP case where we don't have enough precision on the clocks.
+ *
+ * Test reenabled after precision fixes on time. (Mathieu) */
+#if 0
zombie_process = lttv_state_find_process(ts, ANY_CPU, child_pid);
if(unlikely(zombie_process != NULL)) {
guint num_cpus = ltt_trace_get_num_cpu(ts->parent.t);
guint i;
for(i=0; i< num_cpus; i++) {
- g_assert(process != ts->running_process[i]);
+ g_assert(zombie_process != ts->running_process[i]);
}
exit_process(s, zombie_process);
child_pid, &s->parent.timestamp);
} else {
/* The process has already been created : due to time imprecision between
- * multiple CPUs : it has been scheduled in before creation.
+ * multiple CPUs : it has been scheduled in before creation. Note that we
+ * shouldn't have this kind of imprecision.
*
* Simply put a correct parent.
*/
+ g_assert(0); /* This is a problematic case : the process has been created
+ before the fork event */
child_process->ppid = process->pid;
}
if(likely(process != NULL)) {
/* release_task is happening at kernel level : we can now safely release
* the data structure of the process */
+ //This test is fun, though, as it may happen that
+ //at time t : CPU 0 : process_free
+ //at time t+150ns : CPU 1 : schedule out
+ //Clearly due to time imprecision, we disable it. (Mathieu)
+ //If this weird case happen, we have no choice but to put the
+ //Currently running process on the cpu to 0.
+ //I re-enable it following time precision fixes. (Mathieu)
+ //Well, in the case where an process is freed by a process on another CPU
+ //and still scheduled, it happens that this is the schedchange that will
+ //drop the last reference count. Do not free it here!
guint num_cpus = ltt_trace_get_num_cpu(ts->parent.t);
guint i;
for(i=0; i< num_cpus; i++) {
- g_assert(process != ts->running_process[i]);
+ //g_assert(process != ts->running_process[i]);
+ if(process == ts->running_process[i]) {
+ //ts->running_process[i] = lttv_state_find_process(ts, i, 0);
+ break;
+ }
}
- exit_process(s, process);
+ if(i == num_cpus) /* process is not scheduled */
+ exit_process(s, process);
}
return FALSE;
return FALSE;
}
+static gboolean state_save_after_trace_hook(void *hook_data, void *call_data)
+{
+ LttvTraceState *tcs = (LttvTraceState *)(call_data);
+
+ *(tcs->max_time_state_recomputed_in_seek) = tcs->parent.time_span.end_time;
+
+ return FALSE;
+}
+
#if 0
static gboolean block_start(void *hook_data, void *call_data)
{
}
}
+
+ 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)
LttvTracefileState *tfs;
+ LttvHooks *after_trace = lttv_hooks_new();
+
+ lttv_hooks_add(after_trace,
+ state_save_after_trace_hook,
+ NULL,
+ LTTV_PRIO_STATE);
+
+
+ lttv_process_traceset_end(&self->parent,
+ NULL, after_trace, NULL, NULL, NULL);
+ lttv_hooks_destroy(after_trace);
+
nb_trace = lttv_traceset_number(traceset);
for(i = 0 ; i < nb_trace ; i++) {
LttvTracefileContext*, j));
event_count = lttv_hooks_remove(tfs->parent.event,
state_save_event_hook);
-
}
g_free(event_count);
}
LttvAttribute *saved_states_tree, *saved_state_tree, *closest_tree;
- g_tree_destroy(self->parent.pqueue);
- self->parent.pqueue = g_tree_new(compare_tracefile);
+ //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);
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_DEAD = g_quark_from_string("dead");
LTTV_STATE_TRACEFILES = g_quark_from_string("tracefiles");
LTTV_STATE_PROCESSES = g_quark_from_string("processes");
LTTV_STATE_PROCESS = g_quark_from_string("process");