/* Get the name of a tracefile */
-GQuark ltt_tracefile_name(LttTracefile *tf);
+GQuark ltt_tracefile_name(const LttTracefile *tf);
+GQuark ltt_tracefile_long_name(const LttTracefile *tf);
/* get the cpu number of the tracefile */
*Get the name of a tracefile
****************************************************************************/
-GQuark ltt_tracefile_name(LttTracefile *tf)
+GQuark ltt_tracefile_name(const LttTracefile *tf)
{
return tf->name;
}
+GQuark ltt_tracefile_long_name(const LttTracefile *tf)
+{
+ return tf->long_name;
+}
+
+
guint ltt_tracefile_num(LttTracefile *tf)
{
tf->buffer.begin.timestamp = ltt_get_time(LTT_GET_BO(tf),
&header->begin.timestamp);
tf->buffer.begin.timestamp.tv_nsec *= NSEC_PER_USEC;
- g_debug("block %u begin : %lu.%lu", block_num,
- tf->buffer.begin.timestamp.tv_sec, tf->buffer.begin.timestamp.tv_nsec);
+ //g_debug("block %u begin : %lu.%lu", block_num,
+ // tf->buffer.begin.timestamp.tv_sec, tf->buffer.begin.timestamp.tv_nsec);
tf->buffer.begin.cycle_count = ltt_get_uint64(LTT_GET_BO(tf),
&header->begin.cycle_count);
tf->buffer.end.timestamp = ltt_get_time(LTT_GET_BO(tf),
&header->end.timestamp);
tf->buffer.end.timestamp.tv_nsec *= NSEC_PER_USEC;
- g_debug("block %u end : %lu.%lu", block_num,
- tf->buffer.end.timestamp.tv_sec, tf->buffer.end.timestamp.tv_nsec);
+ //g_debug("block %u end : %lu.%lu", block_num,
+ // tf->buffer.end.timestamp.tv_sec, tf->buffer.end.timestamp.tv_nsec);
tf->buffer.end.cycle_count = ltt_get_uint64(LTT_GET_BO(tf),
&header->end.cycle_count);
tf->buffer.lost_size = ltt_get_uint32(LTT_GET_BO(tf),
switch((enum ltt_core_events)tf->event.event_id) {
case LTT_EVENT_FACILITY_LOAD:
size = strlen((char*)tf->event.data) + 1;
- g_debug("Update Event facility load of facility %s", (char*)tf->event.data);
+ //g_debug("Update Event facility load of facility %s", (char*)tf->event.data);
size += sizeof(struct LttFacilityLoad);
break;
case LTT_EVENT_FACILITY_UNLOAD:
- g_debug("Update Event facility unload");
+ //g_debug("Update Event facility unload");
size = sizeof(struct LttFacilityUnload);
break;
case LTT_EVENT_STATE_DUMP_FACILITY_LOAD:
size = strlen((char*)tf->event.data) + 1;
- g_debug("Update Event facility load state dump of facility %s",
- (char*)tf->event.data);
+ //g_debug("Update Event facility load state dump of facility %s",
+ // (char*)tf->event.data);
size += sizeof(struct LttStateDumpFacilityLoad);
break;
case LTT_EVENT_HEARTBEAT:
- g_debug("Update Event heartbeat");
+ //g_debug("Update Event heartbeat");
size = sizeof(TimeHeartbeat);
break;
default:
else
size = 0;
- g_debug("Event root field : f.e %hhu.%hhu size %zd",
- tf->event.facility_id,
- tf->event.event_id, size);
+ //g_debug("Event root field : f.e %hhu.%hhu size %zd",
+ // tf->event.facility_id,
+ // tf->event.event_id, size);
}
tf->event.data_size = size;
#include <lttv/filter.h>
#include <ltt/trace.h>
+#include <ltt/type.h>
#include <stdlib.h>
#include <string.h>
case LTTV_FILTER_STATE_CPU:
if(context == NULL) return TRUE;
else {
- /* FIXME: not sure of that one */
- GQuark quark = ((LttvTracefileState*)context)->cpu_name;
- return se->op((gpointer)&quark,v);
+ /* FIXME: not sure of that one Mathieu : fixed.*/
+ // GQuark quark = ((LttvTracefileState*)context)->cpu_name;
+ // return se->op((gpointer)&quark,v);
+ if(state == NULL) return TRUE;
+ else return se->op((gpointer)&state->cpu,v);
}
break;
case LTTV_FILTER_EVENT_NAME:
LTTV_STATE_TRACEFILES,
LTTV_STATE_PROCESSES,
LTTV_STATE_PROCESS,
+ LTTV_STATE_RUNNING_PROCESS,
LTTV_STATE_EVENT,
LTTV_STATE_SAVED_STATES,
LTTV_STATE_SAVED_STATES_TIME,
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;
+ process_a->cpu != process_b->cpu)) ret = FALSE;
return ret;
}
static void
restore_init_state(LttvTraceState *self)
{
- guint i, nb_tracefile;
+ guint i, nb_cpus;
LttvTracefileState *tfcs;
+ /* Free the process tables */
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;
+ /* Seek time to beginning */
+ g_tree_destroy(self->parent.ts_context->pqueue);
+ self->parent.ts_context->pqueue = g_tree_new(compare_tracefile);
+
+ lttv_process_trace_seek_time(&self->parent, ltt_time_zero);
+
+ nb_cpus = ltt_trace_get_num_cpu(self->parent.t);
+
+ /* Put the per cpu running_process to beginning state : process 0. */
+ for(i=0; i< nb_cpus; i++) {
+ self->running_process[i] = lttv_state_create_process(self, NULL, i, 0,
+ <t_time_zero);
+ self->running_process[i]->state->s = LTTV_STATE_RUN;
+ self->running_process[i]->cpu = i;
+ }
+
+#if 0
nb_tracefile = self->parent.tracefiles->len;
for(i = 0 ; i < nb_tracefile ; i++) {
tfcs->process->last_cpu = tfcs->cpu_name;
tfcs->process->last_cpu_index = ltt_tracefile_num(((LttvTracefileContext*)tfcs)->tf);
}
+#endif //0
}
-static LttTime time_zero = {0,0};
+//static LttTime time_zero = {0,0};
static void
init(LttvTracesetState *self, LttvTraceset *ts)
get_max_time(tcs);
nb_tracefile = tc->tracefiles->len;
-
+#if 0
for(j = 0 ; j < nb_tracefile ; j++) {
tfcs =
LTTV_TRACEFILE_STATE(g_array_index(tc->tracefiles,
LttvTracefileContext*, j));
- tfcs->cpu_name = ltt_tracefile_name(tfcs->parent.tf);
+ tfcs->tracefile_name = ltt_tracefile_name(tfcs->parent.tf);
}
+#endif //0
tcs->processes = NULL;
+ tcs->running_process = g_new(LttvProcessState*,
+ ltt_trace_get_num_cpu(tc->t));
restore_init_state(tcs);
}
}
free_max_time(tcs);
free_saved_state(tcs);
}
+ g_free(tcs->running_process);
+ tcs->running_process = NULL;
lttv_state_free_process_table(tcs->processes);
tcs->processes = NULL;
}
process = (LttvProcessState *)value;
fprintf(fp,
-" <PROCESS CORE=%p PID=%u PPID=%u CTIME_S=%lu CTIME_NS=%lu NAME=\"%s\" CPU=\"%s\">\n",
+" <PROCESS CORE=%p PID=%u PPID=%u CTIME_S=%lu CTIME_NS=%lu NAME=\"%s\" CPU=\"%u\">\n",
process, process->pid, process->ppid, process->creation_time.tv_sec,
process->creation_time.tv_nsec, g_quark_to_string(process->name),
- g_quark_to_string(process->last_cpu));
+ process->cpu);
for(i = 0 ; i < process->execution_stack->len; i++) {
es = &g_array_index(process->execution_stack, LttvExecutionState, i);
LttEventPosition *ep;
+ guint nb_cpus;
+
ep = ltt_event_position_new();
fprintf(fp,"<PROCESS_STATE TIME_S=%lu TIME_NS=%lu>\n", t.tv_sec, t.tv_nsec);
g_hash_table_foreach(self->processes, write_process_state, fp);
+
+ nb_cpus = ltt_trace_get_num_cpu(self->parent.t);
+ for(i=0;i<nb_cpus;i++) {
+ fprintf(fp,"<CPU NUM=%u RUNNING_PROCESS=%u>\n",
+ i, self->running_process[i]->pid);
+ }
nb_tracefile = self->parent.tracefiles->len;
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,
+ fprintf(fp, " <TRACEFILE TIMESTAMP_S=%lu TIMESTAMP_NS=%lu",
+ tfcs->parent.timestamp.tv_sec,
tfcs->parent.timestamp.tv_nsec);
LttEvent *e = ltt_tracefile_get_event(tfcs->parent.tf);
if(e == NULL) fprintf(fp,"/>\n");
static void state_save(LttvTraceState *self, LttvAttribute *container)
{
- guint i, nb_tracefile;
+ guint i, nb_tracefile, nb_cpus;
LttvTracefileState *tfcs;
LttvAttribute *tracefiles_tree, *tracefile_tree;
+
+ guint *running_process;
LttvAttributeType type;
LTTV_POINTER);
*(value.v_pointer) = lttv_state_copy_process_table(self->processes);
+ /* Add the currently running processes array */
+ nb_cpus = ltt_trace_get_num_cpu(self->parent.t);
+ running_process = g_new(guint, nb_cpus);
+ for(i=0;i<nb_cpus;i++) {
+ running_process[i] = self->running_process[i]->pid;
+ }
+ value = lttv_attribute_add(container, LTTV_STATE_RUNNING_PROCESS,
+ LTTV_POINTER);
+ *(value.v_pointer) = running_process;
+
+
nb_tracefile = self->parent.tracefiles->len;
for(i = 0 ; i < nb_tracefile ; i++) {
value = lttv_attribute_add(tracefiles_tree, i,
LTTV_GOBJECT);
*(value.v_gobject) = (GObject *)tracefile_tree;
+#if 0
value = lttv_attribute_add(tracefile_tree, LTTV_STATE_PROCESS,
LTTV_UINT);
*(value.v_uint) = tfcs->process->pid;
+#endif //0
value = lttv_attribute_add(tracefile_tree, LTTV_STATE_EVENT,
LTTV_POINTER);
/* Only save the position if the tfs has not infinite time. */
static void state_restore(LttvTraceState *self, LttvAttribute *container)
{
- guint i, nb_tracefile, pid;
+ guint i, nb_tracefile, pid, nb_cpus;
LttvTracefileState *tfcs;
LttvAttribute *tracefiles_tree, *tracefile_tree;
+ guint *running_process;
+
LttvAttributeType type;
LttvAttributeValue value;
lttv_state_free_process_table(self->processes);
self->processes = lttv_state_copy_process_table(*(value.v_pointer));
+ /* Add the currently running processes array */
+ nb_cpus = ltt_trace_get_num_cpu(self->parent.t);
+ type = lttv_attribute_get_by_name(container, LTTV_STATE_RUNNING_PROCESS,
+ &value);
+ g_assert(type == LTTV_POINTER);
+ running_process = *(value.v_pointer);
+ for(i=0;i<nb_cpus;i++) {
+ pid = running_process[i];
+ self->running_process[i] = lttv_state_find_process(self, i, pid);
+ g_assert(self->running_process[i] != NULL);
+ }
+
+
nb_tracefile = self->parent.tracefiles->len;
g_tree_destroy(tsc->pqueue);
type = lttv_attribute_get(tracefiles_tree, i, &name, &value);
g_assert(type == LTTV_GOBJECT);
tracefile_tree = *((LttvAttribute **)(value.v_gobject));
-
+#if 0
type = lttv_attribute_get_by_name(tracefile_tree, LTTV_STATE_PROCESS,
&value);
g_assert(type == LTTV_UINT);
pid = *(value.v_uint);
tfcs->process = lttv_state_find_process_or_create(tfcs, pid);
-
+#endif //0
type = lttv_attribute_get_by_name(tracefile_tree, LTTV_STATE_EVENT,
&value);
g_assert(type == LTTV_POINTER);
static void state_saved_free(LttvTraceState *self, LttvAttribute *container)
{
- guint i, nb_tracefile;
+ guint i, nb_tracefile, nb_cpus;
LttvTracefileState *tfcs;
LttvAttribute *tracefiles_tree, *tracefile_tree;
+ guint *running_process;
+
LttvAttributeType type;
LttvAttributeValue value;
*(value.v_pointer) = NULL;
lttv_attribute_remove_by_name(container, LTTV_STATE_PROCESSES);
+ /* Free running processes array */
+ nb_cpus = ltt_trace_get_num_cpu(self->parent.t);
+ type = lttv_attribute_get_by_name(tracefile_tree, LTTV_STATE_RUNNING_PROCESS,
+ &value);
+ g_assert(type == LTTV_POINTER);
+ running_process = *(value.v_pointer);
+ g_free(running_process);
+
nb_tracefile = self->parent.tracefiles->len;
for(i = 0 ; i < nb_tracefile ; i++) {
LTTV_POINTER, &v);
g_assert(*(v.v_pointer) == NULL);
*(v.v_pointer) = g_new(LttTime,1);
- *((LttTime *)*(v.v_pointer)) = time_zero;
+ *((LttTime *)*(v.v_pointer)) = ltt_time_zero;
}
guint state_id)
{
LttvExecutionState *es;
-
- LttvProcessState *process = tfs->process;
+
+ guint cpu = ltt_tracefile_num(tfs->parent.tf);
+ LttvTraceState *ts = (LttvTraceState*)tfs->parent.t_context;
+ LttvProcessState *process = ts->running_process[cpu];
guint depth = process->execution_stack->len;
static void pop_state(LttvTracefileState *tfs, LttvExecutionMode t)
{
- LttvProcessState *process = tfs->process;
+ guint cpu = ltt_tracefile_num(tfs->parent.tf);
+ LttvTraceState *ts = (LttvTraceState*)tfs->parent.t_context;
+ LttvProcessState *process = ts->running_process[cpu];
guint depth = process->execution_stack->len;
LttvProcessState *
-lttv_state_create_process(LttvTracefileState *tfs, LttvProcessState *parent,
- guint pid)
+lttv_state_create_process(LttvTraceState *tcs, LttvProcessState *parent,
+ guint cpu, guint pid, const LttTime *timestamp)
{
LttvProcessState *process = g_new(LttvProcessState, 1);
LttvExecutionState *es;
- LttvTraceContext *tc;
-
- LttvTraceState *tcs;
+ LttvTraceContext *tc = (LttvTraceContext*)tcs;
char buffer[128];
- tc = tfs->parent.t_context;
- tcs = (LttvTraceState *)tc;
-
process->pid = pid;
- process->last_cpu = tfs->cpu_name;
- process->last_cpu_index = ltt_tracefile_num(((LttvTracefileContext*)tfs)->tf);
+ process->cpu = cpu;
+ //process->last_cpu = tfs->cpu_name;
+ //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->ppid = parent->pid;
process->name = parent->name;
- process->creation_time = tfs->parent.timestamp;
+ process->creation_time = *timestamp;
}
/* No parent. This process exists but we are missing all information about
process->creation_time = ltt_time_zero;
}
- process->insertion_time = tfs->parent.timestamp;
+ process->insertion_time = *timestamp;
sprintf(buffer,"%d-%lu.%lu",pid, process->creation_time.tv_sec,
process->creation_time.tv_nsec);
process->pid_time = g_quark_from_string(buffer);
- process->last_cpu = tfs->cpu_name;
- process->last_cpu_index = ltt_tracefile_num(((LttvTracefileContext*)tfs)->tf);
+ process->cpu = cpu;
+ //process->last_cpu = tfs->cpu_name;
+ //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);
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->entry = *timestamp;
+ //g_assert(timestamp->tv_sec != 0);
+ es->change = *timestamp;
es->s = LTTV_STATE_WAIT_FORK;
return process;
}
-LttvProcessState *lttv_state_find_process(LttvTracefileState *tfs,
+LttvProcessState *lttv_state_find_process(LttvTraceState *ts, guint cpu,
guint pid)
{
LttvProcessState key;
LttvProcessState *process;
- LttvTraceState* ts = (LttvTraceState*)tfs->parent.t_context;
-
key.pid = pid;
- key.last_cpu = tfs->cpu_name;
+ key.cpu = cpu;
process = g_hash_table_lookup(ts->processes, &key);
return process;
}
LttvProcessState *
-lttv_state_find_process_or_create(LttvTracefileState *tfs, guint pid)
+lttv_state_find_process_or_create(LttvTraceState *ts, guint cpu, guint pid,
+ LttTime *timestamp)
{
- LttvProcessState *process = lttv_state_find_process(tfs, pid);
-
- if(unlikely(process == NULL)) process = lttv_state_create_process(tfs, NULL, pid);
+ LttvProcessState *process = lttv_state_find_process(ts, cpu, pid);
+
+ /* Put ltt_time_zero creation time for unexisting processes */
+ if(unlikely(process == NULL)) process = lttv_state_create_process(ts,
+ NULL, cpu, pid, timestamp);
return process;
}
LttvProcessState key;
key.pid = process->pid;
- key.last_cpu = process->last_cpu;
+ key.cpu = process->cpu;
g_hash_table_remove(ts->processes, &key);
g_array_free(process->execution_stack, TRUE);
g_free(process);
static gboolean schedchange(void *hook_data, void *call_data)
{
LttvTracefileState *s = (LttvTracefileState *)call_data;
+ guint cpu = ltt_tracefile_num(s->parent.tf);
+ LttvTraceState *ts = (LttvTraceState*)s->parent.t_context;
+ LttvProcessState *process = ts->running_process[cpu];
+
LttEvent *e = ltt_tracefile_get_event(s->parent.tf);
LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
guint pid_in, pid_out;
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(likely(s->process != NULL)) {
+
+ if(likely(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
//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(process->pid != pid_out)) {
+ // g_assert(process->pid == 0);
//}
- if(unlikely(s->process->state->s == LTTV_STATE_EXIT)) {
- s->process->state->s = LTTV_STATE_ZOMBIE;
+ if(unlikely(process->state->s == LTTV_STATE_EXIT)) {
+ 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;
+ 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, s->process);
+ // exit_process(s, process);
- s->process->state->change = s->parent.timestamp;
+ 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;
+ process = ts->running_process[cpu] =
+ lttv_state_find_process_or_create(
+ (LttvTraceState*)s->parent.t_context,
+ cpu, pid_in,
+ &s->parent.timestamp);
+ process->state->s = LTTV_STATE_RUN;
+ process->cpu = cpu;
+ // process->last_cpu_index = ltt_tracefile_num(((LttvTracefileContext*)s)->tf);
+ process->state->change = s->parent.timestamp;
return FALSE;
}
guint parent_pid;
guint child_pid;
LttvProcessState *zombie_process;
+ guint cpu = ltt_tracefile_num(s->parent.tf);
+ LttvTraceState *ts = (LttvTraceState*)s->parent.t_context;
+ LttvProcessState *process = ts->running_process[cpu];
/* Parent PID */
f = thf->f1;
f = thf->f2;
child_pid = ltt_event_get_unsigned(e, f);
- zombie_process = lttv_state_find_process(s, child_pid);
+ zombie_process = lttv_state_find_process(ts, ANY_CPU, child_pid);
if(unlikely(zombie_process != NULL)) {
/* Reutilisation of PID. Only now we are sure that the old PID
*/
exit_process(s, zombie_process);
}
- g_assert(s->process->pid != child_pid);
+ g_assert(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);
+ // g_assert(process->pid == parent_pid);
+ lttv_state_create_process(ts, process, cpu, child_pid, &s->parent.timestamp);
return FALSE;
}
LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
LttField *f;
guint pid;
+ guint cpu = ltt_tracefile_num(s->parent.tf);
+ LttvTraceState *ts = (LttvTraceState*)s->parent.t_context;
+ LttvProcessState *process = ts->running_process[cpu];
pid = ltt_event_get_unsigned(e, thf->f1);
// FIXME : Add this test in the "known state" section
- // g_assert(s->process->pid == pid);
+ // g_assert(process->pid == pid);
- if(likely(s->process != NULL)) {
- s->process->state->s = LTTV_STATE_EXIT;
+ if(likely(process != NULL)) {
+ process->state->s = LTTV_STATE_EXIT;
}
return FALSE;
}
static gboolean process_free(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);
LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
guint release_pid;
/* PID of the process to release */
release_pid = ltt_event_get_unsigned(e, thf->f1);
- process = lttv_state_find_process(s, release_pid);
+ process = lttv_state_find_process(ts, ANY_CPU, release_pid);
if(likely(process != NULL)) {
/* release_task is happening at kernel level : we can now safely release
}
}
-
+static guint test_event_count = 0;
static gboolean state_save_event_hook(void *hook_data, void *call_data)
{
guint *event_count = (guint*)hook_data;
+ test_event_count++;
/* Only save at LTTV_STATE_SAVE_INTERVAL */
if(likely((*event_count)++ < LTTV_STATE_SAVE_INTERVAL))
return FALSE;
}
g_free(event_count);
}
+ g_info("EVENT COUNT TEST : %u", test_event_count);
}
gint lttv_state_save_hook_remove_event_hooks(void *hook_data, void *call_data)
LttvAttribute *saved_states_tree, *saved_state_tree, *closest_tree;
+ g_tree_destroy(self->parent.pqueue);
+ self->parent.pqueue = g_tree_new(compare_tracefile);
+
nb_trace = lttv_traceset_number(traceset);
for(i = 0 ; i < nb_trace ; i++) {
tcs = (LttvTraceState *)self->parent.traces[i];
LTTV_STATE_TRACEFILES = g_quark_from_string("tracefiles");
LTTV_STATE_PROCESSES = g_quark_from_string("processes");
LTTV_STATE_PROCESS = g_quark_from_string("process");
+ LTTV_STATE_RUNNING_PROCESS = g_quark_from_string("running_process");
LTTV_STATE_EVENT = g_quark_from_string("event");
LTTV_STATE_SAVED_STATES = g_quark_from_string("saved states");
LTTV_STATE_SAVED_STATES_TIME = g_quark_from_string("saved states time");
/* WARNING : each time the execution_stack size is modified, the state
* must be reget : g_array_set_size can have to move the array.
* (Mathieu) */
- GQuark last_cpu; /* Last CPU where process was scheduled */
- guint last_cpu_index; /* index in the trace for cpu tracefile */
+ guint cpu; /* CPU where process is scheduled (being either in
+ the active or inactive runqueue)*/
+// guint last_tracefile_index; /* index in the trace for cpu tracefile */
/* opened file descriptors, address map?... */
} LttvProcessState;
+#define ANY_CPU 0 /* For clarity sake : a call to lttv_state_find_process for
+ a PID != 0 will search on any cpu automatically. */
+
LttvProcessState *
-lttv_state_find_process(LttvTracefileState *tfs, guint pid);
+lttv_state_find_process(LttvTraceState *ts, guint cpu, guint pid);
LttvProcessState *
-lttv_state_find_process_or_create(LttvTracefileState *tfs, guint pid);
+lttv_state_find_process_or_create(LttvTraceState *ts, guint cpu, guint pid,
+ LttTime *timestamp);
LttvProcessState *
-lttv_state_create_process(LttvTracefileState *tfs, LttvProcessState *parent,
- guint pid);
+lttv_state_create_process(LttvTraceState *ts, LttvProcessState *parent,
+ guint cpu, guint pid, const LttTime *timestamp);
void lttv_state_write(LttvTraceState *self, LttTime t, FILE *fp);
GQuark *trap_names;
GQuark *irq_names;
LttTime *max_time_state_recomputed_in_seek;
+
+ /* Array of per cpu running process */
+ LttvProcessState **running_process;
+
};
struct _LttvTraceStateClass {
struct _LttvTracefileState {
LttvTracefileContext parent;
- LttvProcessState *process;
- GQuark cpu_name;
+ //LttvProcessState *process;
+ GQuark tracefile_name;
// guint saved_position;
};
LttvTracefileContext*, j);
tfcs = LTTV_TRACEFILE_STATS(*tfs);
tfcs->stats = lttv_attribute_find_subdir(tracefiles_stats,
- tfcs->parent.cpu_name);
+ ltt_tracefile_long_name(tfcs->parent.parent.tf));
find_event_tree(tfcs, LTTV_STATS_PROCESS_UNKNOWN,
- tfcs->parent.cpu_name, LTTV_STATE_MODE_UNKNOWN,
+ ltt_tracefile_long_name(tfcs->parent.parent.tf),
+ LTTV_STATE_MODE_UNKNOWN,
LTTV_STATE_SUBMODE_UNKNOWN, &tfcs->current_events_tree,
&tfcs->current_event_types_tree);
}
static void update_event_tree(LttvTracefileStats *tfcs)
{
- LttvExecutionState *es = tfcs->parent.process->state;
+ LttvTraceState *ts = (LttvTraceState *)tfcs->parent.parent.t_context;
+ guint cpu = ltt_tracefile_num(tfcs->parent.parent.tf);
+ LttvProcessState *process = ts->running_process[cpu];
+ LttvExecutionState *es = process->state;
- find_event_tree(tfcs, tfcs->parent.process->pid_time,
- tfcs->parent.cpu_name,
+ find_event_tree(tfcs, process->pid_time,
+ ltt_tracefile_long_name(tfcs->parent.parent.tf),
es->t, es->n, &(tfcs->current_events_tree),
&(tfcs->current_event_types_tree));
}
static void mode_change(LttvTracefileStats *tfcs)
{
+ LttvTraceState *ts = (LttvTraceState *)tfcs->parent.parent.t_context;
+ guint cpu = ltt_tracefile_num(tfcs->parent.parent.tf);
+ LttvProcessState *process = ts->running_process[cpu];
LttvAttributeValue cpu_time;
LttTime delta;
lttv_attribute_find(tfcs->current_events_tree, LTTV_STATS_CPU_TIME,
LTTV_TIME, &cpu_time);
delta = ltt_time_sub(tfcs->parent.parent.timestamp,
- tfcs->parent.process->state->change);
+ process->state->change);
*(cpu_time.v_time) = ltt_time_add(*(cpu_time.v_time), delta);
}
static void mode_end(LttvTracefileStats *tfcs)
{
+ LttvTraceState *ts = (LttvTraceState *)tfcs->parent.parent.t_context;
+ guint cpu = ltt_tracefile_num(tfcs->parent.parent.tf);
+ LttvProcessState *process = ts->running_process[cpu];
LttvAttributeValue elapsed_time, cpu_time;
LttTime delta;
lttv_attribute_find(tfcs->current_events_tree, LTTV_STATS_ELAPSED_TIME,
LTTV_TIME, &elapsed_time);
delta = ltt_time_sub(tfcs->parent.parent.timestamp,
- tfcs->parent.process->state->entry);
+ process->state->entry);
*(elapsed_time.v_time) = ltt_time_add(*(elapsed_time.v_time), delta);
lttv_attribute_find(tfcs->current_events_tree, LTTV_STATS_CPU_TIME,
LTTV_TIME, &cpu_time);
delta = ltt_time_sub(tfcs->parent.parent.timestamp,
- tfcs->parent.process->state->change);
+ process->state->change);
*(cpu_time.v_time) = ltt_time_add(*(cpu_time.v_time), delta);
}
{
LttvTracefileStats *tfcs = (LttvTracefileStats *)call_data;
+ LttvTraceState *ts = (LttvTraceState*)tfcs->parent.parent.t_context;
+
LttEvent *e = ltt_tracefile_get_event(tfcs->parent.parent.tf);
LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data;
/* get the information for the process scheduled in */
- process = lttv_state_find_process_or_create(&(tfcs->parent), pid_in);
+ process = lttv_state_find_process_or_create(ts,
+ ANY_CPU, pid_in, &tfcs->parent.parent.timestamp);
- find_event_tree(tfcs, process->pid_time, tfcs->parent.cpu_name,
+ find_event_tree(tfcs, process->pid_time,
+ ltt_tracefile_long_name(tfcs->parent.parent.tf),
process->state->t, process->state->n, &(tfcs->current_events_tree),
&(tfcs->current_event_types_tree));
/* Subtile modification :
* if tracefile has no event at or after the time requested, it is not put in
- * the queue, as the next read would fail. */
+ * the queue, as the next read would fail.
+ *
+ * Don't forget to empty the traceset pqueue before calling this.
+ */
void lttv_process_trace_seek_time(LttvTraceContext *self, LttTime start)
{
guint i, nb_tracefile;
nb_tracefile = self->tracefiles->len;
- g_tree_destroy(self->ts_context->pqueue);
- self->ts_context->pqueue = g_tree_new(compare_tracefile);
-
GTree *pqueue = self->ts_context->pqueue;
for(i = 0 ; i < nb_tracefile ; i++) {
LttvTraceContext *tc;
+ g_tree_destroy(self->pqueue);
+ self->pqueue = g_tree_new(compare_tracefile);
+
nb_trace = lttv_traceset_number(self->ts);
for(i = 0 ; i < nb_trace ; i++) {
tc = self->traces[i];
LttvTracefileContext *tfc = (LttvTracefileContext *)call_data;
LttvTracefileState *tfs = (LttvTracefileState *)call_data;
+ LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
LttEvent *e;
e = ltt_tracefile_get_event(tfc->tf);
* draw items from the beginning of the read for it. If it is not
* present, it's a new process and it was not present : it will
* be added after the state update. */
- LttvProcessState *process;
+ guint cpu = ltt_tracefile_num(tfc->tf);
+ LttvProcessState *process = ts->running_process[cpu];
/* unknown state, bad current pid */
- if(tfs->process->pid != pid_out)
- process = lttv_state_find_process(tfs, pid_out);
- else
- process = tfs->process;
+ if(process->pid != pid_out)
+ process = lttv_state_find_process(ts, ANY_CPU, pid_out);
if(process != NULL) {
/* Well, the process_out existed : we must get it in the process hash
hashed_process_data = processlist_get_process_data(process_list,
pid_out,
- process->last_cpu_index,
+ process->cpu,
&birth,
tfc->t_context->index);
if(hashed_process_data == NULL)
processlist_add(process_list,
drawing,
pid_out,
- process->last_cpu_index,
+ process->cpu,
process->ppid,
&birth,
tfc->t_context->index,
* present, it's a new process and it was not present : it will
* be added after the state update. */
LttvProcessState *process;
- process = lttv_state_find_process(tfs, pid_in);
+ process = lttv_state_find_process(ts, ANY_CPU, pid_in);
if(process != NULL) {
/* Well, the process_out existed : we must get it in the process hash
hashed_process_data = processlist_get_process_data(process_list,
pid_in,
- process->last_cpu_index,
+ process->cpu,
&birth,
tfc->t_context->index);
if(hashed_process_data == NULL)
processlist_add(process_list,
drawing,
pid_in,
- process->last_cpu_index,
+ process->cpu,
process->ppid,
&birth,
tfc->t_context->index,
LttvTracefileState *tfs = (LttvTracefileState *)call_data;
+ LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
+
LttEvent *e;
e = ltt_tracefile_get_event(tfc->tf);
/* Find process pid_in in the list... */
- //process_in = lttv_state_find_process(tfs, pid_in);
- process_in = tfs->process;
+ //process_in = lttv_state_find_process(ts, ANY_CPU, pid_in);
+ //process_in = tfs->process;
+ guint cpu = ltt_tracefile_num(tfc->tf);
+ process_in = ts->running_process[cpu];
/* It should exist, because we are after the state update. */
#ifdef EXTRA_CHECK
g_assert(process_in != NULL);
hashed_process_data_in = processlist_get_process_data(process_list,
pid_in,
- process_in->last_cpu_index,
+ process_in->cpu,
&birth,
tfc->t_context->index);
if(hashed_process_data_in == NULL)
processlist_add(process_list,
drawing,
pid_in,
- process_in->last_cpu_index,
+ process_in->cpu,
process_in->ppid,
&birth,
tfc->t_context->index,
gtk_widget_queue_draw(drawing->drawing_area);
}
/* Set the current process */
- process_list->current_hash_data[process_in->last_cpu_index] =
+ process_list->current_hash_data[process_in->cpu] =
hashed_process_data_in;
if(ltt_time_compare(hashed_process_data_in->next_good_time,
LttvTracefileState *tfs = (LttvTracefileState *)call_data;
+ LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
+
LttEvent *e;
e = ltt_tracefile_get_event(tfc->tf);
* time to do it.
*/
/* For the pid */
- LttvProcessState *process = tfs->process;
+ //LttvProcessState *process = tfs->process;
+ guint cpu = ltt_tracefile_num(tfc->tf);
+ LttvProcessState *process = ts->running_process[cpu];
g_assert(process != NULL);
guint pid = process->pid;
ProcessList *process_list = control_flow_data->process_list;
LttTime birth = process->creation_time;
- if(likely(process_list->current_hash_data[ltt_tracefile_num(tfc->tf)] != NULL)) {
- hashed_process_data = process_list->current_hash_data[ltt_tracefile_num(tfc->tf)];
+ if(likely(process_list->current_hash_data[cpu] != NULL)) {
+ hashed_process_data = process_list->current_hash_data[cpu];
} else {
hashed_process_data = processlist_get_process_data(process_list,
pid,
- process->last_cpu_index,
+ process->cpu,
&birth,
tfc->t_context->index);
if(unlikely(hashed_process_data == NULL))
processlist_add(process_list,
drawing,
pid,
- process->last_cpu_index,
+ process->cpu,
process->ppid,
&birth,
tfc->t_context->index,
gtk_widget_queue_draw(drawing->drawing_area);
}
/* Set the current process */
- process_list->current_hash_data[process->last_cpu_index] =
+ process_list->current_hash_data[process->cpu] =
hashed_process_data;
}
* This function adds items to be drawn in a queue for each process.
*
*/
+#if 0
int after_execmode_hook(void *hook_data, void *call_data)
{
/**************** DOES NOTHING!! *************/
}
return 0;
}
-
+#endif //0
LttvTracefileState *tfs = (LttvTracefileState *)call_data;
+ LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
+
LttEvent *e;
e = ltt_tracefile_get_event(tfc->tf);
LttTime evtime = ltt_event_time(e);
/* Add process to process list (if not present) */
- LttvProcessState *process = tfs->process;
+ //LttvProcessState *process = tfs->process;
+ guint cpu = ltt_tracefile_num(tfc->tf);
+ LttvProcessState *process = ts->running_process[cpu];
guint pid = process->pid;
LttTime birth;
guint pl_height = 0;
birth = process->creation_time;
- if(likely(process_list->current_hash_data[ltt_tracefile_num(tfc->tf)] != NULL)) {
- hashed_process_data = process_list->current_hash_data[ltt_tracefile_num(tfc->tf)];
+ if(likely(process_list->current_hash_data[cpu] != NULL)) {
+ hashed_process_data = process_list->current_hash_data[cpu];
} else {
hashed_process_data = processlist_get_process_data(process_list,
pid,
- process->last_cpu_index,
+ process->cpu,
&birth,
tfc->t_context->index);
if(unlikely(hashed_process_data == NULL))
processlist_add(process_list,
drawing,
pid,
- process->last_cpu_index,
+ process->cpu,
process->ppid,
&birth,
tfc->t_context->index,
LttvTracefileState *tfs = (LttvTracefileState *)call_data;
+ LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
+
LttEvent *e;
e = ltt_tracefile_get_event(tfc->tf);
/* Don't care about the process if it's not in the state hash already :
* that means a process that has never done anything in the trace and
* unknown suddently gets destroyed : no state meaningful to show. */
- LttvProcessState *process = lttv_state_find_process(tfs, pid);
+ LttvProcessState *process = lttv_state_find_process(ts, ANY_CPU, pid);
if(process != NULL) {
LttTime birth;
* action done by the parent. */
hashed_process_data = processlist_get_process_data(process_list,
pid,
- process->last_cpu_index,
+ process->cpu,
&birth,
tfc->t_context->index);
if(unlikely(hashed_process_data == NULL))
processlist_add(process_list,
drawing,
pid,
- process->last_cpu_index,
+ process->cpu,
process->ppid,
&birth,
tfc->t_context->index,
LttvTracefileState *tfs = (LttvTracefileState *)call_data;
+ LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
+
LttEvent *e;
e = ltt_tracefile_get_event(tfc->tf);
ProcessList *process_list = control_flow_data->process_list;
/* Find child in the list... */
- process_child = lttv_state_find_process(tfs, child_pid);
+ process_child = lttv_state_find_process(ts, ANY_CPU, child_pid);
/* It should exist, because we are after the state update. */
g_assert(process_child != NULL);
* on its child. */
hashed_process_data_child = processlist_get_process_data(process_list,
child_pid,
- process_child->last_cpu_index,
+ process_child->cpu,
&birth,
tfc->t_context->index);
if(likely(hashed_process_data_child == NULL))
processlist_add(process_list,
drawing,
child_pid,
- process_child->last_cpu_index,
+ process_child->cpu,
process_child->ppid,
&birth,
tfc->t_context->index,
LttvTracefileState *tfs = (LttvTracefileState *)call_data;
+ LttvTraceState *ts = (LttvTraceState *)tfc->t_context;
+
LttEvent *e;
e = ltt_tracefile_get_event(tfc->tf);
LttTime evtime = ltt_event_time(e);
/* Add process to process list (if not present) */
- LttvProcessState *process = tfs->process;
+ //LttvProcessState *process = tfs->process;
+ guint cpu = ltt_tracefile_num(tfc->tf);
+ LttvProcessState *process = ts->running_process[cpu];
+
+ /* It should exist, because we are after the state update. */
+ g_assert(process != NULL);
+
guint pid = process->pid;
LttTime birth;
guint pl_height = 0;
ProcessList *process_list = control_flow_data->process_list;
- /* It should exist, because we are after the state update. */
- g_assert(process != NULL);
-
birth = process->creation_time;
- if(likely(process_list->current_hash_data[ltt_tracefile_num(tfc->tf)] != NULL) ){
- hashed_process_data = process_list->current_hash_data[ltt_tracefile_num(tfc->tf)];
+ if(likely(process_list->current_hash_data[cpu] != NULL) ){
+ hashed_process_data = process_list->current_hash_data[cpu];
} else {
hashed_process_data = processlist_get_process_data(process_list,
pid,
- process->last_cpu_index,
+ process->cpu,
&birth,
tfc->t_context->index);
if(unlikely(hashed_process_data == NULL))
processlist_add(process_list,
drawing,
pid,
- process->last_cpu_index,
+ process->cpu,
process->ppid,
&birth,
tfc->t_context->index,
}
/* Set the current process */
- process_list->current_hash_data[process->last_cpu_index] =
+ process_list->current_hash_data[process->cpu] =
hashed_process_data;
}
g_assert(lttv_traceset_number(tsc->ts) > 0);
#endif //EXTRA_CHECK
LttvTraceContext *tc = tsc->traces[process_info->trace_num];
+ LttvTraceState *ts = (LttvTraceState*)tc;
+#if 0
//FIXME : optimize data structures.
LttvTracefileState *tfs;
LttvTracefileContext *tfc;
}
g_assert(i<tc->tracefiles->len);
tfs = LTTV_TRACEFILE_STATE(tfc);
-
+#endif //0
// LttvTracefileState *tfs =
// (LttvTracefileState*)tsc->traces[process_info->trace_num]->
// tracefiles[process_info->cpu];
LttvProcessState *process;
- process = lttv_state_find_process(tfs,
+ process = lttv_state_find_process(ts, process_info->cpu,
process_info->pid);
if(unlikely(process != NULL)) {
if(likely(pa->pid != pb->pid))
ret = FALSE;
- else if(likely((pa->pid == 0 && (pa->cpu != pb->cpu))))
+ if(likely((pa->pid == 0 && (pa->cpu != pb->cpu))))
ret = FALSE;
- else if(unlikely(ltt_time_compare(pa->birth, pb->birth) != 0))
+ if(unlikely(ltt_time_compare(pa->birth, pb->birth) != 0))
ret = FALSE;
- else if(unlikely(pa->trace_num != pb->trace_num))
+ if(unlikely(pa->trace_num != pb->trace_num))
ret = FALSE;
return ret;
lttv_process_traceset_middle(tsc,
events_request->start_time,
G_MAXUINT, NULL);
+ // g_assert(seek_count < 50000);
} else {