X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=ltt%2Fbranches%2Fpoly%2Flttv%2Flttv%2Fstate.c;h=823bbe78aeb96a83359f8618764f0c7cce90b4a7;hb=8743690d339401db862834d50f9b6bbd1268271f;hp=567843002704ffa92605772b2bc466f7c68f289f;hpb=61c8808ef2d7a2bc51619b12ae930d476afb0e8e;p=lttv.git diff --git a/ltt/branches/poly/lttv/lttv/state.c b/ltt/branches/poly/lttv/lttv/state.c index 56784300..823bbe78 100644 --- a/ltt/branches/poly/lttv/lttv/state.c +++ b/ltt/branches/poly/lttv/lttv/state.c @@ -127,6 +127,18 @@ LttvProcessType LTTV_STATE_USER_THREAD, LTTV_STATE_KERNEL_THREAD; +LttvCPUMode + LTTV_CPU_UNKNOWN, + LTTV_CPU_IDLE, + LTTV_CPU_BUSY, + LTTV_CPU_IRQ, + LTTV_CPU_TRAP; + +LttvIRQMode + LTTV_IRQ_UNKNOWN, + LTTV_IRQ_IDLE, + LTTV_IRQ_BUSY; + static GQuark LTTV_STATE_TRACEFILES, LTTV_STATE_PROCESSES, @@ -376,7 +388,8 @@ end: static void init(LttvTracesetState *self, LttvTraceset *ts) { - guint i, j, nb_trace, nb_tracefile; + guint i, j, nb_trace, nb_tracefile, nb_cpu; + guint64 nb_irq; LttvTraceContext *tc; @@ -406,10 +419,26 @@ init(LttvTracesetState *self, LttvTraceset *ts) get_max_time(tcs); nb_tracefile = tc->tracefiles->len; + nb_cpu = ltt_trace_get_num_cpu(tc->t); + nb_irq = tcs->nb_irqs; tcs->processes = NULL; tcs->usertraces = NULL; - tcs->running_process = g_new(LttvProcessState*, - ltt_trace_get_num_cpu(tc->t)); + tcs->running_process = g_new(LttvProcessState*, nb_cpu); + + /* init cpu resource stuff */ + tcs->cpu_states = g_new(LttvCPUState, nb_cpu); + for(j = 0; jcpu_states[j].mode_stack = g_array_new(FALSE, FALSE, sizeof(LttvCPUMode)); + g_assert(tcs->cpu_states[j].mode_stack != NULL); + } + + /* init irq resource stuff */ + tcs->irq_states = g_new(LttvIRQState, nb_irq); + for(j = 0; jirq_states[j].mode_stack = g_array_new(FALSE, FALSE, sizeof(LttvIRQMode)); + g_assert(tcs->irq_states[j].mode_stack != NULL); + } + restore_init_state(tcs); for(j = 0 ; j < nb_tracefile ; j++) { tfcs = @@ -417,6 +446,7 @@ init(LttvTracesetState *self, LttvTraceset *ts) LttvTracefileContext*, j)); tfcs->tracefile_name = ltt_tracefile_name(tfcs->parent.tf); tfcs->cpu = ltt_tracefile_cpu(tfcs->parent.tf); + tfcs->cpu_state = &(tcs->cpu_states[tfcs->cpu]); if(ltt_tracefile_tid(tfcs->parent.tf) != 0) { /* It's a Usertrace */ guint tid = ltt_tracefile_tid(tfcs->parent.tf); @@ -1575,6 +1605,47 @@ static void hash_table_check(GHashTable *table) #endif +/* clears the stack and sets the state passed as argument */ +static void cpu_set_base_mode(LttvCPUState *cpust, LttvCPUMode state) +{ + g_array_set_size(cpust->mode_stack, 1); + ((GQuark *)cpust->mode_stack->data)[0] = state; +} + +static void cpu_push_mode(LttvCPUState *cpust, LttvCPUMode state) +{ + g_array_set_size(cpust->mode_stack, cpust->mode_stack->len + 1); + ((GQuark *)cpust->mode_stack->data)[cpust->mode_stack->len - 1] = state; +} + +static void cpu_pop_mode(LttvCPUState *cpust) +{ + if(cpust->mode_stack->len == 1) + cpu_set_base_mode(cpust, LTTV_CPU_UNKNOWN); + else + g_array_set_size(cpust->mode_stack, cpust->mode_stack->len - 1); +} + +/* clears the stack and sets the state passed as argument */ +static void irq_set_base_mode(LttvIRQState *irqst, LttvIRQMode state) +{ + g_array_set_size(irqst->mode_stack, 1); + ((GQuark *)irqst->mode_stack->data)[0] = state; +} + +static void irq_push_mode(LttvIRQState *irqst, LttvIRQMode state) +{ + g_array_set_size(irqst->mode_stack, irqst->mode_stack->len + 1); + ((GQuark *)irqst->mode_stack->data)[irqst->mode_stack->len - 1] = state; +} + +static void irq_pop_mode(LttvIRQState *irqst) +{ + if(irqst->mode_stack->len == 1) + irq_set_base_mode(irqst, LTTV_IRQ_UNKNOWN); + else + g_array_set_size(irqst->mode_stack, irqst->mode_stack->len - 1); +} static void push_state(LttvTracefileState *tfs, LttvExecutionMode t, guint state_id) @@ -1934,22 +2005,29 @@ static gboolean trap_entry(void *hook_data, void *call_data) } push_state(s, LTTV_STATE_TRAP, submode); + + /* update cpu status */ + cpu_push_mode(s->cpu_state, LTTV_CPU_TRAP); + return FALSE; } - static gboolean trap_exit(void *hook_data, void *call_data) { LttvTracefileState *s = (LttvTracefileState *)call_data; pop_state(s, LTTV_STATE_TRAP); + + /* update cpu status */ + cpu_pop_mode(s->cpu_state); + return FALSE; } - static gboolean irq_entry(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); guint8 fac_id = ltt_event_facility_id(e); guint8 ev_id = ltt_event_eventtype_id(e); @@ -1976,6 +2054,14 @@ static gboolean irq_entry(void *hook_data, void *call_data) /* Do something with the info about being in user or system mode when int? */ push_state(s, LTTV_STATE_IRQ, submode); + + /* update cpu status */ + cpu_push_mode(s->cpu_state, LTTV_CPU_IRQ); + + /* update irq status */ + s->cpu_state->last_irq = irq; + irq_push_mode(&ts->irq_states[irq], LTTV_IRQ_BUSY); + return FALSE; } @@ -1992,8 +2078,16 @@ static gboolean soft_irq_exit(void *hook_data, void *call_data) static gboolean irq_exit(void *hook_data, void *call_data) { LttvTracefileState *s = (LttvTracefileState *)call_data; + LttvTraceState *ts = (LttvTraceState *)s->parent.t_context; pop_state(s, LTTV_STATE_IRQ); + + /* update cpu status */ + cpu_pop_mode(s->cpu_state); + + /* update irq status */ + irq_pop_mode(&ts->irq_states[s->cpu_state->last_irq]); + return FALSE; } @@ -2181,6 +2275,13 @@ static gboolean schedchange(void *hook_data, void *call_data) process->usertrace->cpu = cpu; // process->last_cpu_index = ltt_tracefile_num(((LttvTracefileContext*)s)->tf); process->state->change = s->parent.timestamp; + + /* update cpu status */ + if(pid_in == 0) + cpu_set_base_mode(s->cpu_state, LTTV_CPU_IDLE); + else + cpu_set_base_mode(s->cpu_state, LTTV_CPU_BUSY); + return FALSE; } @@ -3513,6 +3614,15 @@ static void module_init() LTT_FIELD_THIS_FN = g_quark_from_string("this_fn"); LTT_FIELD_CALL_SITE = g_quark_from_string("call_site"); + LTTV_CPU_UNKNOWN = g_quark_from_string("unknown"); + LTTV_CPU_IDLE = g_quark_from_string("idle"); + LTTV_CPU_BUSY = g_quark_from_string("busy"); + LTTV_CPU_IRQ = g_quark_from_string("irq"); + LTTV_CPU_TRAP = g_quark_from_string("trap"); + + LTTV_IRQ_UNKNOWN = g_quark_from_string("unknown"); + LTTV_IRQ_IDLE = g_quark_from_string("idle"); + LTTV_IRQ_BUSY = g_quark_from_string("busy"); } static void module_destroy()