X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=ltt%2Fbranches%2Fpoly%2Flttv%2Fmodules%2Fgui%2Fcontrolflow%2Fprocesslist.c;h=6a8bcd44c8b917aea485bf59917994ceb958e8df;hb=cc09b7022bec85321a29446943bbf3304a3a4192;hp=0a29dfe1e9fa2109590d29ccfb96192d9a26996d;hpb=54d8f654b0f1e1301f4e8a2bdc600bc370fff6f9;p=lttv.git diff --git a/ltt/branches/poly/lttv/modules/gui/controlflow/processlist.c b/ltt/branches/poly/lttv/modules/gui/controlflow/processlist.c index 0a29dfe1..6a8bcd44 100644 --- a/ltt/branches/poly/lttv/modules/gui/controlflow/processlist.c +++ b/ltt/branches/poly/lttv/modules/gui/controlflow/processlist.c @@ -20,19 +20,23 @@ #include #include #include +#include #include "processlist.h" +#include "drawing.h" #include "drawitem.h" #define g_info(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format) #define g_debug(format...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format) +/* Preallocated Size of the index_to_pixmap array */ +#define ALLOCATE_PROCESSES 1000 /***************************************************************************** * Methods to synchronize process list * *****************************************************************************/ -static __inline guint get_cpu_number_from_name(GQuark name); +//static inline guint get_cpu_number_from_name(GQuark name); /* Enumeration of the columns */ enum @@ -233,37 +237,203 @@ gint process_sort_func ( GtkTreeModel *model, } -static guint hash_fct(gconstpointer key) +static guint process_list_hash_fct(gconstpointer key) { - return ((ProcessInfo*)key)->pid; + guint pid = ((const ProcessInfo*)key)->pid; + return ((pid>>8 ^ pid>>4 ^ pid>>2 ^ pid) ^ ((const ProcessInfo*)key)->cpu); } -static gboolean equ_fct(gconstpointer a, gconstpointer b) +/* If hash is good, should be different */ +static gboolean process_list_equ_fct(gconstpointer a, gconstpointer b) { const ProcessInfo *pa = (const ProcessInfo*)a; const ProcessInfo *pb = (const ProcessInfo*)b; + + gboolean ret = TRUE; + + if(likely(pa->pid != pb->pid)) + ret = FALSE; + else if(likely((pa->pid == 0 && (pa->cpu != pb->cpu)))) + ret = FALSE; + else if(unlikely(ltt_time_compare(pa->birth, pb->birth) != 0)) + ret = FALSE; + else if(unlikely(pa->trace_num != pb->trace_num)) + ret = FALSE; + + return ret; +} - if(pa->pid != pb->pid) - return 0; +void destroy_hash_key(gpointer key); - if((pa->pid == 0 && (pa->cpu != pb->cpu))) - return 0; +void destroy_hash_data(gpointer data); - if(pa->birth.tv_sec != pb->birth.tv_sec) - return 0; - if(pa->birth.tv_nsec != pb->birth.tv_nsec) - return 0; +static void update_index_to_pixmap_each(ProcessInfo *key, + HashedProcessData *value, + ProcessList *process_list) +{ + guint array_index = processlist_get_index_from_data(process_list, value); + + g_assert(array_index < process_list->index_to_pixmap->len); - if(pa->trace_num != pb->trace_num) - return 0; + GdkPixmap **pixmap = + (GdkPixmap**)&g_ptr_array_index(process_list->index_to_pixmap, array_index); - return 1; + *pixmap = value->pixmap; } -void destroy_hash_key(gpointer key); -void destroy_hash_data(gpointer data); +static void update_index_to_pixmap(ProcessList *process_list) +{ + g_ptr_array_set_size(process_list->index_to_pixmap, + g_hash_table_size(process_list->process_hash)); + g_hash_table_foreach(process_list->process_hash, + (GHFunc)update_index_to_pixmap_each, + process_list); +} + + +static void update_pixmap_size_each(ProcessInfo *key, + HashedProcessData *value, + guint width) +{ + GdkPixmap *old_pixmap = value->pixmap; + + value->pixmap = + gdk_pixmap_new(old_pixmap, + width, + value->height, + -1); + + gdk_pixmap_unref(old_pixmap); +} + + +void update_pixmap_size(ProcessList *process_list, guint width) +{ + g_hash_table_foreach(process_list->process_hash, + (GHFunc)update_pixmap_size_each, + (gpointer)width); +} + + +typedef struct _CopyPixmap { + GdkDrawable *dest; + GdkGC *gc; + GdkDrawable *src; + gint xsrc, ysrc, xdest, ydest, width, height; +} CopyPixmap; + +static void copy_pixmap_region_each(ProcessInfo *key, + HashedProcessData *value, + CopyPixmap *cp) +{ + GdkPixmap *src = cp->src; + GdkPixmap *dest = cp->dest; + + if(dest == NULL) + dest = value->pixmap; + if(src == NULL) + src = value->pixmap; + + gdk_draw_drawable (dest, + cp->gc, + src, + cp->xsrc, cp->ysrc, + cp->xdest, cp->ydest, + cp->width, cp->height); +} + + + + +void copy_pixmap_region(ProcessList *process_list, GdkDrawable *dest, + GdkGC *gc, GdkDrawable *src, + gint xsrc, gint ysrc, + gint xdest, gint ydest, gint width, gint height) +{ + CopyPixmap cp = { dest, gc, src, xsrc, ysrc, xdest, ydest, width, height }; + + g_hash_table_foreach(process_list->process_hash, + (GHFunc)copy_pixmap_region_each, + &cp); +} + + + +typedef struct _RectanglePixmap { + gboolean filled; + gint x, y, width, height; + GdkGC *gc; +} RectanglePixmap; + +static void rectangle_pixmap_each(ProcessInfo *key, + HashedProcessData *value, + RectanglePixmap *rp) +{ + if(rp->height == -1) + rp->height = value->height; + + gdk_draw_rectangle (value->pixmap, + rp->gc, + rp->filled, + rp->x, rp->y, + rp->width, rp->height); +} + + + + +void rectangle_pixmap(ProcessList *process_list, GdkGC *gc, + gboolean filled, gint x, gint y, gint width, gint height) +{ + RectanglePixmap rp = { filled, x, y, width, height, gc }; + + g_hash_table_foreach(process_list->process_hash, + (GHFunc)rectangle_pixmap_each, + &rp); +} + + +/* Renders each pixmaps into on big drawable */ +void copy_pixmap_to_screen(ProcessList *process_list, + GdkDrawable *dest, + GdkGC *gc, + gint x, gint y, + gint width, gint height) +{ + gint cell_height = + get_cell_height(process_list, + (GtkTreeView*)process_list->process_list_widget); + cell_height = 24; //FIXME + /* Get indexes */ + gint begin = floor(y/(double)cell_height); + gint end = MIN(ceil((y+height)/(double)cell_height), + process_list->index_to_pixmap->len); + gint i; + + for(i=begin; iindex_to_pixmap->len); + /* Render the pixmap to the screen */ + GdkPixmap *pixmap = + (GdkPixmap*)g_ptr_array_index(process_list->index_to_pixmap, i); + + gdk_draw_drawable (dest, + gc, + pixmap, + x, 0, + x, i*cell_height, + width, cell_height); + + } + + +} + + + + + @@ -276,7 +446,8 @@ ProcessList *processlist_construct(void) ProcessList* process_list = g_new(ProcessList,1); process_list->number_of_process = 0; - process_list->cell_height_cache = -1; + + process_list->current_hash_data = NULL; /* Create the Process list */ process_list->list_store = gtk_list_store_new ( N_COLUMNS, @@ -307,7 +478,7 @@ ProcessList *processlist_construct(void) GTK_SORT_ASCENDING); process_list->process_hash = g_hash_table_new_full( - hash_fct, equ_fct, + process_list_hash_fct, process_list_equ_fct, destroy_hash_key, destroy_hash_data ); @@ -390,6 +561,8 @@ ProcessList *processlist_construct(void) process_list, (GDestroyNotify)processlist_destroy); + process_list->index_to_pixmap = g_ptr_array_sized_new(ALLOCATE_PROCESSES); + return process_list; } @@ -398,6 +571,7 @@ void processlist_destroy(ProcessList *process_list) g_debug("processlist_destroy %p", process_list); g_hash_table_destroy(process_list->process_hash); process_list->process_hash = NULL; + g_ptr_array_free(process_list->index_to_pixmap, TRUE); g_free(process_list); g_debug("processlist_destroy end"); @@ -412,7 +586,13 @@ static gboolean remove_hash_item(ProcessInfo *process_info, iter = hashed_process_data->y_iter; gtk_list_store_remove (process_list->list_store, &iter); + gdk_pixmap_unref(hashed_process_data->pixmap); + if(likely(process_list->current_hash_data != NULL)) { + if(likely(hashed_process_data == + process_list->current_hash_data[process_info->cpu])) + process_list->current_hash_data[process_info->cpu] = NULL; + } return TRUE; /* remove the element from the hash table */ } @@ -424,6 +604,7 @@ void processlist_clear(ProcessList *process_list) (GHRFunc)remove_hash_item, (gpointer)process_list); process_list->number_of_process = 0; + update_index_to_pixmap(process_list); } @@ -433,22 +614,6 @@ GtkWidget *processlist_get_widget(ProcessList *process_list) } - -static __inline gint get_cell_height(ProcessList *process_list, GtkTreeView *tree_view) -{ - gint height = process_list->cell_height_cache; - if(height != -1) return height; - else { - GtkTreeViewColumn *Column = gtk_tree_view_get_column(tree_view, 0); - - gtk_tree_view_column_cell_get_size(Column, NULL, NULL, NULL, NULL, - &process_list->cell_height_cache); - } - - - return process_list->cell_height_cache; -} - void destroy_hash_key(gpointer key) { g_free(key); @@ -460,6 +625,7 @@ void destroy_hash_data(gpointer data) } int processlist_add( ProcessList *process_list, + Drawing_t *drawing, guint pid, guint cpu, guint ppid, @@ -467,11 +633,13 @@ int processlist_add( ProcessList *process_list, guint trace_num, const gchar *name, guint *height, + ProcessInfo **pm_process_info, HashedProcessData **pm_hashed_process_data) { ProcessInfo *Process_Info = g_new(ProcessInfo, 1); HashedProcessData *hashed_process_data = g_new(HashedProcessData, 1); *pm_hashed_process_data = hashed_process_data; + *pm_process_info = Process_Info; Process_Info->pid = pid; if(pid == 0) @@ -489,9 +657,16 @@ int processlist_add( ProcessList *process_list, * overriden by the new state before anything is drawn. */ hashed_process_data->x.over = 0; + hashed_process_data->x.over_used = FALSE; + hashed_process_data->x.over_marked = FALSE; hashed_process_data->x.middle = 0; + hashed_process_data->x.middle_used = FALSE; + hashed_process_data->x.middle_marked = FALSE; hashed_process_data->x.under = 0; - + hashed_process_data->x.under_used = FALSE; + hashed_process_data->x.under_marked = FALSE; + hashed_process_data->next_good_time = ltt_time_zero; + /* Add a new row to the model */ gtk_list_store_append ( process_list->list_store, &hashed_process_data->y_iter); @@ -500,32 +675,42 @@ int processlist_add( ProcessList *process_list, PROCESS_COLUMN, name, PID_COLUMN, pid, PPID_COLUMN, ppid, - CPU_COLUMN, get_cpu_number_from_name(cpu), + CPU_COLUMN, cpu, BIRTH_S_COLUMN, birth->tv_sec, BIRTH_NS_COLUMN, birth->tv_nsec, TRACE_COLUMN, trace_num, -1); -#if 0 - hashed_process_data->row_ref = gtk_tree_row_reference_new ( - GTK_TREE_MODEL(process_list->list_store), - gtk_tree_model_get_path( - GTK_TREE_MODEL(process_list->list_store), - &iter)); -#endif //0 + g_hash_table_insert(process_list->process_hash, (gpointer)Process_Info, (gpointer)hashed_process_data); - //g_critical ( "iter after : %s", gtk_tree_path_to_string ( - // gtk_tree_model_get_path ( - // GTK_TREE_MODEL(process_list->list_store), - // &iter))); process_list->number_of_process++; - *height = get_cell_height(process_list, - GTK_TREE_VIEW(process_list->process_list_widget)) - * process_list->number_of_process ; + hashed_process_data->height = get_cell_height(process_list, + (GtkTreeView*)process_list->process_list_widget); + hashed_process_data->height = 24; // FIXME + g_assert(hashed_process_data->height != 0); + + *height = hashed_process_data->height * process_list->number_of_process; + + hashed_process_data->pixmap = + gdk_pixmap_new(drawing->drawing_area->window, + drawing->alloc_width, + hashed_process_data->height, + -1); + // Clear the image + gdk_draw_rectangle (hashed_process_data->pixmap, + drawing->drawing_area->style->black_gc, + TRUE, + 0, 0, + drawing->alloc_width, + hashed_process_data->height); + + update_index_to_pixmap(process_list); + + return 0; } @@ -535,110 +720,53 @@ int processlist_remove( ProcessList *process_list, LttTime *birth, guint trace_num) { - ProcessInfo Process_Info; - gint *path_indices; + ProcessInfo process_info; HashedProcessData *hashed_process_data; GtkTreeIter iter; - Process_Info.pid = pid; - Process_Info.cpu = cpu; - Process_Info.birth = *birth; - Process_Info.trace_num = trace_num; + process_info.pid = pid; + if(pid == 0) + process_info.cpu = cpu; + else + process_info.cpu = 0; + process_info.birth = *birth; + process_info.trace_num = trace_num; - if(hashed_process_data = + hashed_process_data = (HashedProcessData*)g_hash_table_lookup( process_list->process_hash, - &Process_Info)) + &process_info); + if(likely(hashed_process_data != NULL)) { iter = hashed_process_data->y_iter; gtk_list_store_remove (process_list->list_store, &iter); g_hash_table_remove(process_list->process_hash, - &Process_Info); - - process_list->number_of_process--; - - return 0; - } else { - return 1; - } -} - - -guint processlist_get_height(ProcessList *process_list) -{ - return get_cell_height(process_list, - GTK_TREE_VIEW(process_list->process_list_widget)) - * process_list->number_of_process ; -} - + &process_info); -__inline gint processlist_get_process_pixels( ProcessList *process_list, - guint pid, guint cpu, LttTime *birth, guint trace_num, - guint *y, - guint *height, - HashedProcessData **pm_hashed_process_data) -{ - ProcessInfo Process_Info; - gint *path_indices; - GtkTreePath *tree_path; - HashedProcessData *hashed_process_data = NULL; + if(likely(process_list->current_hash_data != NULL)) { + if(likely(hashed_process_data == process_list->current_hash_data[cpu])) { + process_list->current_hash_data[cpu] = NULL; + } + } + + gdk_pixmap_unref(hashed_process_data->pixmap); + + update_index_to_pixmap(process_list); - Process_Info.pid = pid; - Process_Info.cpu = cpu; - Process_Info.birth = *birth; - Process_Info.trace_num = trace_num; + process_list->number_of_process--; - if(hashed_process_data = - (HashedProcessData*)g_hash_table_lookup( - process_list->process_hash, - &Process_Info)) - { - tree_path = gtk_tree_model_get_path( - GTK_TREE_MODEL(process_list->list_store), - &hashed_process_data->y_iter); - path_indices = gtk_tree_path_get_indices (tree_path); - - *height = get_cell_height(process_list, - GTK_TREE_VIEW(process_list->process_list_widget)); - *y = *height * path_indices[0]; - *pm_hashed_process_data = hashed_process_data; - gtk_tree_path_free(tree_path); - return 0; } else { - *pm_hashed_process_data = hashed_process_data; return 1; } - } -__inline gint processlist_get_pixels_from_data( ProcessList *process_list, - ProcessInfo *process_info, - HashedProcessData *hashed_process_data, - guint *y, - guint *height) -{ - gint *path_indices; - GtkTreePath *tree_path; - - tree_path = gtk_tree_model_get_path(GTK_TREE_MODEL(process_list->list_store), - &hashed_process_data->y_iter); - path_indices = gtk_tree_path_get_indices (tree_path); - - *height = get_cell_height(process_list, - GTK_TREE_VIEW(process_list->process_list_widget)); - *y = *height * path_indices[0]; - gtk_tree_path_free(tree_path); - - return 0; - -} - -static __inline guint get_cpu_number_from_name(GQuark name) +#if 0 +static inline guint get_cpu_number_from_name(GQuark name) { const gchar *string; char *begin; @@ -655,4 +783,4 @@ static __inline guint get_cpu_number_from_name(GQuark name) return cpu; } - +#endif //0