X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=ltt%2Fbranches%2Fpoly%2Flttv%2Fmodules%2Fgui%2Fresourceview%2Fprocesslist.c;h=03c838254a4845dc770f2e1aa6a98fe0068a60bf;hb=27274b95df69ef3f24710e928f1b8873e2e7571b;hp=3495202cc735d68de9165aba8e3e3ba4dcd12f44;hpb=67f729732d629426de5a04965a81f6f0848af053;p=lttv.git diff --git a/ltt/branches/poly/lttv/modules/gui/resourceview/processlist.c b/ltt/branches/poly/lttv/modules/gui/resourceview/processlist.c index 3495202c..03c83825 100644 --- a/ltt/branches/poly/lttv/modules/gui/resourceview/processlist.c +++ b/ltt/branches/poly/lttv/modules/gui/resourceview/processlist.c @@ -59,7 +59,7 @@ gint resource_sort_func ( GtkTreeModel *model, static guint ru_numeric_hash_fct(gconstpointer key) { - ResourceUniqueNumeric *ru = (const ResourceUniqueNumeric *)key; + ResourceUniqueNumeric *ru = (ResourceUniqueNumeric *)key; int tmp = (ru->trace_num << 8) ^ ru->id; return g_int_hash(&tmp); @@ -106,6 +106,77 @@ gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event, gpointer data) return TRUE; } +void expand_event(GtkTreeView *treeview, GtkTreeIter *iter, GtkTreePath *arg2, gpointer user_data) +{ + ControlFlowData *resourceview_data = + (ControlFlowData*)g_object_get_data( + G_OBJECT(treeview), + "resourceview_data"); + ProcessList *process_list = (ProcessList *) user_data; + ResourceUnique *rup; + HashedResourceData *hrd; + gboolean result; + + GtkTreeModel *model; + GtkTreeIter child; + + /* Determine which trace has been expanded */ + model = gtk_tree_view_get_model(treeview); + + /* mark each of the trace's resources invisible */ + result = gtk_tree_model_iter_children(model, &child, iter); + + /* for each child of the collapsed row */ + while(result) { + /* hide the item */ + gtk_tree_model_get(model, &child, DATA_COLUMN, &hrd, -1); + hrd->hidden=0; + + /* find next */ + result = gtk_tree_model_iter_next(model, &child); + } + + update_index_to_pixmap(process_list); + + gtk_widget_queue_draw(resourceview_data->drawing->drawing_area); +} + +void collapse_event(GtkTreeView *treeview, GtkTreeIter *iter, GtkTreePath *arg2, gpointer user_data) +{ + ControlFlowData *resourceview_data = + (ControlFlowData*)g_object_get_data( + G_OBJECT(treeview), + "resourceview_data"); + ProcessList *process_list = (ProcessList *) user_data; + ResourceUnique *rup; + HashedResourceData *hrd; + gboolean result; + + GtkTreeModel *model; + GtkTreeIter child; + + /* Determine which trace has been expanded */ + model = gtk_tree_view_get_model(treeview); + + /* mark each of the trace's resources invisible */ + result = gtk_tree_model_iter_children(model, &child, iter); + + /* for each child of the collapsed row */ + while(result) { + char *name; + /* hide the item */ + gtk_tree_model_get(model, &child, NAME_COLUMN, &name, DATA_COLUMN, &hrd, -1); + hrd->hidden=1; + + /* find next */ + result = gtk_tree_model_iter_next(model, &child); + } + + update_index_to_pixmap(process_list); + + gtk_widget_queue_draw(resourceview_data->drawing->drawing_area); +} + static gboolean update_index_to_pixmap_each (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, UpdateIndexPixmapArg *arg) { guint array_index = arg->count; @@ -116,11 +187,13 @@ static gboolean update_index_to_pixmap_each (GtkTreeModel *model, GtkTreePath *p g_assert(array_index < arg->process_list->index_to_pixmap->len); - GdkPixmap **pixmap = - (GdkPixmap**)&g_ptr_array_index(arg->process_list->index_to_pixmap, array_index); - *pixmap = hdata->pixmap; + if(hdata->hidden == 0) { + GdkPixmap **pixmap = + (GdkPixmap**)&g_ptr_array_index(arg->process_list->index_to_pixmap, array_index); + *pixmap = hdata->pixmap; - arg->count++; + arg->count++; + } return FALSE; } @@ -134,13 +207,18 @@ void update_index_to_pixmap(ProcessList *process_list) items += g_hash_table_size(process_list->restypes[i].hash_table); } + /* we don't know the exact number of items there will be, + * so set an upper bound */ g_ptr_array_set_size(process_list->index_to_pixmap, items); arg.count = 0; arg.process_list = process_list; - gtk_tree_model_foreach(process_list->list_store, + gtk_tree_model_foreach(GTK_TREE_MODEL(process_list->list_store), (GtkTreeModelForeachFunc)update_index_to_pixmap_each, &arg); + + /* now that we know the exact number of items, set it */ + g_ptr_array_set_size(process_list->index_to_pixmap, arg.count); } @@ -334,6 +412,9 @@ ProcessList *processlist_construct(void) NULL, NULL, &process_list->cell_height); + + g_signal_connect(process_list->process_list_widget, "row-expanded", G_CALLBACK(expand_event), process_list); + g_signal_connect(process_list->process_list_widget, "row-collapsed", G_CALLBACK(collapse_event), process_list); #if GTK_CHECK_VERSION(2,4,15) guint ypad; @@ -367,6 +448,8 @@ ProcessList *processlist_construct(void) process_list->restypes[RV_RESOURCE_MACHINE].hash_table = g_hash_table_new(ru_numeric_hash_fct, ru_numeric_equ_fct); process_list->restypes[RV_RESOURCE_CPU].hash_table = g_hash_table_new(ru_numeric_hash_fct, ru_numeric_equ_fct); process_list->restypes[RV_RESOURCE_IRQ].hash_table = g_hash_table_new(ru_numeric_hash_fct, ru_numeric_equ_fct); + process_list->restypes[RV_RESOURCE_SOFT_IRQ].hash_table = g_hash_table_new(ru_numeric_hash_fct, ru_numeric_equ_fct); + process_list->restypes[RV_RESOURCE_TRAP].hash_table = g_hash_table_new(ru_numeric_hash_fct, ru_numeric_equ_fct); process_list->restypes[RV_RESOURCE_BDEV].hash_table = g_hash_table_new(ru_numeric_hash_fct, ru_numeric_equ_fct); return process_list; @@ -440,86 +523,67 @@ void destroy_hash_data(gpointer data) g_free(data); } -HashedResourceData *resourcelist_obtain_machine(ControlFlowData *resourceview_data, guint trace_num, guint id) +GQuark make_cpu_name(ControlFlowData *resourceview_data, guint trace_num, guint id) { - ResourceUniqueNumeric *ru = g_new(ResourceUniqueNumeric, 1); - HashedResourceData *data = g_new(HashedResourceData, 1); - - /* Prepare hash key */ - ru->trace_num = trace_num; - ru->id = id; - - /* Search within hash table */ - GHashTable *ht = resourceview_data->process_list->restypes[RV_RESOURCE_MACHINE].hash_table; - data = g_hash_table_lookup(ht, ru); - - /* If not found in hash table, add it */ - if(data == NULL) { - GQuark name; + GQuark name; + gchar *str; - data = g_malloc(sizeof(HashedResourceData)); - /* Prepare hashed data */ - data->type = RV_RESOURCE_MACHINE; - data->x.over = 0; - data->x.over_used = FALSE; - data->x.over_marked = FALSE; - data->x.middle = 0; // last - data->x.middle_used = FALSE; - data->x.middle_marked = FALSE; - data->x.under = 0; - data->x.under_used = FALSE; - data->x.under_marked = FALSE; - data->next_good_time = ltt_time_zero; + str = g_strdup_printf("CPU%u", id); + name = g_quark_from_string(str); + g_free(str); - data->height = resourceview_data->process_list->cell_height; - data->pixmap = - gdk_pixmap_new(resourceview_data->drawing->drawing_area->window, - resourceview_data->drawing->alloc_width, - data->height, - -1); - g_assert(data->pixmap); + return name; +} - gdk_draw_rectangle (data->pixmap, - resourceview_data->drawing->drawing_area->style->black_gc, - TRUE, - 0, 0, - resourceview_data->drawing->alloc_width, - data->height); +GQuark make_irq_name(ControlFlowData *resourceview_data, guint trace_num, guint id) +{ + GQuark name; + gchar *str; - /* add to hash table */ - g_hash_table_insert(ht, ru, data); - resourceview_data->process_list->number_of_process++; // TODO: check + str = g_strdup_printf("IRQ %u", id); + name = g_quark_from_string(str); + g_free(str); - /* add to process list */ - { - gchar *str; - str = g_strdup_printf("Trace %u", id); - name = g_quark_from_string(str); - g_free(str); - } + return name; +} - gtk_tree_store_append(resourceview_data->process_list->list_store, &data->y_iter, NULL); - gtk_tree_store_set(resourceview_data->process_list->list_store, &data->y_iter, - NAME_COLUMN, g_quark_to_string(name), DATA_COLUMN, data, - -1); +GQuark make_soft_irq_name(ControlFlowData *resourceview_data, guint trace_num, guint id) +{ + GQuark name; + gchar *str; - update_index_to_pixmap(resourceview_data->process_list); + str = g_strdup_printf("SOFTIRQ %u", id); + name = g_quark_from_string(str); + g_free(str); - int heightall = data->height * resourceview_data->process_list->number_of_process; + return name; +} - gtk_widget_set_size_request(resourceview_data->drawing->drawing_area, - -1, - heightall); +GQuark make_trap_name(ControlFlowData *resourceview_data, guint trace_num, guint id) +{ + GQuark name; + gchar *str; - gtk_widget_queue_draw(resourceview_data->drawing->drawing_area); - } + str = g_strdup_printf("Trap %u", id); + name = g_quark_from_string(str); + g_free(str); - gtk_tree_view_expand_all(resourceview_data->process_list->process_list_widget); + return name; +} - return data; +GQuark make_bdev_name(ControlFlowData *resourceview_data, guint trace_num, guint id) +{ + GQuark name; + gchar *str; + + str = g_strdup_printf("Block (%u,%u)", MAJOR(id), MINOR(id)); + name = g_quark_from_string(str); + g_free(str); + + return name; } -HashedResourceData *resourcelist_obtain_cpu(ControlFlowData *resourceview_data, guint trace_num, guint id) +HashedResourceData *resourcelist_obtain_machine(ControlFlowData *resourceview_data, guint trace_num, guint id) { ResourceUniqueNumeric *ru = g_new(ResourceUniqueNumeric, 1); HashedResourceData *data = g_new(HashedResourceData, 1); @@ -529,21 +593,16 @@ HashedResourceData *resourcelist_obtain_cpu(ControlFlowData *resourceview_data, ru->id = id; /* Search within hash table */ - GHashTable *ht = resourceview_data->process_list->restypes[RV_RESOURCE_CPU].hash_table; + GHashTable *ht = resourceview_data->process_list->restypes[RV_RESOURCE_MACHINE].hash_table; data = g_hash_table_lookup(ht, ru); /* If not found in hash table, add it */ if(data == NULL) { GQuark name; - HashedResourceData *parent; - /* Find the parent machine */ - parent = resourcelist_obtain_machine(resourceview_data, trace_num, trace_num); - - /* Prepare hashed data */ data = g_malloc(sizeof(HashedResourceData)); - - data->type = RV_RESOURCE_CPU; + /* Prepare hashed data */ + data->type = RV_RESOURCE_MACHINE; data->x.over = 0; data->x.over_used = FALSE; data->x.over_marked = FALSE; @@ -554,6 +613,7 @@ HashedResourceData *resourcelist_obtain_cpu(ControlFlowData *resourceview_data, data->x.under_used = FALSE; data->x.under_marked = FALSE; data->next_good_time = ltt_time_zero; + data->hidden = 0; data->height = resourceview_data->process_list->cell_height; data->pixmap = @@ -561,6 +621,7 @@ HashedResourceData *resourcelist_obtain_cpu(ControlFlowData *resourceview_data, resourceview_data->drawing->alloc_width, data->height, -1); + g_assert(data->pixmap); gdk_draw_rectangle (data->pixmap, resourceview_data->drawing->drawing_area->style->black_gc, @@ -576,12 +637,12 @@ HashedResourceData *resourcelist_obtain_cpu(ControlFlowData *resourceview_data, /* add to process list */ { gchar *str; - str = g_strdup_printf("CPU%u", id); + str = g_strdup_printf("Trace %u", id); name = g_quark_from_string(str); g_free(str); } - gtk_tree_store_append(resourceview_data->process_list->list_store, &data->y_iter, &parent->y_iter); + gtk_tree_store_append(resourceview_data->process_list->list_store, &data->y_iter, NULL); gtk_tree_store_set(resourceview_data->process_list->list_store, &data->y_iter, NAME_COLUMN, g_quark_to_string(name), DATA_COLUMN, data, -1); @@ -597,20 +658,32 @@ HashedResourceData *resourcelist_obtain_cpu(ControlFlowData *resourceview_data, gtk_widget_queue_draw(resourceview_data->drawing->drawing_area); } + /* expand the newly added machine */ + { + GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(resourceview_data->process_list->process_list_widget)); + GtkTreePath *path; + path = gtk_tree_model_get_path(model, &data->y_iter); + + gtk_tree_view_expand_row(GTK_TREE_VIEW(resourceview_data->process_list->process_list_widget), path, FALSE); + + gtk_tree_path_free(path); + } + return data; } -HashedResourceData *resourcelist_obtain_irq(ControlFlowData *resourceview_data, guint trace_num, guint id) +HashedResourceData *resourcelist_obtain_generic(ControlFlowData *resourceview_data, gint res_type, guint trace_num, guint id, GQuark (*make_name_func)(ControlFlowData *resourceview_data, guint trace_num, guint id)) { ResourceUniqueNumeric *ru = g_new(ResourceUniqueNumeric, 1); HashedResourceData *data = g_new(HashedResourceData, 1); /* Prepare hash key */ + ru->ru.type = &(resourceview_data->process_list->restypes[res_type]); ru->trace_num = trace_num; ru->id = id; /* Search within hash table */ - GHashTable *ht = resourceview_data->process_list->restypes[RV_RESOURCE_IRQ].hash_table; + GHashTable *ht = resourceview_data->process_list->restypes[res_type].hash_table; data = g_hash_table_lookup(ht, ru); /* If not found in hash table, add it */ @@ -624,7 +697,7 @@ HashedResourceData *resourcelist_obtain_irq(ControlFlowData *resourceview_data, /* Prepare hashed data */ data = g_malloc(sizeof(HashedResourceData)); - data->type = RV_RESOURCE_IRQ; + data->type = res_type; data->x.over = 0; data->x.over_used = FALSE; data->x.over_marked = FALSE; @@ -655,18 +728,26 @@ HashedResourceData *resourcelist_obtain_irq(ControlFlowData *resourceview_data, resourceview_data->process_list->number_of_process++; // TODO: check /* add to process list */ - { - gchar *str; - str = g_strdup_printf("IRQ %u", id); - name = g_quark_from_string(str); - g_free(str); - } + name = make_name_func(resourceview_data, trace_num, id); gtk_tree_store_append(resourceview_data->process_list->list_store, &data->y_iter, &parent->y_iter); gtk_tree_store_set(resourceview_data->process_list->list_store, &data->y_iter, NAME_COLUMN, g_quark_to_string(name), DATA_COLUMN, data, -1); + /* Determine if we should add it hidden or not */ + { + gboolean result; + GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(resourceview_data->process_list->process_list_widget)); + GtkTreeIter parent_iter; + + result = gtk_tree_model_iter_parent(model, &parent_iter, &data->y_iter); + GtkTreePath *path = gtk_tree_model_get_path(model, &parent_iter); + data->hidden = gtk_tree_view_row_expanded(GTK_TREE_VIEW(resourceview_data->process_list->process_list_widget), path)?0:1; + gtk_tree_path_free(path); + } + + update_index_to_pixmap(resourceview_data->process_list); int heightall = data->height * resourceview_data->process_list->number_of_process; @@ -681,83 +762,28 @@ HashedResourceData *resourcelist_obtain_irq(ControlFlowData *resourceview_data, return data; } -HashedResourceData *resourcelist_obtain_bdev(ControlFlowData *resourceview_data, guint trace_num, guint id) +HashedResourceData *resourcelist_obtain_cpu(ControlFlowData *resourceview_data, guint trace_num, guint id) { - ResourceUniqueNumeric *ru = g_new(ResourceUniqueNumeric, 1); - HashedResourceData *data = g_new(HashedResourceData, 1); - - /* Prepare hash key */ - ru->trace_num = trace_num; - ru->id = id; - - /* Search within hash table */ - GHashTable *ht = resourceview_data->process_list->restypes[RV_RESOURCE_BDEV].hash_table; - data = g_hash_table_lookup(ht, ru); - - /* If not found in hash table, add it */ - if(data == NULL) { - GQuark name; - HashedResourceData *parent; - - /* Find the parent machine */ - parent = resourcelist_obtain_machine(resourceview_data, trace_num, trace_num); - - /* Prepare hashed data */ - data = g_malloc(sizeof(HashedResourceData)); - - data->type = RV_RESOURCE_BDEV; - data->x.over = 0; - data->x.over_used = FALSE; - data->x.over_marked = FALSE; - data->x.middle = 0; // last - data->x.middle_used = FALSE; - data->x.middle_marked = FALSE; - data->x.under = 0; - data->x.under_used = FALSE; - data->x.under_marked = FALSE; - data->next_good_time = ltt_time_zero; - - data->height = resourceview_data->process_list->cell_height; - data->pixmap = - gdk_pixmap_new(resourceview_data->drawing->drawing_area->window, - resourceview_data->drawing->alloc_width, - data->height, - -1); - - gdk_draw_rectangle (data->pixmap, - resourceview_data->drawing->drawing_area->style->black_gc, - TRUE, - 0, 0, - resourceview_data->drawing->alloc_width, - data->height); - - /* add to hash table */ - g_hash_table_insert(ht, ru, data); - resourceview_data->process_list->number_of_process++; // TODO: check - - /* add to process list */ - { - gchar *str; - str = g_strdup_printf("Block (%u,%u)", MAJOR(id), MINOR(id)); - name = g_quark_from_string(str); - g_free(str); - } - - gtk_tree_store_append(resourceview_data->process_list->list_store, &data->y_iter, &parent->y_iter); - gtk_tree_store_set(resourceview_data->process_list->list_store, &data->y_iter, - NAME_COLUMN, g_quark_to_string(name), DATA_COLUMN, data, - -1); - - update_index_to_pixmap(resourceview_data->process_list); + return resourcelist_obtain_generic(resourceview_data, RV_RESOURCE_CPU, trace_num, id, make_cpu_name); +} - int heightall = data->height * resourceview_data->process_list->number_of_process; +HashedResourceData *resourcelist_obtain_irq(ControlFlowData *resourceview_data, guint trace_num, guint id) +{ + return resourcelist_obtain_generic(resourceview_data, RV_RESOURCE_IRQ, trace_num, id, make_irq_name); +} - gtk_widget_set_size_request(resourceview_data->drawing->drawing_area, - -1, - heightall); +HashedResourceData *resourcelist_obtain_soft_irq(ControlFlowData *resourceview_data, guint trace_num, guint id) +{ + return resourcelist_obtain_generic(resourceview_data, RV_RESOURCE_SOFT_IRQ, trace_num, id, make_soft_irq_name); +} - gtk_widget_queue_draw(resourceview_data->drawing->drawing_area); - } +HashedResourceData *resourcelist_obtain_trap(ControlFlowData *resourceview_data, guint trace_num, guint id) +{ + return resourcelist_obtain_generic(resourceview_data, RV_RESOURCE_TRAP, trace_num, id, make_trap_name); +} - return data; +HashedResourceData *resourcelist_obtain_bdev(ControlFlowData *resourceview_data, guint trace_num, guint id) +{ + return resourcelist_obtain_generic(resourceview_data, RV_RESOURCE_BDEV, trace_num, id, make_bdev_name); } +