LTT_FIELD_ADDRESS,
LTT_FIELD_SYMBOL,
LTT_FIELD_IP,
- LTT_FIELD_FD;
+ LTT_FIELD_FD,
+ LTT_FIELD_STATE,
+ LTT_FIELD_CPU_ID;
LttvExecutionMode
LTTV_STATE_MODE_UNKNOWN,
static LttvBdevState *bdevstate_copy(LttvBdevState *bds);
-#if (__SIZEOF_LONG__ == 4)
+#if (__WORDSIZE == 32)
guint guint64_hash(gconstpointer key)
{
guint64 ukey = *(const guint64 *)key;
static void expand_kprobe_table(LttvTraceState *ts, guint64 ip, char *symbol)
{
LttvNameTables *nt = ts->name_tables;
-#if (__SIZEOF_LONG__ == 4)
+#if (__WORDSIZE == 32)
guint64 *ip_ptr = g_new(guint64, 1);
g_hash_table_insert(nt->kprobe_hash, ip_ptr,
(gpointer)(glong)g_quark_from_string(symbol));
name_tables->irq_names[i] = g_quark_from_string(ltt_enum_string_get(t, i));
}
*/
+ /* FIXME: LttvIRQState *irq_states should become a g_array */
+ /* temp fix: increase from 256 to 512 default size */
- name_tables->nb_irqs = 256;
- name_tables->irq_names = g_new(GQuark, 256);
- for(i = 0 ; i < 256 ; i++) {
+ name_tables->nb_irqs = 512;
+ name_tables->irq_names = g_new(GQuark, 512);
+ for(i = 0 ; i < 512 ; i++) {
g_string_printf(fe_name, "irq %d", i);
name_tables->irq_names[i] = g_quark_from_string(fe_name->str);
}
g_string_free(fe_name, TRUE);
-#if (__SIZEOF_LONG__ == 4)
+#if (__WORDSIZE == 32)
name_tables->kprobe_hash = g_hash_table_new_full(guint64_hash, guint64_equal,
g_free, NULL);
#else
return FALSE;
}
+static gboolean sched_try_wakeup(void *hook_data, void *call_data)
+{
+ LttvTracefileState *s = (LttvTracefileState *)call_data;
+ LttEvent *e = ltt_tracefile_get_event(s->parent.tf);
+ LttvTraceHook *th = (LttvTraceHook *)hook_data;
+ LttvProcessState *process;
+ gint woken_pid;
+ guint woken_cpu;
+
+ woken_pid = ltt_event_get_int(e, lttv_trace_get_hook_field(th, 0));
+ woken_cpu = ltt_event_get_unsigned(e, lttv_trace_get_hook_field(th, 1));
+
+ process = lttv_state_find_process_or_create(
+ (LttvTraceState*)s->parent.t_context,
+ woken_cpu, woken_pid,
+ &s->parent.timestamp);
+ process->state->s = LTTV_STATE_WAIT_CPU;
+ process->state->change = s->parent.timestamp;
+
+ g_debug("Wakeup: process %d on CPU %u\n", woken_pid, woken_cpu);
+
+ return FALSE;
+}
+
static gboolean schedchange(void *hook_data, void *call_data)
{
LttvTracefileState *s = (LttvTracefileState *)call_data;
return FALSE;
}
+static void print_stack(LttvProcessState *process)
+{
+ LttvExecutionState *es;
+ int i;
+
+ g_debug("Execution stack for process %u %s:\n",
+ process->pid, g_quark_to_string(process->name));
+
+ for (i = 0; i < process->execution_stack->len; i++) {
+ es = &g_array_index(process->execution_stack,
+ LttvExecutionState, i);
+ g_debug("Depth %d mode %s submode %s status %s\n",
+ i, g_quark_to_string(es->t),
+ g_quark_to_string(es->n),
+ g_quark_to_string(es->s));
+ }
+
+}
+
static void fix_process(gpointer key, gpointer value,
gpointer user_data)
{
process = (LttvProcessState *)value;
LttTime *timestamp = (LttTime*)user_data;
+ print_stack(process);
+
if(process->type == LTTV_STATE_KERNEL_THREAD) {
es = &g_array_index(process->execution_stack, LttvExecutionState, 0);
if(es->t == LTTV_STATE_MODE_UNKNOWN) {
es->s = LTTV_STATE_RUN;
if(process->execution_stack->len == 1) {
- /* Still in bottom unknown mode, means never did a system call
+ /* Still in bottom unknown mode, means we either:
+ * - never did a system call
+ * - are scheduled out from user mode.
* May be either in user mode, syscall mode, running or waiting.*/
- /* FIXME : we may be tagging syscall mode when being user mode */
- process->execution_stack =
- g_array_set_size(process->execution_stack, 2);
- 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->cum_cpu_time = ltt_time_zero;
- if(es->s == LTTV_STATE_WAIT_FORK)
- es->s = LTTV_STATE_WAIT;
+ /* CHECK : we may be tagging syscall mode when being user mode
+ * (should be fixed now) */
+ if (es->s == LTTV_STATE_WAIT_CPU) {
+ /* nothing to do: scheduled out from userspace */
+ } else {
+ process->execution_stack =
+ g_array_set_size(process->execution_stack, 2);
+ 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->cum_cpu_time = ltt_time_zero;
+ if(es->s == LTTV_STATE_WAIT_FORK)
+ es->s = LTTV_STATE_WAIT;
+ }
}
}
}
LTT_FIELD_PREV_STATE),
schedchange, NULL, &hooks);
+ lttv_trace_find_hook(ts->parent.t,
+ LTT_CHANNEL_KERNEL,
+ LTT_EVENT_SCHED_TRY_WAKEUP,
+ FIELD_ARRAY(LTT_FIELD_PID, LTT_FIELD_CPU_ID, LTT_FIELD_STATE),
+ sched_try_wakeup, NULL, &hooks);
+
lttv_trace_find_hook(ts->parent.t,
LTT_CHANNEL_KERNEL,
LTT_EVENT_PROCESS_FORK,
LTT_FIELD_SYMBOL = g_quark_from_string("symbol");
LTT_FIELD_IP = g_quark_from_string("ip");
LTT_FIELD_FD = g_quark_from_string("fd");
+ LTT_FIELD_STATE = g_quark_from_string("state");
+ LTT_FIELD_CPU_ID = g_quark_from_string("cpu_id");
LTTV_CPU_UNKNOWN = g_quark_from_string("unknown");
LTTV_CPU_IDLE = g_quark_from_string("idle");