X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=ltt%2Fbranches%2Fpoly%2Flttv%2Flttv%2Fstate.c;h=b0f79fcfac323326486c13e6cebc26e81ae3dbd6;hb=29af7cfdc9979121f09db4ba7c154f52d0fb518e;hp=0a058c62dae633d29a943bd0b4721ddd6c494e4f;hpb=0c0168a8f2530b37c6b63a340835f8141adbed27;p=lttv.git diff --git a/ltt/branches/poly/lttv/lttv/state.c b/ltt/branches/poly/lttv/lttv/state.c index 0a058c62..b0f79fcf 100644 --- a/ltt/branches/poly/lttv/lttv/state.c +++ b/ltt/branches/poly/lttv/lttv/state.c @@ -75,7 +75,8 @@ GQuark LTT_EVENT_FUNCTION_EXIT, LTT_EVENT_THREAD_BRAND, LTT_EVENT_REQUEST_ISSUE, - LTT_EVENT_REQUEST_COMPLETE; + LTT_EVENT_REQUEST_COMPLETE, + LTT_EVENT_LIST_INTERRUPT; /* Fields Quarks */ @@ -102,7 +103,9 @@ GQuark LTT_FIELD_CALL_SITE, LTT_FIELD_MINOR, LTT_FIELD_MAJOR, - LTT_FIELD_OPERATION; + LTT_FIELD_OPERATION, + LTT_FIELD_ACTION, + LTT_FIELD_NUM; LttvExecutionMode LTTV_STATE_MODE_UNKNOWN, @@ -164,7 +167,8 @@ static GQuark LTTV_STATE_NAME_TABLES, LTTV_STATE_TRACE_STATE_USE_COUNT, LTTV_STATE_RESOURCE_CPUS, - LTTV_STATE_RESOURCE_IRQS; + LTTV_STATE_RESOURCE_IRQS, + LTTV_STATE_RESOURCE_BLKDEVS; static void create_max_time(LttvTraceState *tcs); @@ -185,6 +189,15 @@ static void lttv_state_free_process_table(GHashTable *processes); static void lttv_trace_states_read_raw(LttvTraceState *tcs, FILE *fp, GPtrArray *quarktable); +/* Resource function prototypes */ +static LttvBdevState *get_hashed_bdevstate(LttvTraceState *ts, guint16 devcode); +static LttvBdevState *bdevstate_new(void); +static void bdevstate_free(LttvBdevState *); +static void bdevstate_free_cb(gpointer key, gpointer value, gpointer user_data); +static LttvBdevState *bdevstate_copy(LttvBdevState *bds); +static LttvBdevState *bdev_state_get(LttvTraceState *ts, guint16 devcode); + + void lttv_state_save(LttvTraceState *self, LttvAttribute *container) { LTTV_TRACE_STATE_GET_CLASS(self)->state_save(self, container); @@ -294,10 +307,15 @@ restore_init_state(LttvTraceState *self) g_array_remove_range(self->cpu_states[i].mode_stack, 0, self->cpu_states[i].mode_stack->len); } + /* reset irq states */ for(i=0; iirq_states[i].mode_stack->len > 0) g_array_remove_range(self->irq_states[i].mode_stack, 0, self->irq_states[i].mode_stack->len); } + + /* reset bdev states */ + g_hash_table_foreach(self->bdev_states, bdevstate_free_cb, NULL); + g_hash_table_steal_all(self->bdev_states); #if 0 nb_tracefile = self->parent.tracefiles->len; @@ -1173,6 +1191,89 @@ static void lttv_state_free_irq_states(LttvIRQState *states, guint n) g_free(states); } +/* bdevstate stuff */ + +static LttvBdevState *get_hashed_bdevstate(LttvTraceState *ts, guint16 devcode) +{ + gint devcode_gint = devcode; + gpointer bdev = g_hash_table_lookup(ts->bdev_states, &devcode_gint); + if(bdev == NULL) { + LttvBdevState *bdevstate = g_malloc(sizeof(LttvBdevState)); + bdevstate->mode_stack = g_array_new(FALSE, FALSE, sizeof(GQuark)); + + gint * key = g_malloc(sizeof(gint)); + *key = devcode; + g_hash_table_insert(ts->bdev_states, key, bdevstate); + + bdev = bdevstate; + } + + return bdev; +} + +static LttvBdevState *bdevstate_new(void) +{ + LttvBdevState *retval; + retval = g_malloc(sizeof(LttvBdevState)); + retval->mode_stack = g_array_new(FALSE, FALSE, sizeof(GQuark)); + + return retval; +} + +static void bdevstate_free(LttvBdevState *bds) +{ + g_array_free(bds->mode_stack, FALSE); + g_free(bds); +} + +static void bdevstate_free_cb(gpointer key, gpointer value, gpointer user_data) +{ + LttvBdevState *bds = (LttvBdevState *) value; + + bdevstate_free(bds); +} + +static LttvBdevState *bdevstate_copy(LttvBdevState *bds) +{ + LttvBdevState *retval; + + retval = bdevstate_new(); + g_array_insert_vals(retval->mode_stack, 0, bds->mode_stack->data, bds->mode_stack->len); + + return retval; +} + +static void insert_and_copy_bdev_state(gpointer k, gpointer v, gpointer u) +{ + GHashTable *ht = (GHashTable *)u; + LttvBdevState *bds = (LttvBdevState *)v; + LttvBdevState *newbds; + + newbds = bdevstate_copy(v); + + g_hash_table_insert(u, k, newbds); +} + +static GHashTable *lttv_state_copy_blkdev_hashtable(GHashTable *ht) +{ + GHashTable *retval; + + retval = g_hash_table_new(g_int_hash, g_int_equal); + + g_hash_table_foreach(ht, insert_and_copy_bdev_state, retval); + + return retval; +} + +/* Free a hashtable and the LttvBdevState structures its values + * point to. */ + +static void lttv_state_free_blkdev_hashtable(GHashTable *ht) +{ + g_hash_table_foreach(ht, bdevstate_free_cb, NULL); + g_hash_table_destroy(ht); +} + /* The saved state for each trace contains a member "processes", which stores a copy of the process table, and a member "tracefiles" with one entry per tracefile. Each tracefile has a "process" member pointing @@ -1270,6 +1371,11 @@ static void state_save(LttvTraceState *self, LttvAttribute *container) LTTV_POINTER); *(value.v_pointer) = lttv_state_copy_irq_states(self->irq_states, nb_irqs); } + + /* save the blkdev states */ + value = lttv_attribute_add(container, LTTV_STATE_RESOURCE_BLKDEVS, + LTTV_POINTER); + *(value.v_pointer) = lttv_state_copy_blkdev_hashtable(self->bdev_states); } @@ -1334,6 +1440,12 @@ static void state_restore(LttvTraceState *self, LttvAttribute *container) lttv_state_free_irq_states(self->irq_states, nb_irqs); self->irq_states = lttv_state_copy_irq_states(*(value.v_pointer), nb_irqs); + /* restore the blkdev states */ + type = lttv_attribute_get_by_name(container, LTTV_STATE_RESOURCE_BLKDEVS, &value); + g_assert(type == LTTV_POINTER); + lttv_state_free_blkdev_hashtable(self->bdev_states); + self->bdev_states = lttv_state_copy_blkdev_hashtable(*(value.v_pointer)); + for(i = 0 ; i < nb_tracefile ; i++) { tfcs = LTTV_TRACEFILE_STATE(g_array_index(self->parent.tracefiles, @@ -2259,25 +2371,24 @@ static gboolean soft_irq_entry(void *hook_data, void *call_data) return FALSE; } -LttvBdevState *bdev_state_get(LttvTraceState *ts, guint16 devcode) +static gboolean enum_interrupt(void *hook_data, void *call_data) { - gint devcode_gint = devcode; - gpointer bdev = g_hash_table_lookup(ts->bdev_states, &devcode_gint); - if(bdev == NULL) { - LttvBdevState *bdevstate = g_malloc(sizeof(LttvBdevState)); - bdevstate->mode_stack = g_array_new(FALSE, FALSE, sizeof(GQuark)); + 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); + LttvTraceHookByFacility *thf = (LttvTraceHookByFacility *)hook_data; - gint * key = g_malloc(sizeof(gint)); - *key = devcode; - g_hash_table_insert(ts->bdev_states, key, bdevstate); - printf("adding key %u to hash table\n", *key); + GQuark action = g_quark_from_string(ltt_event_get_string(e, thf->f1)); + guint irq = ltt_event_get_long_unsigned(e, thf->f2); - bdev = bdevstate; - } + ts->irq_names[irq] = action; - return bdev; + return FALSE; } + static gboolean bdev_request_issue(void *hook_data, void *call_data) { LttvTracefileState *s = (LttvTracefileState *)call_data; @@ -2293,7 +2404,7 @@ static gboolean bdev_request_issue(void *hook_data, void *call_data) guint16 devcode = MKDEV(major,minor); /* have we seen this block device before? */ - gpointer bdev = bdev_state_get(ts, devcode); + gpointer bdev = get_hashed_bdevstate(ts, devcode); if(oper == 0) bdev_push_mode(bdev, LTTV_BDEV_BUSY_READING); @@ -2316,7 +2427,7 @@ static gboolean bdev_request_complete(void *hook_data, void *call_data) guint16 devcode = MKDEV(major,minor); /* have we seen this block device before? */ - gpointer bdev = bdev_state_get(ts, devcode); + gpointer bdev = get_hashed_bdevstate(ts, devcode); /* update block device */ bdev_pop_mode(bdev); @@ -3083,6 +3194,12 @@ void lttv_state_add_event_hooks(LttvTracesetState *self) statedump_end, NULL, &g_array_index(hooks, LttvTraceHook, hn++)); if(ret) hn--; + ret = lttv_trace_find_hook(ts->parent.t, + LTT_FACILITY_LIST, LTT_EVENT_LIST_INTERRUPT, + LTT_FIELD_ACTION, LTT_FIELD_NUM, 0, + enum_interrupt, NULL, &g_array_index(hooks, LttvTraceHook, hn++)); + if(ret) hn--; + ret = lttv_trace_find_hook(ts->parent.t, LTT_FACILITY_BLOCK, LTT_EVENT_REQUEST_ISSUE, LTT_FIELD_MAJOR, LTT_FIELD_MINOR, LTT_FIELD_OPERATION, @@ -3777,6 +3894,8 @@ static void module_init() LTTV_STATE_TRACE_STATE_USE_COUNT = g_quark_from_string("trace_state_use_count"); LTTV_STATE_RESOURCE_CPUS = g_quark_from_string("cpu resource states"); + LTTV_STATE_RESOURCE_IRQS = g_quark_from_string("irq resource states"); + LTTV_STATE_RESOURCE_BLKDEVS = g_quark_from_string("blkdevs resource states"); LTT_FACILITY_KERNEL = g_quark_from_string("kernel"); @@ -3808,6 +3927,7 @@ static void module_init() LTT_EVENT_THREAD_BRAND = g_quark_from_string("thread_brand"); LTT_EVENT_REQUEST_ISSUE = g_quark_from_string("_blk_request_issue"); LTT_EVENT_REQUEST_COMPLETE = g_quark_from_string("_blk_request_complete"); + LTT_EVENT_LIST_INTERRUPT = g_quark_from_string("interrupt");; LTT_FIELD_SYSCALL_ID = g_quark_from_string("syscall_id"); @@ -3833,6 +3953,8 @@ static void module_init() LTT_FIELD_MAJOR = g_quark_from_string("major"); LTT_FIELD_MINOR = g_quark_from_string("minor"); LTT_FIELD_OPERATION = g_quark_from_string("direction"); + LTT_FIELD_ACTION = g_quark_from_string("action"); + LTT_FIELD_NUM = g_quark_from_string("num"); LTTV_CPU_UNKNOWN = g_quark_from_string("unknown"); LTTV_CPU_IDLE = g_quark_from_string("idle");