* MA 02111-1307, USA.
*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
#include <lttv/lttv.h>
#include <lttv/module.h>
#include <ltt/type.h>
#include <stdio.h>
+#define PREALLOCATED_EXECUTION_STACK 10
+
LttvExecutionMode
LTTV_STATE_MODE_UNKNOWN,
LTTV_STATE_USER_MODE,
}
+/* 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(unlikely(s->process->state->s == LTTV_STATE_EXIT)) {
s->process->state->s = LTTV_STATE_ZOMBIE;
} else {
- if(state_out == 0) s->process->state->s = LTTV_STATE_WAIT_CPU;
+ 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
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.
*/
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;
}
+static gboolean process_release(LttvTraceHook *trace_hook,
+ LttvTracefileState *s)
+{
+ LttField *f;
+ guint release_pid;
+ LttvProcessState *process;
+
+ /* PID of the process to release */
+ f = trace_hook->f2;
+ release_pid = ltt_event_get_unsigned(s->parent.e, f);
+
+ process = lttv_state_find_process(s, release_pid);
+
+ if(likely(process != NULL)) {
+ /* release_task is happening at kernel level : we can now safely release
+ * the data structure of the process */
+ exit_process(s, process);
+ }
+
+ return FALSE;
+}
+
gboolean process(void *hook_data, void *call_data)
{
LttvTraceHook *trace_hook = (LttvTraceHook *)hook_data;
return process_fork(trace_hook, s);
} else if(sub_id == 3) {
return process_exit(trace_hook, s);
+ } else if(sub_id == 7) {
+ return process_release(trace_hook, s);
}
return 0;
}