From da4353bbbb28c19bd28447018edb94845ae71673 Mon Sep 17 00:00:00 2001 From: Julien Desfossez Date: Tue, 28 Aug 2012 21:40:26 -0400 Subject: [PATCH] filtering in GUI working Signed-off-by: Julien Desfossez --- src/common.c | 47 ++++++++++++++++++---- src/common.h | 6 +++ src/cursesdisplay.c | 97 ++++++++++++++++++++------------------------- src/lttngtop.c | 35 +++++++++++----- 4 files changed, 112 insertions(+), 73 deletions(-) diff --git a/src/common.c b/src/common.c index 1fc74be..500c80d 100644 --- a/src/common.c +++ b/src/common.c @@ -200,7 +200,9 @@ struct processtop* add_proc(struct lttngtop *ctx, int tid, char *comm, g_ptr_array_add(ctx->process_table, newproc); g_hash_table_insert(ctx->process_hash_table, (gpointer) (unsigned long) tid, newproc); - + if (lookup_tid_list(tid)) { + add_filter_tid_list(tid, newproc); + } ctx->nbnewthreads++; ctx->nbthreads++; } @@ -228,6 +230,9 @@ struct processtop* update_proc(struct processtop* proc, int pid, int tid, free(proc->hostname); } proc->hostname = strdup(hostname); + if (lookup_hostname_list(hostname)) { + add_filter_tid_list(tid, proc); + } } } return proc; @@ -522,12 +527,14 @@ struct lttngtop* get_copy_lttngtop(unsigned long start, unsigned long end) */ g_ptr_array_add(dst->cpu_table, newcpu); } - for (i = 0; i < lttngtop.kprobes_table->len; i++) { - tmpprobe = g_ptr_array_index(lttngtop.kprobes_table, i); - newprobe = g_new0(struct kprobes, 1); - memcpy(newprobe, tmpprobe, sizeof(struct kprobes)); - tmpprobe->count = 0; - g_ptr_array_add(dst->kprobes_table, newprobe); + if (lttngtop.kprobes_table) { + for (i = 0; i < lttngtop.kprobes_table->len; i++) { + tmpprobe = g_ptr_array_index(lttngtop.kprobes_table, i); + newprobe = g_new0(struct kprobes, 1); + memcpy(newprobe, tmpprobe, sizeof(struct kprobes)); + tmpprobe->count = 0; + g_ptr_array_add(dst->kprobes_table, newprobe); + } } /* FIXME : better algo */ /* create the threads index if required */ @@ -648,13 +655,37 @@ struct tm format_timestamp(uint64_t timestamp) int *lookup_tid_list(int tid) { + if (!tid_list) + return NULL; + return g_hash_table_lookup(tid_list, (gpointer) &tid); } char *lookup_hostname_list(const char *hostname) { - if (!hostname) + if (!hostname || !hostname_list) return NULL; return g_hash_table_lookup(hostname_list, (gpointer) hostname); } + +int *lookup_filter_tid_list(int tid) +{ + return g_hash_table_lookup(global_filter_list, (gpointer) &tid); +} + +void add_filter_tid_list(int tid, struct processtop *newproc) +{ + unsigned long *hash_tid; + + hash_tid = malloc(sizeof(unsigned long)); + *hash_tid = tid; + g_hash_table_insert(global_filter_list, + (gpointer) (unsigned long) hash_tid, newproc); +} + +void remove_filter_tid_list(int tid) +{ + g_hash_table_remove(global_filter_list, + (gpointer) (unsigned long) &tid); +} diff --git a/src/common.h b/src/common.h index 06bb219..59a7a7f 100644 --- a/src/common.h +++ b/src/common.h @@ -30,6 +30,7 @@ sem_t goodtodisplay, goodtoupdate, timer, pause_sem, end_trace_sem, bootstrap; GPtrArray *copies; /* struct lttngtop */ GHashTable *global_perf_liszt; +GHashTable *global_filter_list; char *opt_tid; char *opt_hostname; @@ -37,6 +38,8 @@ char *opt_kprobes; GHashTable *tid_list; GHashTable *hostname_list; +int toggle_filter; + extern int quit; struct lttngtop *data; @@ -81,7 +84,10 @@ enum bt_cb_ret handle_statedump_process_state(struct bt_ctf_event *call_data, struct tm format_timestamp(uint64_t timestamp); +int *lookup_filter_tid_list(int tid); int *lookup_tid_list(int tid); char *lookup_hostname_list(const char *hostname); +void add_filter_tid_list(int tid, struct processtop *newproc); +void remove_filter_tid_list(int tid); #endif /* _COMMON_H */ diff --git a/src/cursesdisplay.c b/src/cursesdisplay.c index 4cc9730..3695131 100644 --- a/src/cursesdisplay.c +++ b/src/cursesdisplay.c @@ -63,7 +63,6 @@ int toggle_virt = -1; int toggle_pause = -1; int max_center_lines; -GPtrArray *selected_processes; pthread_t keyboard_thread; @@ -106,8 +105,9 @@ void init_screen() init_pair(2, COLOR_GREEN, COLOR_BLACK); /* + */ init_pair(3, COLOR_BLACK, COLOR_WHITE); /* keys */ init_pair(4, COLOR_WHITE, COLOR_GREEN); /* keys activated */ - init_pair(5, COLOR_WHITE, COLOR_BLUE); /* select line */ - init_pair(6, COLOR_WHITE, COLOR_GREEN); /* selected process */ + init_pair(5, COLOR_BLACK, COLOR_YELLOW); /* select line */ + init_pair(6, COLOR_GREEN, COLOR_BLACK); /* selected process */ + init_pair(7, COLOR_RED, COLOR_YELLOW); /* selected process + line*/ } termtype = getenv("TERM"); if (!strcmp(termtype, "xterm") || !strcmp(termtype, "xterm-color") || @@ -232,37 +232,17 @@ void print_log(char *str) int process_selected(struct processtop *process) { - int i; - struct processtop *stored_process; - - for (i = 0; i < selected_processes->len; i++) { - stored_process = g_ptr_array_index(selected_processes, i); - if (!stored_process) - return 0; - if (stored_process->tid == process->tid) - return 1; - } + if (lookup_filter_tid_list(process->tid)) + return 1; return 0; } void update_selected_processes() { - int i; - struct processtop *stored_process; - if (process_selected(selected_process)) { - for (i = 0; i < selected_processes->len; i++) { - stored_process = g_ptr_array_index(selected_processes, i); - if (!stored_process) - return; - if (stored_process->tid == selected_process->tid) - g_ptr_array_remove(selected_processes, - stored_process); - print_log("Process removed"); - } + remove_filter_tid_list(selected_process->tid); } else { - g_ptr_array_add(selected_processes, selected_process); - print_log("Process added"); + add_filter_tid_list(selected_process->tid, selected_process); } } @@ -604,27 +584,26 @@ void update_cputop_display() nblinedisplayed < max_center_lines; i++) { tmp = g_ptr_array_index(data->process_table, i); current_row_offset = 1; - if (!opt_tid && (opt_hostname && !lookup_hostname_list(tmp->hostname))) - continue; - if (!opt_hostname && (opt_tid && !lookup_tid_list(tmp->pid))) - continue; - if ((opt_tid && !lookup_tid_list(tmp->tid)) && - (opt_hostname && !lookup_hostname_list(tmp->hostname))) + if (toggle_filter > 0 && !lookup_filter_tid_list(tmp->tid)) continue; if (tmp->pid != tmp->tid) if (toggle_threads == -1) continue; - if (process_selected(tmp)) { - wattron(center, COLOR_PAIR(6)); - mvwhline(center, current_line + header_offset, 1, ' ', COLS-3); - } + /* line */ if (current_line == selected_line) { selected_process = tmp; wattron(center, COLOR_PAIR(5)); mvwhline(center, current_line + header_offset, 1, ' ', COLS-3); } + /* filtered process */ + if (process_selected(tmp)) { + if (current_line == selected_line) + wattron(center, COLOR_PAIR(7)); + else + wattron(center, COLOR_PAIR(6)); + } /* CPU(%) */ mvwprintw(center, current_line + header_offset, current_row_offset, "%1.2f", @@ -651,6 +630,7 @@ void update_cputop_display() /* NAME */ mvwprintw(center, current_line + header_offset, current_row_offset, "%s", tmp->comm); + wattroff(center, COLOR_PAIR(7)); wattroff(center, COLOR_PAIR(6)); wattroff(center, COLOR_PAIR(5)); nblinedisplayed++; @@ -862,12 +842,7 @@ void update_perf() nblinedisplayed < max_center_lines; i++) { tmp = g_ptr_array_index(data->process_table, i); - if (!opt_tid && (opt_hostname && !lookup_hostname_list(tmp->hostname))) - continue; - if (!opt_hostname && (opt_tid && !lookup_tid_list(tmp->pid))) - continue; - if ((opt_tid && !lookup_tid_list(tmp->tid)) && - (opt_hostname && !lookup_hostname_list(tmp->hostname))) + if (toggle_filter > 0 && !lookup_filter_tid_list(tmp->tid)) continue; if (tmp->pid != tmp->tid) @@ -875,8 +850,10 @@ void update_perf() continue; if (process_selected(tmp)) { - wattron(center, COLOR_PAIR(6)); - mvwhline(center, current_line + header_offset, 1, ' ', COLS-3); + if (current_line == selected_line) + wattron(center, COLOR_PAIR(7)); + else + wattron(center, COLOR_PAIR(6)); } if (current_line == selected_line) { selected_process = tmp; @@ -953,12 +930,7 @@ void update_iostream() nblinedisplayed < max_center_lines; i++) { tmp = g_ptr_array_index(data->process_table, i); - if (!opt_tid && (opt_hostname && !lookup_hostname_list(tmp->hostname))) - continue; - if (!opt_hostname && (opt_tid && !lookup_tid_list(tmp->pid))) - continue; - if ((opt_tid && !lookup_tid_list(tmp->tid)) && - (opt_hostname && !lookup_hostname_list(tmp->hostname))) + if (toggle_filter > 0 && !lookup_filter_tid_list(tmp->tid)) continue; if (tmp->pid != tmp->tid) @@ -966,8 +938,10 @@ void update_iostream() continue; if (process_selected(tmp)) { - wattron(center, COLOR_PAIR(6)); - mvwhline(center, current_line + header_offset, 1, ' ', COLS-3); + if (current_line == selected_line) + wattron(center, COLOR_PAIR(7)); + else + wattron(center, COLOR_PAIR(6)); } if (current_line == selected_line) { selected_process = tmp; @@ -1518,6 +1492,13 @@ void *handle_keyboard(void *p) update_preference_panel(&pref_line_selected, 1, 0); } else { update_selected_processes(); + if (toggle_filter > 0) { + max_elements = g_hash_table_size(global_filter_list); + fprintf(stderr, "select : %d, max : %d\n", + selected_line, max_elements); + if (selected_line >= max_elements) + selected_line = max_elements - 1; + } update_current_view(); } break; @@ -1601,6 +1582,15 @@ void *handle_keyboard(void *p) /* exit keyboard thread */ pthread_exit(0); break; + case 'f': + toggle_filter *= -1; + selected_line = 0; + if (toggle_filter > 0) + max_elements = g_hash_table_size(global_filter_list); + else + max_elements = data->process_table->len; + update_current_view(); + break; case 't': toggle_threads *= -1; update_current_view(); @@ -1666,7 +1656,6 @@ void init_view_headers() void init_ncurses() { - selected_processes = g_ptr_array_new(); sem_init(&update_display_sem, 0, 1); init_view_headers(); init_screen(); diff --git a/src/lttngtop.c b/src/lttngtop.c index 024dc5b..26da967 100644 --- a/src/lttngtop.c +++ b/src/lttngtop.c @@ -214,6 +214,11 @@ enum bt_cb_ret print_timestamp(struct bt_ctf_event *call_data, void *private_dat } hostname = get_context_hostname(call_data); + if (opt_tid || opt_hostname) + if (!lookup_filter_tid_list(pid)) + goto end; + + /* if (!opt_tid && (opt_hostname && !lookup_hostname_list(hostname))) goto end; if (!opt_hostname && (opt_tid && !lookup_tid_list(pid))) @@ -221,6 +226,7 @@ enum bt_cb_ret print_timestamp(struct bt_ctf_event *call_data, void *private_dat if ((opt_tid && !lookup_tid_list(pid)) && (opt_hostname && !lookup_hostname_list(hostname))) goto end; + */ cpu_id = get_cpu_id(call_data); procname = get_context_comm(call_data); @@ -484,6 +490,7 @@ void init_lttngtop() { copies = g_ptr_array_new(); global_perf_liszt = g_hash_table_new(g_str_hash, g_str_equal); + global_filter_list = g_hash_table_new(g_str_hash, g_str_equal); sem_init(&goodtodisplay, 0, 0); sem_init(&goodtoupdate, 0, 1); @@ -502,6 +509,8 @@ void init_lttngtop() lttngtop.process_table = g_ptr_array_new(); lttngtop.files_table = g_ptr_array_new(); lttngtop.cpu_table = g_ptr_array_new(); + + toggle_filter = -1; } void usage(FILE *fp) @@ -620,6 +629,7 @@ static int parse_options(int argc, char **argv) opt_child = 1; break; case OPT_PID: + toggle_filter = 1; tid_list = g_hash_table_new(g_str_hash, g_str_equal); tmp_str = strtok(opt_tid, ","); @@ -632,6 +642,7 @@ static int parse_options(int argc, char **argv) } break; case OPT_HOSTNAME: + toggle_filter = 1; hostname_list = g_hash_table_new(g_str_hash, g_str_equal); tmp_str = strtok(opt_hostname, ","); @@ -688,6 +699,10 @@ void iter_trace(struct bt_context *bt_ctx) begin_pos.type = BT_SEEK_BEGIN; iter = bt_ctf_iter_create(bt_ctx, &begin_pos, NULL); + /* at each event, verify the status of the process table */ + bt_ctf_iter_add_callback(iter, 0, NULL, 0, + fix_process_table, + NULL, NULL, NULL); if (opt_textdump) { bt_ctf_iter_add_callback(iter, 0, NULL, 0, print_timestamp, @@ -697,10 +712,6 @@ void iter_trace(struct bt_context *bt_ctx) bt_ctf_iter_add_callback(iter, 0, NULL, 0, check_timestamp, NULL, NULL, NULL); - /* at each event, verify the status of the process table */ - bt_ctf_iter_add_callback(iter, 0, NULL, 0, - fix_process_table, - NULL, NULL, NULL); /* to handle the scheduling events */ bt_ctf_iter_add_callback(iter, g_quark_from_static_string("sched_switch"), @@ -739,13 +750,15 @@ void iter_trace(struct bt_context *bt_ctx) NULL, NULL, NULL); /* for kprobes */ - for (i = 0; i < lttngtop.kprobes_table->len; i++) { - kprobe = g_ptr_array_index(lttngtop.kprobes_table, i); - bt_ctf_iter_add_callback(iter, - g_quark_from_static_string( - kprobe->probe_name), - NULL, 0, handle_kprobes, - NULL, NULL, NULL); + if (lttngtop.kprobes_table) { + for (i = 0; i < lttngtop.kprobes_table->len; i++) { + kprobe = g_ptr_array_index(lttngtop.kprobes_table, i); + bt_ctf_iter_add_callback(iter, + g_quark_from_static_string( + kprobe->probe_name), + NULL, 0, handle_kprobes, + NULL, NULL, NULL); + } } } -- 2.34.1