From bdd0561e19389a10901240dc907a969d9f97c898 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 10 Feb 2010 17:14:28 -0500 Subject: trace-graph: Add hash to lookup pids and cpus Add a hash in the graph info to quickly look up to see if plots have been registered to a pid or cpus. This is currently not used but will be in the following patches. Signed-off-by: Steven Rostedt --- trace-graph.c | 3 +- trace-graph.h | 42 +++++++++++++---- trace-plot-cpu.c | 5 +- trace-plot-task.c | 7 ++- trace-plot.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 171 insertions(+), 19 deletions(-) diff --git a/trace-graph.c b/trace-graph.c index 85009cf..f1f0a2c 100644 --- a/trace-graph.c +++ b/trace-graph.c @@ -1626,7 +1626,6 @@ static void draw_info(struct graph_info *ginfo, draw_timeline(ginfo, new_width); - for (i = 0; i < ginfo->plots; i++) draw_plot(ginfo, i, new_width, ginfo->read_comms); @@ -2087,7 +2086,7 @@ trace_graph_create_with_callbacks(struct tracecmd_input *handle, ginfo->task_filter = filter_task_hash_alloc(); ginfo->hide_tasks = filter_task_hash_alloc(); - + ginfo->widget = gtk_hbox_new(FALSE, 0); gtk_widget_show(ginfo->widget); diff --git a/trace-graph.h b/trace-graph.h index 8e75dbb..f7bc117 100644 --- a/trace-graph.h +++ b/trace-graph.h @@ -81,6 +81,7 @@ struct plot_callbacks { }; struct graph_plot { + struct graph_plot *next; /* for hash */ int pos; char *label; const struct plot_callbacks *cb; @@ -92,6 +93,14 @@ struct graph_callbacks { graph_filter_cb *filter; }; +struct plot_hash { + struct plot_hash *next; + struct graph_plot *plots; + gint val; +}; + +#define PLOT_HASH_SIZE 1024 + struct graph_info { struct tracecmd_input *handle; struct pevent *pevent; @@ -101,6 +110,9 @@ struct graph_info { struct graph_plot **plot_array; /* all plots */ struct graph_plot *plot_clicked; /* plot that was clicked on */ + gint nr_task_hash; + struct plot_hash *task_hash[PLOT_HASH_SIZE]; + struct plot_hash *cpu_hash[PLOT_HASH_SIZE]; GtkWidget *widget; /* Box to hold graph */ GtkWidget *scrollwin; /* graph scroll window */ @@ -226,15 +238,29 @@ gboolean trace_graph_filter_on_event(struct graph_info *ginfo, struct record *re /* plots */ void trace_graph_plot_free(struct graph_info *ginfo); void trace_graph_plot_init(struct graph_info *ginfo); -void trace_graph_plot_append(struct graph_info *ginfo, - const char *label, const struct plot_callbacks *cb, - void *data); -void trace_graph_plot_insert(struct graph_info *ginfo, - int pos, - const char *label, const struct plot_callbacks *cb, - void *data); +struct graph_plot *trace_graph_plot_append(struct graph_info *ginfo, + const char *label, + const struct plot_callbacks *cb, + void *data); +struct graph_plot *trace_graph_plot_insert(struct graph_info *ginfo, + int pos, + const char *label, + const struct plot_callbacks *cb, + void *data); void trace_graph_plot_remove(struct graph_info *ginfo, struct graph_plot *plot); - +struct plot_hash *trace_graph_plot_find_task(struct graph_info *ginfo, gint task); +void trace_graph_plot_add_task(struct graph_info *ginfo, struct graph_plot *plot, + gint task); +void trace_graph_plot_remove_task(struct graph_info *ginfo, + struct graph_plot *plot, + gint task); +struct plot_hash *trace_graph_plot_find_cpu(struct graph_info *ginfo, gint cpu); +void trace_graph_plot_add_cpu(struct graph_info *ginfo, struct graph_plot *plot, + gint cpu); +void trace_graph_plot_remove_cpu(struct graph_info *ginfo, struct graph_plot *plot, + gint cpu); + +/* plot callbacks */ int trace_graph_plot_match_time(struct graph_info *ginfo, struct graph_plot *plot, unsigned long long time); diff --git a/trace-plot-cpu.c b/trace-plot-cpu.c index 7fd9ecc..2690155 100644 --- a/trace-plot-cpu.c +++ b/trace-plot-cpu.c @@ -398,6 +398,7 @@ void cpu_plot_destroy(struct graph_info *ginfo, struct graph_plot *plot) { struct cpu_plot_info *cpu_info = plot->private; + trace_graph_plot_remove_cpu(ginfo, plot, cpu_info->cpu); free(cpu_info); } @@ -414,6 +415,7 @@ static const struct plot_callbacks cpu_plot_cb = { void graph_plot_init_cpus(struct graph_info *ginfo, int cpus) { struct cpu_plot_info *cpu_info; + struct graph_plot *plot; char label[100]; long cpu; @@ -423,6 +425,7 @@ void graph_plot_init_cpus(struct graph_info *ginfo, int cpus) snprintf(label, 100, "CPU %ld", cpu); - trace_graph_plot_append(ginfo, label, &cpu_plot_cb, cpu_info); + plot = trace_graph_plot_append(ginfo, label, &cpu_plot_cb, cpu_info); + trace_graph_plot_add_cpu(ginfo, plot, cpu); } } diff --git a/trace-plot-task.c b/trace-plot-task.c index abe4025..6b35586 100644 --- a/trace-plot-task.c +++ b/trace-plot-task.c @@ -536,6 +536,8 @@ void task_plot_destroy(struct graph_info *ginfo, struct graph_plot *plot) { struct task_plot_info *task_info = plot->private; + trace_graph_plot_remove_task(ginfo, plot, task_info->pid); + free(task_info); } @@ -576,11 +578,14 @@ void graph_plot_init_tasks(struct graph_info *ginfo) void graph_plot_task(struct graph_info *ginfo, int pid) { struct task_plot_info *task_info; + struct graph_plot *plot; char label[100]; task_info = malloc_or_die(sizeof(*task_info)); task_info->pid = pid; snprintf(label, 100, "TASK %d", pid); - trace_graph_plot_append(ginfo, label, &task_plot_cb, task_info); + plot = trace_graph_plot_append(ginfo, label, &task_plot_cb, task_info); + + trace_graph_plot_add_task(ginfo, plot, pid); } diff --git a/trace-plot.c b/trace-plot.c index c6f7e7a..5f0ab75 100644 --- a/trace-plot.c +++ b/trace-plot.c @@ -44,9 +44,10 @@ allocate_plot(struct graph_info *ginfo, return plot; } -void trace_graph_plot_append(struct graph_info *ginfo, - const char *label, const struct plot_callbacks *cb, - void *data) +struct graph_plot * +trace_graph_plot_append(struct graph_info *ginfo, + const char *label, const struct plot_callbacks *cb, + void *data) { struct graph_plot *plot; @@ -69,12 +70,15 @@ void trace_graph_plot_append(struct graph_info *ginfo, } ginfo->plots++; + + return plot; } -void trace_graph_plot_insert(struct graph_info *ginfo, - int pos, - const char *label, const struct plot_callbacks *cb, - void *data) +struct graph_plot * +trace_graph_plot_insert(struct graph_info *ginfo, + int pos, + const char *label, const struct plot_callbacks *cb, + void *data) { struct graph_plot *plot; int i; @@ -104,6 +108,8 @@ void trace_graph_plot_insert(struct graph_info *ginfo, /* Update the new positions */ for (i = pos + 1; i < ginfo->plots; i++) ginfo->plot_array[i]->pos = i; + + return plot; } void trace_graph_plot_remove(struct graph_info *ginfo, struct graph_plot *plot) @@ -131,6 +137,119 @@ void trace_graph_plot_remove(struct graph_info *ginfo, struct graph_plot *plot) } } +static struct plot_hash *find_hash(struct plot_hash **array, gint val) +{ + struct plot_hash *hash; + gint key; + + key = trace_hash(val) % PLOT_HASH_SIZE; + + for (hash = array[key]; hash; hash = hash->next) { + if (hash->val == val) + return hash; + } + + return NULL; +} + +static void add_hash(struct plot_hash **array, struct graph_plot *plot, gint val) +{ + struct plot_hash *hash; + gint key; + + hash = find_hash(array, val); + if (!hash) { + hash = g_new0(typeof(*hash), 1); + g_assert(hash); + key = trace_hash(val) % PLOT_HASH_SIZE; + hash->next = array[key]; + hash->val = val; + array[key] = hash; + } + + plot->next = hash->plots; + hash->plots = plot; +} + +static void remove_hash(struct plot_hash **array, struct graph_plot *plot, gint val) +{ + struct plot_hash *hash, **phash; + struct graph_plot **pplot; + gint key; + + hash = find_hash(array, val); + pplot = &hash->plots; + + while (*pplot) { + if (*pplot == plot) { + *pplot = plot->next; + break; + } + pplot = &(*pplot)->next; + } + + if (hash->plots) + return; + + /* remove this hash item */ + key = trace_hash(val) % PLOT_HASH_SIZE; + phash = &array[key]; + while (*phash) { + if (*phash == hash) { + *phash = hash->next; + break; + } + phash = &(*phash)->next; + } + + g_free(hash); +} + +struct plot_hash * +trace_graph_plot_find_task(struct graph_info *ginfo, gint task) +{ + return find_hash(ginfo->task_hash, task); +} + +void trace_graph_plot_add_task(struct graph_info *ginfo, + struct graph_plot *plot, + gint task) +{ + add_hash(ginfo->task_hash, plot, task); + ginfo->nr_task_hash++; +} + +void trace_graph_plot_remove_task(struct graph_info *ginfo, + struct graph_plot *plot, + gint task) +{ + remove_hash(ginfo->task_hash, plot, task); + ginfo->nr_task_hash--; +} + +struct plot_hash * +trace_graph_plot_find_cpu(struct graph_info *ginfo, gint cpu) +{ + return find_hash(ginfo->cpu_hash, cpu); +} + +void trace_graph_plot_add_cpu(struct graph_info *ginfo, + struct graph_plot *plot, + gint cpu) +{ + add_hash(ginfo->cpu_hash, plot, cpu); +} + +void trace_graph_plot_remove_cpu(struct graph_info *ginfo, + struct graph_plot *plot, + gint cpu) +{ + remove_hash(ginfo->cpu_hash, plot, cpu); +} + + +/* Plot callback helpers */ + int trace_graph_plot_match_time(struct graph_info *ginfo, struct graph_plot *plot, unsigned long long time) -- cgit v1.2.2