X-Git-Url: https://git.lttng.org/?p=lttngtop.git;a=blobdiff_plain;f=src%2Fcursesdisplay.c;h=a2e3f275edd0c6bf528aad812bdd75e7551d3842;hp=af09cb2df1280a7bb1292d988ad052ca83998c84;hb=3b15348ccad727f0d6232af738efa96b20ebc56a;hpb=d26643ed7ca126bc2cb88970270d8867e1546e1b diff --git a/src/cursesdisplay.c b/src/cursesdisplay.c index af09cb2..a2e3f27 100644 --- a/src/cursesdisplay.c +++ b/src/cursesdisplay.c @@ -38,11 +38,11 @@ sem_t update_display_sem; char *termtype; WINDOW *footer, *header, *center, *status; -WINDOW *perf_panel_window = NULL; -PANEL *perf_panel, *main_panel; +WINDOW *pref_panel_window = NULL; +PANEL *pref_panel, *main_panel; -int perf_panel_visible = 0; -int perf_line_selected = 0; +int pref_panel_visible = 0; +int pref_line_selected = 0; int last_display_index, currently_displayed_index; @@ -65,6 +65,8 @@ GPtrArray *selected_processes; pthread_t keyboard_thread; +struct cputopview cputopview[4]; + void reset_ncurses() { curs_set(1); @@ -374,6 +376,34 @@ gint sort_by_cpu_desc(gconstpointer p1, gconstpointer p2) return -1; } +gint sort_by_tid_desc(gconstpointer p1, gconstpointer p2) +{ + struct processtop *n1 = *(struct processtop **)p1; + struct processtop *n2 = *(struct processtop **)p2; + unsigned long totaln1 = n1->tid; + unsigned long totaln2 = n2->tid; + + if (totaln1 < totaln2) + return 1; + if (totaln1 == totaln2) + return 0; + return -1; +} + +gint sort_by_pid_desc(gconstpointer p1, gconstpointer p2) +{ + struct processtop *n1 = *(struct processtop **)p1; + struct processtop *n2 = *(struct processtop **)p2; + unsigned long totaln1 = n1->pid; + unsigned long totaln2 = n2->pid; + + if (totaln1 < totaln2) + return 1; + if (totaln1 == totaln2) + return 0; + return -1; +} + gint sort_by_cpu_group_by_threads_desc(gconstpointer p1, gconstpointer p2) { struct processtop *n1 = *(struct processtop **)p1; @@ -401,14 +431,23 @@ void update_cputop_display() elapsed = data->end - data->start; maxcputime = elapsed * data->cpu_table->len / 100.0; - g_ptr_array_sort(data->process_table, sort_by_cpu_desc); + if (cputopview[0].sort == 1) + g_ptr_array_sort(data->process_table, sort_by_cpu_desc); + else if (cputopview[1].sort == 1) + g_ptr_array_sort(data->process_table, sort_by_pid_desc); + else if (cputopview[2].sort == 1) + g_ptr_array_sort(data->process_table, sort_by_tid_desc); + else if (cputopview[3].sort == 1) + g_ptr_array_sort(data->process_table, sort_by_cpu_desc); + else + g_ptr_array_sort(data->process_table, sort_by_cpu_desc); set_window_title(center, "CPU Top"); wattron(center, A_BOLD); - mvwprintw(center, 1, 1, "CPU(%)"); - mvwprintw(center, 1, 12, "TGID"); - mvwprintw(center, 1, 22, "PID"); - mvwprintw(center, 1, 32, "NAME"); + mvwprintw(center, 1, 1, cputopview[0].title); + mvwprintw(center, 1, 12, cputopview[1].title); + mvwprintw(center, 1, 22, cputopview[2].title); + mvwprintw(center, 1, 32, cputopview[3].title); wattroff(center, A_BOLD); max_center_lines = LINES - 5 - 7 - 1 - header_offset; @@ -418,6 +457,7 @@ void update_cputop_display() nblinedisplayed < max_center_lines; i++) { tmp = g_ptr_array_index(data->process_table, i); + /* FIXME : random segfault here */ if (process_selected(tmp)) { wattron(center, COLOR_PAIR(6)); mvwhline(center, current_line + header_offset, 1, ' ', COLS-3); @@ -494,6 +534,7 @@ void update_process_details() struct files *file_tmp; int i, j = 0; char unit[4]; + char filename_buf[COLS]; set_window_title(center, "Process details"); @@ -535,7 +576,8 @@ void update_process_details() mvwprintw(center, 8, 24, "FILENAME"); wattroff(center, A_BOLD); - for (i = 0; i < tmp->process_files_table->len; i++) { + for (i = selected_line; i < tmp->process_files_table->len && + i < (selected_line + max_center_lines - 7); i++) { file_tmp = get_file(tmp, i); if (file_tmp != NULL) { mvwprintw(center, 9 + j, 1, "%d", i); @@ -543,7 +585,8 @@ void update_process_details() mvwprintw(center, 9 + j, 10, "%s", unit); scale_unit(file_tmp->write, unit); mvwprintw(center, 9 + j, 17, "%s", unit); - mvwprintw(center, 9 + j, 24, "%s", file_tmp->name); + snprintf(filename_buf, COLS - 25, "%s", file_tmp->name); + mvwprintw(center, 9 + j, 24, "%s", filename_buf); j++; } } @@ -570,7 +613,7 @@ void update_perf() mvwprintw(center, 1, 22, "NAME"); perf_row = 40; - g_hash_table_iter_init(&iter, data->perf_list); + g_hash_table_iter_init(&iter, global_perf_liszt); while (g_hash_table_iter_next (&iter, &key, (gpointer) &perfn1)) { if (perfn1->visible) { /* + 5 to strip the "perf_" prefix */ @@ -605,7 +648,7 @@ void update_perf() mvwprintw(center, current_line + header_offset, 11, "%d", tmp->tid); mvwprintw(center, current_line + header_offset, 22, "%s", tmp->comm); - g_hash_table_iter_init(&iter, data->perf_list); + g_hash_table_iter_init(&iter, global_perf_liszt); perf_row = 40; while (g_hash_table_iter_next (&iter, &key, (gpointer) &perfn1)) { @@ -739,45 +782,93 @@ void update_current_view() sem_post(&update_display_sem); } -void setup_perf_panel() +void update_cpu_pref(int *line_selected, int toggle_view, int toggle_sort) { + int i; int size; + if (!data) return; - if (perf_panel_window) { - del_panel(perf_panel); - delwin(perf_panel_window); + if (pref_panel_window) { + del_panel(pref_panel); + delwin(pref_panel_window); } - size = g_hash_table_size(data->perf_list); - perf_panel_window = create_window(size + 2, 30, 10, 10); - perf_panel = new_panel(perf_panel_window); - perf_panel_visible = 0; - hide_panel(perf_panel); + size = 4; + + pref_panel_window = create_window(size + 2, 30, 10, 10); + pref_panel = new_panel(pref_panel_window); + + werase(pref_panel_window); + box(pref_panel_window, 0 , 0); + set_window_title(pref_panel_window, "CPUTop Preferences "); + wattron(pref_panel_window, A_BOLD); + mvwprintw(pref_panel_window, size + 1, 1, + " 's' to sort"); + wattroff(pref_panel_window, A_BOLD); + + if (*line_selected > 3) + *line_selected = 3; + if (toggle_sort == 1) { + /* special case, we don't support sorting by procname for now */ + if (*line_selected != 3) { + if (cputopview[*line_selected].sort == 1) + cputopview[*line_selected].reverse = 1; + for (i = 0; i < 4; i++) + cputopview[i].sort = 0; + cputopview[*line_selected].sort = 1; + update_current_view(); + } + } + + for (i = 0; i < 4; i++) { + if (i == *line_selected) { + wattron(pref_panel_window, COLOR_PAIR(5)); + mvwhline(pref_panel_window, i + 1, 1, ' ', 30 - 2); + } + if (cputopview[i].sort == 1) + wattron(pref_panel_window, A_BOLD); + mvwprintw(pref_panel_window, i + 1, 1, "[x] %s", + cputopview[i].title); + wattroff(pref_panel_window, A_BOLD); + wattroff(pref_panel_window, COLOR_PAIR(5)); + + } + update_panels(); + doupdate(); } -void update_perf_panel(int line_selected, int toggle_view, int toggle_sort) +void update_perf_pref(int *line_selected, int toggle_view, int toggle_sort) { int i; struct perfcounter *perf; GList *perflist; + int size; if (!data) return; + if (pref_panel_window) { + del_panel(pref_panel); + delwin(pref_panel_window); + } + size = g_hash_table_size(global_perf_liszt); - werase(perf_panel_window); - box(perf_panel_window, 0 , 0); - set_window_title(perf_panel_window, "Perf Preferences "); - wattron(perf_panel_window, A_BOLD); - mvwprintw(perf_panel_window, g_hash_table_size(data->perf_list) + 1, 1, + pref_panel_window = create_window(size + 2, 30, 10, 10); + pref_panel = new_panel(pref_panel_window); + + werase(pref_panel_window); + box(pref_panel_window, 0 , 0); + set_window_title(pref_panel_window, "Perf Preferences "); + wattron(pref_panel_window, A_BOLD); + mvwprintw(pref_panel_window, g_hash_table_size(global_perf_liszt) + 1, 1, " 's' to sort"); - wattroff(perf_panel_window, A_BOLD); + wattroff(pref_panel_window, A_BOLD); if (toggle_sort == 1) { i = 0; - perflist = g_list_first(g_hash_table_get_keys(data->perf_list)); + perflist = g_list_first(g_hash_table_get_keys(global_perf_liszt)); while (perflist) { - perf = g_hash_table_lookup(data->perf_list, perflist->data); - if (i != line_selected) + perf = g_hash_table_lookup(global_perf_liszt, perflist->data); + if (i != *line_selected) perf->sort = 0; else perf->sort = 1; @@ -788,24 +879,24 @@ void update_perf_panel(int line_selected, int toggle_view, int toggle_sort) } i = 0; - perflist = g_list_first(g_hash_table_get_keys(data->perf_list)); + perflist = g_list_first(g_hash_table_get_keys(global_perf_liszt)); while (perflist) { - perf = g_hash_table_lookup(data->perf_list, perflist->data); - if (i == line_selected && toggle_view == 1) { + perf = g_hash_table_lookup(global_perf_liszt, perflist->data); + if (i == *line_selected && toggle_view == 1) { perf->visible = perf->visible == 1 ? 0:1; update_current_view(); } - if (i == line_selected) { - wattron(perf_panel_window, COLOR_PAIR(5)); - mvwhline(perf_panel_window, i + 1, 1, ' ', 30 - 2); + if (i == *line_selected) { + wattron(pref_panel_window, COLOR_PAIR(5)); + mvwhline(pref_panel_window, i + 1, 1, ' ', 30 - 2); } if (perf->sort == 1) - wattron(perf_panel_window, A_BOLD); - mvwprintw(perf_panel_window, i + 1, 1, "[%c] %s", + wattron(pref_panel_window, A_BOLD); + mvwprintw(pref_panel_window, i + 1, 1, "[%c] %s", perf->visible == 1 ? 'x' : ' ', (char *) perflist->data + 5); - wattroff(perf_panel_window, A_BOLD); - wattroff(perf_panel_window, COLOR_PAIR(5)); + wattroff(pref_panel_window, A_BOLD); + wattroff(pref_panel_window, COLOR_PAIR(5)); i++; perflist = g_list_next(perflist); } @@ -813,16 +904,38 @@ void update_perf_panel(int line_selected, int toggle_view, int toggle_sort) doupdate(); } -void toggle_perf_panel(void) +int update_preference_panel(int *line_selected, int toggle_view, int toggle_sort) { - if (perf_panel_visible) { - hide_panel(perf_panel); - perf_panel_visible = 0; + int ret = 0; + + switch(current_view) { + case perf: + update_perf_pref(line_selected, toggle_view, toggle_sort); + break; + case cpu: + update_cpu_pref(line_selected, toggle_view, toggle_sort); + break; + default: + ret = -1; + break; + } + + return ret; +} + +void toggle_pref_panel(void) +{ + int ret; + + if (pref_panel_visible) { + hide_panel(pref_panel); + pref_panel_visible = 0; } else { - setup_perf_panel(); - update_perf_panel(perf_line_selected, 0, 0); - show_panel(perf_panel); - perf_panel_visible = 1; + ret = update_preference_panel(&pref_line_selected, 0, 0); + if (ret < 0) + return; + show_panel(pref_panel); + pref_panel_visible = 1; } update_panels(); doupdate(); @@ -863,10 +976,9 @@ void *handle_keyboard(void *p) switch(ch) { /* Move the cursor and scroll */ case KEY_DOWN: - if (perf_panel_visible) { - if (perf_line_selected < g_hash_table_size(data->perf_list) - 1) - perf_line_selected++; - update_perf_panel(perf_line_selected, 0, 0); + if (pref_panel_visible) { + pref_line_selected++; + update_preference_panel(&pref_line_selected, 0, 0); } else { if (selected_line < (max_center_lines - 1) && selected_line < max_elements - 1) { @@ -883,10 +995,10 @@ void *handle_keyboard(void *p) case KEY_NPAGE: break; case KEY_UP: - if (perf_panel_visible) { - if (perf_line_selected > 0) - perf_line_selected--; - update_perf_panel(perf_line_selected, 0, 0); + if (pref_panel_visible) { + if (pref_line_selected > 0) + pref_line_selected--; + update_preference_panel(&pref_line_selected, 0, 0); } else { if (selected_line > 0) { selected_line--; @@ -937,16 +1049,16 @@ void *handle_keyboard(void *p) break; case ' ': - if (perf_panel_visible) { - update_perf_panel(perf_line_selected, 1, 0); + if (pref_panel_visible) { + update_preference_panel(&pref_line_selected, 1, 0); } else { update_selected_processes(); update_current_view(); } break; case 's': - if (perf_panel_visible) - update_perf_panel(perf_line_selected, 0, 1); + if (pref_panel_visible) + update_preference_panel(&pref_line_selected, 0, 1); break; case 13: /* FIXME : KEY_ENTER ?? */ @@ -961,21 +1073,29 @@ void *handle_keyboard(void *p) break; case KEY_F(1): + if (pref_panel_visible) + toggle_pref_panel(); current_view = cpu; selected_line = 0; update_current_view(); break; case KEY_F(2): + if (pref_panel_visible) + toggle_pref_panel(); current_view = cpu; selected_line = 0; update_current_view(); break; case KEY_F(3): + if (pref_panel_visible) + toggle_pref_panel(); current_view = perf; selected_line = 0; update_current_view(); break; case KEY_F(4): + if (pref_panel_visible) + toggle_pref_panel(); current_view = iostream; selected_line = 0; update_current_view(); @@ -996,7 +1116,7 @@ void *handle_keyboard(void *p) } break; case 'P': - toggle_perf_panel(); + toggle_pref_panel(); break; default: if (data) @@ -1019,10 +1139,14 @@ void init_ncurses() status = create_window(MAX_LOG_LINES + 2, COLS - 1, LINES - 7, 0); footer = create_window(1, COLS - 1, LINES - 1, 0); + cputopview[0].title = strdup("CPU(%)"); + cputopview[0].sort = 1; + cputopview[1].title = strdup("TGID"); + cputopview[2].title = strdup("PID"); + cputopview[3].title = strdup("NAME"); print_log("Starting display"); main_panel = new_panel(center); - setup_perf_panel(); current_view = cpu; @@ -1031,4 +1155,3 @@ void init_ncurses() pthread_create(&keyboard_thread, NULL, handle_keyboard, (void *)NULL); } -