X-Git-Url: https://git.lttng.org/?p=lttngtop.git;a=blobdiff_plain;f=src%2Fcursesdisplay.c;h=97069fe10299347334db8104ca36a45dc233112e;hp=c8d7067805c6b37440edcc2bf2827a5ab8e8b923;hb=fbbda4dac5b23757921dea8e2992cbb6bff5775f;hpb=951303ccce366e1850310349ab03dce0300d4bea diff --git a/src/cursesdisplay.c b/src/cursesdisplay.c index c8d7067..97069fe 100644 --- a/src/cursesdisplay.c +++ b/src/cursesdisplay.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Julien Desfossez + * Copyright (C) 2011-2012 Julien Desfossez * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License Version 2 as @@ -43,6 +43,7 @@ PANEL *pref_panel, *main_panel; int pref_panel_visible = 0; int pref_line_selected = 0; +int pref_current_sort = 0; int last_display_index, currently_displayed_index; @@ -57,7 +58,8 @@ char log_lines[MAX_LINE_LENGTH * MAX_LOG_LINES + MAX_LOG_LINES]; int max_elements = 80; -int toggle_threads = -1; +int toggle_threads = 1; +int toggle_virt = -1; int toggle_pause = -1; int max_center_lines; @@ -65,7 +67,7 @@ GPtrArray *selected_processes; pthread_t keyboard_thread; -struct header_view cputopview[4]; +struct header_view cputopview[6]; struct header_view iostreamtopview[3]; struct header_view fileview[3]; @@ -73,11 +75,17 @@ void reset_ncurses() { curs_set(1); endwin(); - exit(0); + quit = 1; + sem_post(&pause_sem); + sem_post(&timer); + sem_post(&goodtodisplay); + sem_post(&end_trace_sem); + sem_post(&goodtoupdate); } static void handle_sigterm(int signal) { + pthread_cancel(keyboard_thread); reset_ncurses(); } @@ -118,6 +126,7 @@ void init_screen() define_key("\033[17;2~", KEY_F(18)); } signal(SIGTERM, handle_sigterm); + signal(SIGINT, handle_sigterm); mousemask(BUTTON1_CLICKED, NULL); refresh(); } @@ -281,6 +290,8 @@ void update_footer() print_key(footer, "Space", "Highlight ", 0); print_key(footer, "q", "Quit ", 0); print_key(footer, "r", "Pref ", 0); + print_key(footer, "t", "Threads ", toggle_threads); + print_key(footer, "v", "Virt ", toggle_virt); print_key(footer, "p", "Pause ", toggle_pause); wrefresh(footer); @@ -300,23 +311,6 @@ void basic_header() wrefresh(header); } -struct tm format_timestamp(uint64_t timestamp) -{ - struct tm tm; - uint64_t ts_sec = 0, ts_nsec; - time_t time_s; - - ts_nsec = timestamp; - ts_sec += ts_nsec / NSEC_PER_SEC; - ts_nsec = ts_nsec % NSEC_PER_SEC; - - time_s = (time_t) ts_sec; - - localtime_r(&time_s, &tm); - - return tm; -} - static void scale_unit(uint64_t bytes, char *ret) { if (bytes >= 1000000000) @@ -328,6 +322,7 @@ static void scale_unit(uint64_t bytes, char *ret) else sprintf(ret, "%" PRIu64, bytes); } + uint64_t total_io() { int i; @@ -450,8 +445,8 @@ gint sort_by_process_total_desc(gconstpointer p1, gconstpointer p2) { struct processtop *n1 = *(struct processtop **)p1; struct processtop *n2 = *(struct processtop **)p2; - unsigned long totaln1 = n1->filewrite + n1->fileread; - unsigned long totaln2 = n2->filewrite + n2->fileread; + unsigned long totaln1 = n1->totalfilewrite + n1->totalfileread; + unsigned long totaln2 = n2->totalfilewrite + n2->totalfileread; if (totaln1 < totaln2) return 1; @@ -525,6 +520,30 @@ gint sort_by_cpu_group_by_threads_desc(gconstpointer p1, gconstpointer p2) return -1; } +void update_kprobes_display() +{ + int i, column; + + set_window_title(center, "Kprobes Top"); + /* + wattron(center, A_BOLD); + column = 1; + for (i = 0; i < 6; i++) { + if (toggle_virt < 0 && (i == 3 || i == 4)) { + continue; + } + if (cputopview[i].sort) { + wattron(center, A_UNDERLINE); + pref_current_sort = i; + } + mvwprintw(center, 1, column, cputopview[i].title); + wattroff(center, A_UNDERLINE); + column += 10; + } + wattroff(center, A_BOLD); + */ +} + void update_cputop_display() { int i; @@ -534,6 +553,7 @@ void update_cputop_display() double maxcputime; int nblinedisplayed = 0; int current_line = 0; + int current_row_offset; int column; elapsed = data->end - data->start; @@ -553,9 +573,14 @@ void update_cputop_display() set_window_title(center, "CPU Top"); wattron(center, A_BOLD); column = 1; - for (i = 0; i < 4; i++) { - if (cputopview[i].sort) + for (i = 0; i < 6; i++) { + if (toggle_virt < 0 && (i == 3 || i == 4)) { + continue; + } + if (cputopview[i].sort) { wattron(center, A_UNDERLINE); + pref_current_sort = i; + } mvwprintw(center, 1, column, cputopview[i].title); wattroff(center, A_UNDERLINE); column += 10; @@ -568,6 +593,18 @@ void update_cputop_display() for (i = list_offset; i < data->process_table->len && 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))) + continue; + + if (tmp->pid != tmp->tid) + if (toggle_threads == -1) + continue; if (process_selected(tmp)) { wattron(center, COLOR_PAIR(6)); @@ -579,14 +616,31 @@ void update_cputop_display() mvwhline(center, current_line + header_offset, 1, ' ', COLS-3); } /* CPU(%) */ - mvwprintw(center, current_line + header_offset, 1, "%1.2f", + mvwprintw(center, current_line + header_offset, + current_row_offset, "%1.2f", tmp->totalcpunsec / maxcputime); - /* TGID */ - mvwprintw(center, current_line + header_offset, 11, "%d", tmp->pid); + current_row_offset += 10; /* PID */ - mvwprintw(center, current_line + header_offset, 21, "%d", tmp->tid); + mvwprintw(center, current_line + header_offset, + current_row_offset, "%d", tmp->pid); + current_row_offset += 10; + /* TID */ + mvwprintw(center, current_line + header_offset, + current_row_offset, "%d", tmp->tid); + current_row_offset += 10; + if (toggle_virt > 0) { + /* VPID */ + mvwprintw(center, current_line + header_offset, + current_row_offset, "%d", tmp->vpid); + current_row_offset += 10; + /* VTID */ + mvwprintw(center, current_line + header_offset, + current_row_offset, "%d", tmp->vtid); + current_row_offset += 10; + } /* NAME */ - mvwprintw(center, current_line + header_offset, 31, "%s", tmp->comm); + mvwprintw(center, current_line + header_offset, + current_row_offset, "%s", tmp->comm); wattroff(center, COLOR_PAIR(6)); wattroff(center, COLOR_PAIR(5)); nblinedisplayed++; @@ -648,6 +702,7 @@ void update_process_details() char unit[4]; char filename_buf[COLS]; int line = 1; + int column; GPtrArray *newfilearray = g_ptr_array_new(); GHashTableIter iter; struct perfcounter *perfn1, *perfn2; @@ -675,6 +730,12 @@ void update_process_details() wprintw(center, "%d", tmp->pid); print_key_title("PPID", line++); wprintw(center, "%d", tmp->ppid); + print_key_title("VPID", line++); + wprintw(center, "%d", tmp->vpid); + print_key_title("VTID", line++); + wprintw(center, "%d", tmp->vtid); + print_key_title("VPPID", line++); + wprintw(center, "%d", tmp->vppid); print_key_title("CPU", line++); wprintw(center, "%1.2f %%", tmp->totalcpunsec/maxcputime); @@ -695,10 +756,17 @@ void update_process_details() line++; wattron(center, A_BOLD); - mvwprintw(center, line, 1, "FD"); - mvwprintw(center, line, 10, "READ"); - mvwprintw(center, line, 17, "WRITE"); - mvwprintw(center, line++, 24, "FILENAME"); + column = 1; + for (i = 0; i < 3; i++) { + if (fileview[i].sort) { + pref_current_sort = i; + wattron(center, A_UNDERLINE); + } + mvwprintw(center, line, column, fileview[i].title); + wattroff(center, A_UNDERLINE); + column += 10; + } + mvwprintw(center, line++, column, "FILENAME"); wattroff(center, A_BOLD); /* @@ -728,11 +796,11 @@ void update_process_details() continue; mvwprintw(center, line + j, 1, "%d", file_tmp->fd); scale_unit(file_tmp->read, unit); - mvwprintw(center, line + j, 10, "%s", unit); + mvwprintw(center, line + j, 11, "%s", unit); scale_unit(file_tmp->write, unit); - mvwprintw(center, line + j, 17, "%s", unit); + mvwprintw(center, line + j, 21, "%s", unit); snprintf(filename_buf, COLS - 25, "%s", file_tmp->name); - mvwprintw(center, line + j, 24, "%s", filename_buf); + mvwprintw(center, line + j, 31, "%s", filename_buf); j++; } g_ptr_array_free(newfilearray, TRUE); @@ -762,16 +830,20 @@ void update_perf() g_hash_table_iter_init(&iter, global_perf_liszt); while (g_hash_table_iter_next (&iter, &key, (gpointer) &perfn1)) { if (perfn1->visible) { + if (perfn1->sort) { + /* pref_current_sort = i; */ + wattron(center, A_UNDERLINE); + } /* + 5 to strip the "perf_" prefix */ mvwprintw(center, 1, perf_row, "%s", (char *) key + 5); + wattroff(center, A_UNDERLINE); perf_row += 20; } if (perfn1->sort) { perf_key = (char *) key; } } - wattroff(center, A_BOLD); g_ptr_array_sort_with_data(data->process_table, sort_perf, perf_key); @@ -780,6 +852,18 @@ 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))) + 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); @@ -826,16 +910,25 @@ void update_iostream() int current_line = 0; int total = 0; char unit[4]; + int column; set_window_title(center, "IO Top"); wattron(center, A_BOLD); mvwprintw(center, 1, 1, "PID"); mvwprintw(center, 1, 11, "TID"); mvwprintw(center, 1, 22, "NAME"); - mvwprintw(center, 1, 40, "R (B/sec)"); - mvwprintw(center, 1, 52, "W (B/sec)"); - mvwprintw(center, 1, 64, "Total"); + column = 40; + for (i = 0; i < 3; i++) { + if (iostreamtopview[i].sort) { + pref_current_sort = i; + wattron(center, A_UNDERLINE); + } + mvwprintw(center, 1, column, iostreamtopview[i].title); + wattroff(center, A_UNDERLINE); + column += 12; + } wattroff(center, A_BOLD); + wattroff(center, A_UNDERLINE); if (iostreamtopview[0].sort == 1) g_ptr_array_sort(data->process_table, sort_by_process_read_desc); @@ -850,6 +943,18 @@ 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))) + 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); @@ -912,6 +1017,9 @@ void update_current_view() case tree: update_cputop_display(); break; + case kprobes: + update_kprobes_display(); + break; default: break; } @@ -920,6 +1028,25 @@ void update_current_view() sem_post(&update_display_sem); } +void update_process_detail_sort(int *line_selected) +{ + int i; + int size; + + size = 3; + + if (*line_selected > (size - 1)) + *line_selected = size - 1; + else if (*line_selected < 0) + *line_selected = 0; + + if (fileview[*line_selected].sort == 1) + fileview[*line_selected].reverse = 1; + for (i = 0; i < size; i++) + fileview[i].sort = 0; + fileview[*line_selected].sort = 1; +} + void update_process_detail_pref(int *line_selected, int toggle_view, int toggle_sort) { int i; @@ -946,12 +1073,10 @@ void update_process_detail_pref(int *line_selected, int toggle_view, int toggle_ if (*line_selected > (size - 1)) *line_selected = size - 1; + else if (*line_selected < 0) + *line_selected = 0; if (toggle_sort == 1) { - if (fileview[*line_selected].sort == 1) - fileview[*line_selected].reverse = 1; - for (i = 0; i < size; i++) - fileview[i].sort = 0; - fileview[*line_selected].sort = 1; + update_process_detail_sort(line_selected); update_current_view(); } @@ -972,6 +1097,24 @@ void update_process_detail_pref(int *line_selected, int toggle_view, int toggle_ doupdate(); } +void update_iostream_sort(int *line_selected) +{ + int i; + int size; + + size = 3; + if (*line_selected > (size - 1)) + *line_selected = size - 1; + else if (*line_selected < 0) + *line_selected = 0; + if (iostreamtopview[*line_selected].sort == 1) + iostreamtopview[*line_selected].reverse = 1; + for (i = 0; i < size; i++) + iostreamtopview[i].sort = 0; + iostreamtopview[*line_selected].sort = 1; + +} + void update_iostream_pref(int *line_selected, int toggle_view, int toggle_sort) { int i; @@ -998,12 +1141,10 @@ void update_iostream_pref(int *line_selected, int toggle_view, int toggle_sort) if (*line_selected > (size - 1)) *line_selected = size - 1; + else if (*line_selected < 0) + *line_selected = 0; if (toggle_sort == 1) { - if (iostreamtopview[*line_selected].sort == 1) - iostreamtopview[*line_selected].reverse = 1; - for (i = 0; i < size; i++) - iostreamtopview[i].sort = 0; - iostreamtopview[*line_selected].sort = 1; + update_iostream_sort(line_selected); update_current_view(); } @@ -1024,6 +1165,26 @@ void update_iostream_pref(int *line_selected, int toggle_view, int toggle_sort) doupdate(); } +void update_cpu_sort(int *line_selected) +{ + int i; + int size = 3; + + if (*line_selected > (size - 1)) + *line_selected = size - 1; + else if (*line_selected < 0) + *line_selected = 0; + + /* 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 < size; i++) + cputopview[i].sort = 0; + cputopview[*line_selected].sort = 1; + } +} + void update_cpu_pref(int *line_selected, int toggle_view, int toggle_sort) { int i; @@ -1050,16 +1211,11 @@ void update_cpu_pref(int *line_selected, int toggle_view, int toggle_sort) if (*line_selected > (size - 1)) *line_selected = size - 1; + else if (*line_selected < 0) + *line_selected = 0; 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 < size; i++) - cputopview[i].sort = 0; - cputopview[*line_selected].sort = 1; - update_current_view(); - } + update_cpu_sort(line_selected); + update_current_view(); } for (i = 0; i < size; i++) { @@ -1079,6 +1235,32 @@ void update_cpu_pref(int *line_selected, int toggle_view, int toggle_sort) doupdate(); } +void update_perf_sort(int *line_selected) +{ + int i; + struct perfcounter *perf; + GList *perflist; + int size; + + size = g_hash_table_size(global_perf_liszt); + if (*line_selected > (size - 1)) + *line_selected = size - 1; + else if (*line_selected < 0) + *line_selected = 0; + + i = 0; + perflist = g_list_first(g_hash_table_get_keys(global_perf_liszt)); + while (perflist) { + perf = g_hash_table_lookup(global_perf_liszt, perflist->data); + if (i != *line_selected) + perf->sort = 0; + else + perf->sort = 1; + i++; + perflist = g_list_next(perflist); + } +} + void update_perf_pref(int *line_selected, int toggle_view, int toggle_sort) { int i; @@ -1105,18 +1287,13 @@ void update_perf_pref(int *line_selected, int toggle_view, int toggle_sort) " 's' : sort, space : toggle"); wattroff(pref_panel_window, A_BOLD); + if (*line_selected > (size - 1)) + *line_selected = size - 1; + else if (*line_selected < 0) + *line_selected = 0; + if (toggle_sort == 1) { - i = 0; - perflist = g_list_first(g_hash_table_get_keys(global_perf_liszt)); - while (perflist) { - perf = g_hash_table_lookup(global_perf_liszt, perflist->data); - if (i != *line_selected) - perf->sort = 0; - else - perf->sort = 1; - i++; - perflist = g_list_next(perflist); - } + update_perf_sort(line_selected); update_current_view(); } @@ -1171,6 +1348,32 @@ int update_preference_panel(int *line_selected, int toggle_view, int toggle_sort return ret; } +int update_sort(int *line_selected) +{ + int ret = 0; + + switch(current_view) { + case perf: + update_perf_sort(line_selected); + break; + case cpu: + update_cpu_sort(line_selected); + break; + case iostream: + update_iostream_sort(line_selected); + break; + case process_details: + update_process_detail_sort(line_selected); + break; + default: + ret = -1; + break; + } + + return ret; +} + + void toggle_pref_panel(void) { int ret; @@ -1312,6 +1515,26 @@ void *handle_keyboard(void *p) if (pref_panel_visible) update_preference_panel(&pref_line_selected, 0, 1); break; + case '>': + /* perf uses a hashtable, it is ordered backward */ + if (current_view == perf) { + pref_current_sort--; + } else if (!pref_panel_visible) { + pref_current_sort++; + } + update_sort(&pref_current_sort); + update_current_view(); + break; + case '<': + /* perf uses a hashtable, it is ordered backward */ + if (current_view == perf) { + pref_current_sort++; + } else if (!pref_panel_visible) { + pref_current_sort--; + } + update_sort(&pref_current_sort); + update_current_view(); + break; case 13: /* FIXME : KEY_ENTER ?? */ if (pref_panel_visible) @@ -1323,6 +1546,7 @@ void *handle_keyboard(void *p) current_view = previous_view; previous_view = process_details; } + selected_line = 0; update_current_view(); break; @@ -1354,9 +1578,18 @@ void *handle_keyboard(void *p) selected_line = 0; update_current_view(); break; + case KEY_F(5): + if (pref_panel_visible) + toggle_pref_panel(); + current_view = kprobes; + selected_line = 0; + update_current_view(); + break; case KEY_F(10): case 'q': reset_ncurses(); + /* exit keyboard thread */ + pthread_exit(0); break; case 't': toggle_threads *= -1; @@ -1372,6 +1605,10 @@ void *handle_keyboard(void *p) case 'r': toggle_pref_panel(); break; + case 'v': + toggle_virt *= -1; + update_current_view(); + break; /* ESCAPE, but slow to process, don't know why */ case 27: if (pref_panel_visible) @@ -1396,9 +1633,11 @@ void init_view_headers() { cputopview[0].title = strdup("CPU(%)"); cputopview[0].sort = 1; - cputopview[1].title = strdup("TGID"); - cputopview[2].title = strdup("PID"); - cputopview[3].title = strdup("NAME"); + cputopview[1].title = strdup("PID"); + cputopview[2].title = strdup("TID"); + cputopview[3].title = strdup("VPID"); + cputopview[4].title = strdup("VTID"); + cputopview[5].title = strdup("NAME"); iostreamtopview[0].title = strdup("R (B/sec)"); iostreamtopview[1].title = strdup("W (B/sec)");