X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=ltt%2Fbranches%2Fpoly%2Flttv%2Flttv%2Fstate.c;h=4858b21669c0ce556eaa4168d8883464957c24c5;hb=521a0efa430162f3b78b5cd569e730ed4c60bfc6;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..4858b216 100644 --- a/ltt/branches/poly/lttv/lttv/state.c +++ b/ltt/branches/poly/lttv/lttv/state.c @@ -164,7 +164,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 +186,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 +304,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 +1188,85 @@ 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)); +} + +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); +} + +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 +1364,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 +1433,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 +2364,6 @@ static gboolean soft_irq_entry(void *hook_data, void *call_data) return FALSE; } -LttvBdevState *bdev_state_get(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); - printf("adding key %u to hash table\n", *key); - - bdev = bdevstate; - } - - return bdev; -} - static gboolean bdev_request_issue(void *hook_data, void *call_data) { LttvTracefileState *s = (LttvTracefileState *)call_data; @@ -2293,7 +2379,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 +2402,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); @@ -3777,6 +3863,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");