#include <ltt/type.h>
#include <stdio.h>
+#define PREALLOCATED_EXECUTION_STACK 10
+
LttvExecutionMode
LTTV_STATE_MODE_UNKNOWN,
LTTV_STATE_USER_MODE,
LTTV_STATE_WAIT_FORK,
LTTV_STATE_WAIT_CPU,
LTTV_STATE_EXIT,
+ LTTV_STATE_ZOMBIE,
LTTV_STATE_WAIT,
LTTV_STATE_RUN;
guint process_hash(gconstpointer key)
{
- return ((const LttvProcessState *)key)->pid;
+ guint pid = ((const LttvProcessState *)key)->pid;
+ return (pid>>8 ^ pid>>4 ^ pid>>2 ^ pid) ;
}
+/* If the hash table hash function is well distributed,
+ * the process_equal should compare different pid */
gboolean process_equal(gconstpointer a, gconstpointer b)
{
const LttvProcessState *process_a, *process_b;
-
+ gboolean ret = TRUE;
+
process_a = (const LttvProcessState *)a;
process_b = (const LttvProcessState *)b;
+
+ if(likely(process_a->pid != process_b->pid)) ret = FALSE;
+ else if(likely(process_a->pid == 0 &&
+ process_a->last_cpu != process_b->last_cpu)) ret = FALSE;
- if(process_a->pid != process_b->pid) return FALSE;
- if(process_a->pid == 0 &&
- process_a->last_cpu != process_b->last_cpu) return FALSE;
- return TRUE;
+ return ret;
}
tfcs->process = lttv_state_create_process(tfcs, NULL,0);
tfcs->process->state->s = LTTV_STATE_RUN;
tfcs->process->last_cpu = tfcs->cpu_name;
+ tfcs->process->last_cpu_index = ((LttvTracefileContext*)tfcs)->index;
}
}
process = (LttvProcessState *)value;
new_process = g_new(LttvProcessState, 1);
*new_process = *process;
- new_process->execution_stack = g_array_new(FALSE, FALSE,
- sizeof(LttvExecutionState));
+ new_process->execution_stack = g_array_sized_new(FALSE, FALSE,
+ sizeof(LttvExecutionState), PREALLOCATED_EXECUTION_STACK);
g_array_set_size(new_process->execution_stack,process->execution_stack->len);
for(i = 0 ; i < process->execution_stack->len; i++) {
g_array_index(new_process->execution_stack, LttvExecutionState, i) =
process->pid = pid;
process->last_cpu = tfs->cpu_name;
+ process->last_cpu_index = ((LttvTracefileContext*)tfs)->index;
g_warning("Process %u, core %p", process->pid, process);
g_hash_table_insert(tcs->processes, process, process);
process->creation_time.tv_nsec);
process->pid_time = g_quark_from_string(buffer);
process->last_cpu = tfs->cpu_name;
- process->execution_stack = g_array_new(FALSE, FALSE,
- sizeof(LttvExecutionState));
+ process->last_cpu_index = ((LttvTracefileContext*)tfs)->index;
+ process->execution_stack = g_array_sized_new(FALSE, FALSE,
+ sizeof(LttvExecutionState), PREALLOCATED_EXECUTION_STACK);
g_array_set_size(process->execution_stack, 1);
es = process->state = &g_array_index(process->execution_stack,
LttvExecutionState, 0);
{
LttvProcessState *process = lttv_state_find_process(tfs, pid);
- if(process == NULL) process = lttv_state_create_process(tfs, NULL, pid);
+ if(unlikely(process == NULL)) process = lttv_state_create_process(tfs, NULL, pid);
return process;
}
pid_out = ltt_event_get_unsigned(s->parent.e, h->f2);
state_out = ltt_event_get_unsigned(s->parent.e, h->f3);
- if(s->process != NULL) {
+ if(likely(s->process != NULL)) {
/* We could not know but it was not the idle process executing.
This should only happen at the beginning, before the first schedule
is missing. It is not obvious how we could, after the fact, compensate
the wrongly attributed statistics. */
- if(s->process->pid != pid_out) {
+ if(unlikely(s->process->pid != pid_out)) {
g_assert(s->process->pid == 0);
}
- if(s->process->state->s != LTTV_STATE_EXIT) {
- if(state_out == 0) s->process->state->s = LTTV_STATE_WAIT_CPU;
+ if(unlikely(s->process->state->s == LTTV_STATE_EXIT)) {
+ s->process->state->s = LTTV_STATE_ZOMBIE;
+ } else {
+ if(unlikely(state_out == 0)) s->process->state->s = LTTV_STATE_WAIT_CPU;
else s->process->state->s = LTTV_STATE_WAIT;
} /* FIXME : we do not remove process here, because the kernel
* still has them : they may be zombies. We need to know
* exactly when release_task is executed on the PID to
- * know when the zombie is destroyed. We should rename STATE_EXIT
- * for STATE_ZOMBIE.
+ * know when the zombie is destroyed.
*/
//else
// exit_process(s, s->process);
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 = ((LttvTracefileContext*)s)->index;
s->process->state->change = s->parent.timestamp;
return FALSE;
}
zombie_process = lttv_state_find_process(s, child_pid);
- if(zombie_process != NULL) {
+ if(unlikely(zombie_process != NULL)) {
/* Reutilisation of PID. Only now we are sure that the old PID
* has been released. FIXME : sould know when release_task happens instead.
*/
exit_process(s, zombie_process);
}
+ g_assert(s->process->pid != child_pid);
lttv_state_create_process(s, s->process, child_pid);
return FALSE;
static gboolean process_exit(LttvTraceHook *trace_hook, LttvTracefileState *s)
{
- if(s->process != NULL) {
+ if(likely(s->process != NULL)) {
s->process->state->s = LTTV_STATE_EXIT;
}
return FALSE;
LTTV_STATE_SUBMODE_NONE = g_quark_from_string("(no submode)");
LTTV_STATE_WAIT_CPU = g_quark_from_string("wait for cpu");
LTTV_STATE_EXIT = g_quark_from_string("exiting");
+ LTTV_STATE_ZOMBIE = g_quark_from_string("zombie");
LTTV_STATE_WAIT = g_quark_from_string("wait for I/O");
LTTV_STATE_RUN = g_quark_from_string("running");
LTTV_STATE_TRACEFILES = g_quark_from_string("tracefiles");