Commit | Line | Data |
---|---|---|
1fc22eb4 | 1 | /* |
aa15ac1c | 2 | * Copyright (C) 2011-2012 Julien Desfossez |
1fc22eb4 JD |
3 | * |
4 | * This program is free software; you can redistribute it and/or modify | |
5 | * it under the terms of the GNU General Public License Version 2 as | |
6 | * published by the Free Software Foundation; | |
7 | * | |
8 | * This program is distributed in the hope that it will be useful, | |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | * GNU General Public License for more details. | |
12 | * | |
71bd7ce1 AM |
13 | * You should have received a copy of the GNU General Public License along |
14 | * with this program; if not, write to the Free Software Foundation, Inc., | |
15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
1fc22eb4 JD |
16 | */ |
17 | ||
18 | #include <stdio.h> | |
19 | #include <stdlib.h> | |
20 | #include <signal.h> | |
21 | #include <string.h> | |
22 | #include <ncurses.h> | |
23 | #include <panel.h> | |
24 | #include <pthread.h> | |
25 | #include <semaphore.h> | |
26 | ||
715cf83c PBT |
27 | #include <state/StateSystem.hpp> |
28 | #include <state/statevalue/StateValue.hpp> | |
29 | #include <state/statevalue/IntegerStateValue.hpp> | |
30 | #include <state/statevalue/StringStateValue.hpp> | |
31 | #include <state/statevalue/NullStateValue.hpp> | |
32 | #include <state/statevalue/QuarkStateValue.hpp> | |
33 | ||
34 | #define __STDC_FORMAT_MACROS | |
35 | #include <inttypes.h> | |
36 | ||
1fc22eb4 JD |
37 | #include "cursesdisplay.h" |
38 | #include "lttngtoptypes.h" | |
b093de8a | 39 | #include "iostreamtop.h" |
1fc22eb4 JD |
40 | #include "common.h" |
41 | ||
42 | #define DEFAULT_DELAY 15 | |
43 | #define MAX_LINE_LENGTH 50 | |
44 | #define MAX_LOG_LINES 4 | |
45 | ||
715cf83c PBT |
46 | using namespace State; |
47 | ||
48 | enum view_list current_view; | |
49 | enum view_list previous_view; | |
50 | ||
1fc22eb4 JD |
51 | /* to prevent concurrent updates of the different windows */ |
52 | sem_t update_display_sem; | |
53 | ||
54 | char *termtype; | |
55 | WINDOW *footer, *header, *center, *status; | |
0d91c12a JD |
56 | WINDOW *pref_panel_window = NULL; |
57 | PANEL *pref_panel, *main_panel; | |
1fc22eb4 | 58 | |
0d91c12a | 59 | int pref_panel_visible = 0; |
3b15348c | 60 | int pref_line_selected = 0; |
41ff0645 | 61 | int pref_current_sort = 0; |
1fc22eb4 | 62 | |
715cf83c | 63 | Quark selected_process; |
1fc22eb4 JD |
64 | int selected_ret; |
65 | ||
66 | int selected_line = 0; /* select bar position */ | |
67 | int selected_in_list = 0; /* selection relative to the whole list */ | |
68 | int list_offset = 0; /* first index in the list to display (scroll) */ | |
69 | int nb_log_lines = 0; | |
70 | char log_lines[MAX_LINE_LENGTH * MAX_LOG_LINES + MAX_LOG_LINES]; | |
71 | ||
72 | int max_elements = 80; | |
73 | ||
e15ed00a | 74 | int toggle_threads = 1; |
1fc22eb4 | 75 | int toggle_pause = -1; |
1fc22eb4 JD |
76 | |
77 | int max_center_lines; | |
635dc837 | 78 | GPtrArray *selected_processes; |
1fc22eb4 JD |
79 | |
80 | pthread_t keyboard_thread; | |
81 | ||
89f1e0d1 JD |
82 | struct header_view cputopview[4]; |
83 | struct header_view iostreamtopview[3]; | |
32647247 | 84 | struct header_view fileview[3]; |
3b15348c | 85 | |
715cf83c PBT |
86 | unsigned long i_start = 0; |
87 | unsigned long i_end = 0; | |
88 | ||
89 | std::string sort_perf_key; | |
90 | ||
91 | ||
1fc22eb4 JD |
92 | void reset_ncurses() |
93 | { | |
94 | curs_set(1); | |
95 | endwin(); | |
96 | exit(0); | |
97 | } | |
98 | ||
99 | static void handle_sigterm(int signal) | |
100 | { | |
101 | reset_ncurses(); | |
102 | } | |
103 | ||
104 | void init_screen() | |
105 | { | |
106 | initscr(); | |
107 | noecho(); | |
108 | halfdelay(DEFAULT_DELAY); | |
109 | nonl(); | |
110 | intrflush(stdscr, false); | |
111 | keypad(stdscr, true); | |
112 | curs_set(0); | |
113 | ||
114 | if (has_colors()) { | |
115 | start_color(); | |
116 | init_pair(1, COLOR_RED, COLOR_BLACK); /* - */ | |
117 | init_pair(2, COLOR_GREEN, COLOR_BLACK); /* + */ | |
118 | init_pair(3, COLOR_BLACK, COLOR_WHITE); /* keys */ | |
119 | init_pair(4, COLOR_WHITE, COLOR_GREEN); /* keys activated */ | |
120 | init_pair(5, COLOR_WHITE, COLOR_BLUE); /* select line */ | |
635dc837 | 121 | init_pair(6, COLOR_WHITE, COLOR_GREEN); /* selected process */ |
1fc22eb4 JD |
122 | } |
123 | termtype = getenv("TERM"); | |
124 | if (!strcmp(termtype, "xterm") || !strcmp(termtype, "xterm-color") || | |
125 | !strcmp(termtype, "vt220")) { | |
126 | define_key("\033[H", KEY_HOME); | |
127 | define_key("\033[F", KEY_END); | |
128 | define_key("\033OP", KEY_F(1)); | |
129 | define_key("\033OQ", KEY_F(2)); | |
130 | define_key("\033OR", KEY_F(3)); | |
131 | define_key("\033OS", KEY_F(4)); | |
132 | define_key("\0330U", KEY_F(6)); | |
133 | define_key("\033[11~", KEY_F(1)); | |
134 | define_key("\033[12~", KEY_F(2)); | |
135 | define_key("\033[13~", KEY_F(3)); | |
136 | define_key("\033[14~", KEY_F(4)); | |
137 | define_key("\033[16~", KEY_F(6)); | |
138 | define_key("\033[17;2~", KEY_F(18)); | |
139 | } | |
140 | signal(SIGTERM, handle_sigterm); | |
141 | mousemask(BUTTON1_CLICKED, NULL); | |
142 | refresh(); | |
143 | } | |
144 | ||
145 | WINDOW *create_window(int height, int width, int startx, int starty) | |
146 | { | |
147 | WINDOW *win; | |
148 | win = newwin(height, width, startx, starty); | |
149 | box(win, 0 , 0); | |
150 | wrefresh(win); | |
151 | return win; | |
152 | } | |
153 | ||
154 | WINDOW *create_window_no_border(int height, int width, int startx, int starty) | |
155 | { | |
156 | WINDOW *win; | |
157 | win = newwin(height, width, startx, starty); | |
158 | wrefresh(win); | |
159 | return win; | |
160 | } | |
161 | ||
162 | void print_digit(WINDOW *win, int digit) | |
163 | { | |
164 | if (digit < 0) { | |
165 | wattron(win, COLOR_PAIR(1)); | |
166 | wprintw(win, "%d", digit); | |
167 | wattroff(win, COLOR_PAIR(1)); | |
168 | } else if (digit > 0) { | |
169 | wattron(win, COLOR_PAIR(2)); | |
170 | wprintw(win, "+%d", digit); | |
171 | wattroff(win, COLOR_PAIR(2)); | |
172 | } else { | |
173 | wprintw(win, "0"); | |
174 | } | |
175 | } | |
176 | ||
177 | void print_digits(WINDOW *win, int first, int second) | |
178 | { | |
179 | wprintw(win, "("); | |
180 | print_digit(win, first); | |
181 | wprintw(win, ", "); | |
182 | print_digit(win, second); | |
183 | wprintw(win, ")"); | |
184 | } | |
185 | ||
715cf83c | 186 | void print_headers(int line, const char desc[], int value, int first, int second) |
1fc22eb4 JD |
187 | { |
188 | wattron(header, A_BOLD); | |
189 | mvwprintw(header, line, 4, "%s", desc); | |
190 | wattroff(header, A_BOLD); | |
e05a35a6 | 191 | mvwprintw(header, line, 16, "%d", value); |
1fc22eb4 JD |
192 | wmove(header, line, 24); |
193 | print_digits(header, first, second); | |
194 | wmove(header, line, 40); | |
195 | } | |
196 | ||
715cf83c | 197 | void set_window_title(WINDOW *win, const char title[]) |
1fc22eb4 JD |
198 | { |
199 | wattron(win, A_BOLD); | |
200 | mvwprintw(win, 0, 1, title); | |
201 | wattroff(win, A_BOLD); | |
202 | } | |
203 | ||
715cf83c | 204 | void print_log(const char str[]) |
1fc22eb4 | 205 | { |
715cf83c | 206 | unsigned int i; |
1fc22eb4 JD |
207 | int current_line = 1; |
208 | int current_char = 1; | |
209 | char *tmp, *tmp2; | |
210 | /* rotate the line buffer */ | |
211 | if (nb_log_lines >= MAX_LOG_LINES) { | |
212 | tmp = strndup(log_lines, MAX_LINE_LENGTH * MAX_LOG_LINES + MAX_LOG_LINES); | |
213 | tmp2 = strchr(tmp, '\n'); | |
214 | memset(log_lines, '\0', strlen(log_lines)); | |
215 | strncat(log_lines, tmp2 + 1, strlen(tmp2) - 1); | |
216 | log_lines[strlen(log_lines)] = '\n'; | |
217 | log_lines[strlen(log_lines)] = '\0'; | |
218 | free(tmp); | |
219 | } | |
220 | nb_log_lines++; | |
221 | ||
222 | strncat(log_lines, str, MAX_LINE_LENGTH - 1); | |
223 | ||
224 | if (nb_log_lines < MAX_LOG_LINES) | |
225 | log_lines[strlen(log_lines)] = '\n'; | |
226 | log_lines[strlen(log_lines)] = '\0'; | |
227 | ||
228 | werase(status); | |
229 | box(status, 0 , 0); | |
230 | set_window_title(status, "Status"); | |
231 | for (i = 0; i < strlen(log_lines); i++) { | |
232 | if (log_lines[i] == '\n') { | |
233 | wmove(status, ++current_line, 1); | |
234 | current_char = 1; | |
235 | } else { | |
b093de8a MB |
236 | mvwprintw(status, current_line, current_char++, "%c", |
237 | log_lines[i]); | |
1fc22eb4 JD |
238 | } |
239 | } | |
240 | wrefresh(status); | |
241 | } | |
242 | ||
715cf83c | 243 | int process_selected(Quark proc) |
635dc837 | 244 | { |
715cf83c PBT |
245 | int selected; |
246 | get_current_attribute_value_int(&proc, "selected", selected); | |
247 | return selected; | |
635dc837 JD |
248 | } |
249 | ||
250 | void update_selected_processes() | |
251 | { | |
715cf83c | 252 | Quark selected = state_system->getQuark(selected_process, "selected"); |
635dc837 | 253 | if (process_selected(selected_process)) { |
715cf83c PBT |
254 | state_system->updateCurrentState(selected, 0); |
255 | print_log("Process removed"); | |
635dc837 | 256 | } else { |
715cf83c | 257 | state_system->updateCurrentState(selected, 1); |
635dc837 JD |
258 | print_log("Process added"); |
259 | } | |
260 | } | |
261 | ||
715cf83c | 262 | void print_key(WINDOW *win, const char key[], const char desc[], int toggle) |
1fc22eb4 JD |
263 | { |
264 | int pair; | |
265 | if (toggle > 0) | |
266 | pair = 4; | |
267 | else | |
268 | pair = 3; | |
269 | wattron(win, COLOR_PAIR(pair)); | |
270 | wprintw(footer, "%s", key); | |
271 | wattroff(win, COLOR_PAIR(pair)); | |
272 | wprintw(footer, ":%s", desc); | |
273 | } | |
274 | ||
275 | void update_footer() | |
276 | { | |
277 | sem_wait(&update_display_sem); | |
278 | werase(footer); | |
279 | wmove(footer, 1, 1); | |
280 | print_key(footer, "F2", "CPUtop ", current_view == cpu); | |
281 | print_key(footer, "F3", "PerfTop ", current_view == perf); | |
e7be7d41 | 282 | print_key(footer, "F4", "IOTop ", current_view == iostream); |
1fc22eb4 | 283 | print_key(footer, "Enter", "Details ", current_view == process_details); |
635dc837 | 284 | print_key(footer, "Space", "Highlight ", 0); |
d33aae69 | 285 | print_key(footer, "q", "Quit ", 0); |
f9ff6939 | 286 | print_key(footer, "r", "Pref ", 0); |
e15ed00a | 287 | print_key(footer, "t", "Threads ", toggle_threads); |
1fc22eb4 JD |
288 | print_key(footer, "p", "Pause ", toggle_pause); |
289 | ||
290 | wrefresh(footer); | |
291 | sem_post(&update_display_sem); | |
292 | } | |
293 | ||
294 | void basic_header() | |
295 | { | |
296 | werase(header); | |
297 | box(header, 0 , 0); | |
298 | set_window_title(header, "Statistics for interval [gathering data...["); | |
299 | wattron(header, A_BOLD); | |
300 | mvwprintw(header, 1, 4, "CPUs"); | |
e05a35a6 | 301 | mvwprintw(header, 2, 4, "Threads"); |
dc8f04dd | 302 | mvwprintw(header, 3, 4, "FDs"); |
1fc22eb4 JD |
303 | wattroff(header, A_BOLD); |
304 | wrefresh(header); | |
305 | } | |
306 | ||
91be6bb5 JD |
307 | struct tm format_timestamp(uint64_t timestamp) |
308 | { | |
309 | struct tm tm; | |
310 | uint64_t ts_sec = 0, ts_nsec; | |
311 | time_t time_s; | |
312 | ||
313 | ts_nsec = timestamp; | |
314 | ts_sec += ts_nsec / NSEC_PER_SEC; | |
315 | ts_nsec = ts_nsec % NSEC_PER_SEC; | |
316 | ||
317 | time_s = (time_t) ts_sec; | |
318 | ||
319 | localtime_r(&time_s, &tm); | |
320 | ||
321 | return tm; | |
322 | } | |
323 | ||
69362330 JD |
324 | static void scale_unit(uint64_t bytes, char *ret) |
325 | { | |
326 | if (bytes >= 1000000000) | |
327 | sprintf(ret, "%" PRIu64 "G", bytes/1000000000); | |
328 | if (bytes >= 1000000) | |
329 | sprintf(ret, "%" PRIu64 "M", bytes/1000000); | |
330 | else if (bytes >= 1000) | |
331 | sprintf(ret, "%" PRIu64 "K", bytes/1000); | |
332 | else | |
333 | sprintf(ret, "%" PRIu64, bytes); | |
334 | } | |
41ff0645 | 335 | |
69362330 JD |
336 | uint64_t total_io() |
337 | { | |
69362330 | 338 | uint64_t total = 0; |
715cf83c PBT |
339 | int read, write; |
340 | unsigned long birth; | |
341 | unsigned long real_start; | |
342 | Quark proc; | |
343 | ||
344 | if (get_attribute_value_at_quark(i_end, NULL, "proc", proc)) { | |
345 | do { | |
346 | get_attribute_value_at_ulong( | |
347 | i_end, &proc, "birth", birth); | |
348 | if (birth > i_start) | |
349 | real_start = birth; | |
350 | else | |
351 | real_start = i_start; | |
352 | get_interval_value_int(real_start, i_end, &proc, | |
353 | "fileread", read); | |
354 | get_interval_value_int(real_start, i_end, &proc, | |
355 | "filewrite", write); | |
356 | total += read + write; | |
357 | ||
358 | } while (get_attribute_value_at_quark( | |
359 | i_end, &proc, "next", proc)); | |
69362330 JD |
360 | } |
361 | ||
362 | return total; | |
363 | } | |
364 | ||
1fc22eb4 JD |
365 | void update_header() |
366 | { | |
91be6bb5 JD |
367 | struct tm start, end; |
368 | uint64_t ts_nsec_start, ts_nsec_end; | |
715cf83c PBT |
369 | char io[16]; |
370 | int cpu_nb; | |
371 | int nbthreads, nbnewthreads, nbdeadthreads; | |
372 | int nbfiles, nbnewfiles, nbdeadfiles; | |
91be6bb5 | 373 | |
715cf83c PBT |
374 | ts_nsec_start = i_start % NSEC_PER_SEC; |
375 | start = format_timestamp(i_start); | |
91be6bb5 | 376 | |
715cf83c PBT |
377 | ts_nsec_end = i_end % NSEC_PER_SEC; |
378 | end = format_timestamp(i_end); | |
91be6bb5 | 379 | |
1fc22eb4 JD |
380 | werase(header); |
381 | box(header, 0 , 0); | |
382 | set_window_title(header, "Statistics for interval "); | |
383 | wattron(header, A_BOLD); | |
91be6bb5 | 384 | |
715cf83c PBT |
385 | wprintw(header, |
386 | "[%02d:%02d:%02d.%09" PRIu64 ", %02d:%02d:%02d.%09" PRIu64 "[", | |
91be6bb5 JD |
387 | start.tm_hour, start.tm_min, start.tm_sec, ts_nsec_start, |
388 | end.tm_hour, end.tm_min, end.tm_sec, ts_nsec_end); | |
1fc22eb4 JD |
389 | mvwprintw(header, 1, 4, "CPUs"); |
390 | wattroff(header, A_BOLD); | |
715cf83c PBT |
391 | |
392 | cpu_nb = get_sequence_length(i_end, state_system->getQuark("cpu")); | |
393 | get_attribute_value_at_int(i_end, NULL, "nbthreads", nbthreads); | |
394 | get_interval_value_int(i_start, i_end, NULL, "nbnewthreads", | |
395 | nbnewthreads); | |
396 | get_interval_value_int(i_start, i_end, NULL, "nbdeadthreads", | |
397 | nbdeadthreads); | |
398 | get_attribute_value_at_int(i_end, NULL, "nbfiles", nbfiles); | |
399 | get_interval_value_int(i_start, i_end, NULL, "nbnewfiles", nbnewfiles); | |
400 | get_interval_value_int(i_start, i_end, NULL, "nbdeadfiles", | |
401 | nbdeadfiles); | |
402 | ||
403 | wprintw(header, "\t%d\t(max/cpu : %0.2f%)", cpu_nb, | |
404 | 100.0/cpu_nb); | |
405 | print_headers(2, "Threads", nbthreads, nbnewthreads,-1*nbdeadthreads); | |
406 | print_headers(3, "FDs", nbfiles, nbnewfiles,-1*nbdeadfiles); | |
69362330 JD |
407 | scale_unit(total_io(), io); |
408 | mvwprintw(header, 3, 43, "%sB/sec", io); | |
1fc22eb4 JD |
409 | wrefresh(header); |
410 | } | |
411 | ||
715cf83c | 412 | int sort_by_cpu_desc(const void *pp1, const void *pp2) |
1fc22eb4 | 413 | { |
715cf83c PBT |
414 | Quark p1 = *(Quark *)pp1; |
415 | Quark p2 = *(Quark *)pp2; | |
416 | unsigned long total1, total2; | |
417 | unsigned long birth1, birth2; | |
418 | unsigned long start1 = i_start; | |
419 | unsigned long start2 = i_start; | |
420 | ||
421 | get_attribute_value_at_ulong(i_end, &p1, "birth", birth1); | |
422 | get_attribute_value_at_ulong(i_end, &p2, "birth", birth2); | |
423 | if (birth1 > i_start) | |
424 | start1 = birth1; | |
425 | if (birth2 > i_start) | |
426 | start2 = birth2; | |
427 | ||
428 | get_interval_value_ulong(start1, i_end, &p1, "totalcpunsec", total1); | |
429 | get_interval_value_ulong(start2, i_end, &p2, "totalcpunsec", total2); | |
430 | ||
431 | if (total1 > total2) | |
1fc22eb4 | 432 | return 1; |
715cf83c | 433 | if (total1 == total2) |
1fc22eb4 JD |
434 | return 0; |
435 | return -1; | |
436 | } | |
437 | ||
715cf83c | 438 | int sort_by_tid_desc(const void *pp1, const void *pp2) |
3b15348c | 439 | { |
715cf83c PBT |
440 | Quark p1 = *(Quark *)pp1; |
441 | Quark p2 = *(Quark *)pp2; | |
442 | int tid1, tid2; | |
443 | ||
444 | get_attribute_value_at_int(i_end, &p1, "tid", tid1); | |
445 | get_attribute_value_at_int(i_end, &p2, "tid", tid2); | |
3b15348c | 446 | |
715cf83c | 447 | if (tid1 > tid2) |
3b15348c | 448 | return 1; |
715cf83c | 449 | if (tid1 == tid2) |
3b15348c JD |
450 | return 0; |
451 | return -1; | |
452 | } | |
453 | ||
715cf83c | 454 | int sort_by_pid_desc(const void *pp1, const void *pp2) |
3b15348c | 455 | { |
715cf83c PBT |
456 | Quark p1 = *(Quark *)pp1; |
457 | Quark p2 = *(Quark *)pp2; | |
458 | int pid1, pid2; | |
459 | ||
460 | get_attribute_value_at_int(i_end, &p1, "pid", pid1); | |
461 | get_attribute_value_at_int(i_end, &p2, "pid", pid2); | |
3b15348c | 462 | |
715cf83c | 463 | if (pid1 > pid2) |
3b15348c | 464 | return 1; |
715cf83c | 465 | if (pid1 == pid2) |
3b15348c JD |
466 | return 0; |
467 | return -1; | |
468 | } | |
469 | ||
89f1e0d1 | 470 | |
715cf83c PBT |
471 | int sort_by_process_read_desc(const void *pp1, const void *pp2) |
472 | { | |
473 | Quark p1 = *(Quark *)pp1; | |
474 | Quark p2 = *(Quark *)pp2; | |
475 | int total1, total2; | |
476 | unsigned long birth1, birth2; | |
477 | unsigned long start1 = i_start; | |
478 | unsigned long start2 = i_start; | |
479 | ||
480 | get_attribute_value_at_ulong(i_end, &p1, "birth", birth1); | |
481 | get_attribute_value_at_ulong(i_end, &p2, "birth", birth2); | |
482 | if (birth1 > i_start) | |
483 | start1 = birth1; | |
484 | if (birth2 > i_start) | |
485 | start2 = birth2; | |
486 | ||
487 | get_interval_value_int(start1, i_end, &p1, "fileread", total1); | |
488 | get_interval_value_int(start2, i_end, &p2, "fileread", total2); | |
489 | ||
490 | if (total1 > total2) | |
89f1e0d1 | 491 | return 1; |
715cf83c | 492 | if (total1 == total2) |
89f1e0d1 JD |
493 | return 0; |
494 | return -1; | |
495 | } | |
496 | ||
715cf83c | 497 | int sort_by_process_write_desc(const void *pp1, const void *pp2) |
89f1e0d1 | 498 | { |
715cf83c PBT |
499 | Quark p1 = *(Quark *)pp1; |
500 | Quark p2 = *(Quark *)pp2; | |
501 | int total1, total2; | |
502 | unsigned long birth1, birth2; | |
503 | unsigned long start1 = i_start; | |
504 | unsigned long start2 = i_start; | |
505 | ||
506 | get_attribute_value_at_ulong(i_end, &p1, "birth", birth1); | |
507 | get_attribute_value_at_ulong(i_end, &p2, "birth", birth2); | |
508 | if (birth1 > i_start) | |
509 | start1 = birth1; | |
510 | if (birth2 > i_start) | |
511 | start2 = birth2; | |
512 | ||
513 | get_interval_value_int(start1, i_end, &p1, "filewrite", total1); | |
514 | get_interval_value_int(start2, i_end, &p2, "filewrite", total2); | |
515 | ||
516 | if (total1 > total2) | |
89f1e0d1 | 517 | return 1; |
715cf83c | 518 | if (total1 == total2) |
89f1e0d1 JD |
519 | return 0; |
520 | return -1; | |
521 | } | |
522 | ||
715cf83c | 523 | int sort_by_process_total_desc(const void *pp1, const void *pp2) |
89f1e0d1 | 524 | { |
715cf83c PBT |
525 | Quark p1 = *(Quark *)pp1; |
526 | Quark p2 = *(Quark *)pp2; | |
527 | int p1Read, p2Read; | |
528 | int p1Write, p2Write; | |
529 | int total1, total2; | |
530 | unsigned long birth1, birth2; | |
531 | unsigned long start1 = i_start; | |
532 | unsigned long start2 = i_start; | |
533 | ||
534 | get_attribute_value_at_ulong(i_end, &p1, "birth", birth1); | |
535 | get_attribute_value_at_ulong(i_end, &p2, "birth", birth2); | |
536 | if (birth1 > i_start) | |
537 | start1 = birth1; | |
538 | if (birth2 > i_start) | |
539 | start2 = birth2; | |
540 | ||
541 | get_interval_value_int(start1, i_end, &p1, "fileread", p1Read); | |
542 | get_interval_value_int(start2, i_end, &p2, "fileread", p2Read); | |
543 | get_interval_value_int(start1, i_end, &p1, "filewrite", p1Write); | |
544 | get_interval_value_int(start2, i_end, &p2, "filewrite", p2Write); | |
545 | ||
546 | total1 = p1Read + p1Write; | |
547 | total2 = p2Read + p2Write; | |
548 | ||
549 | if (total1 > total2) | |
89f1e0d1 | 550 | return 1; |
715cf83c | 551 | if (total1 == total2) |
89f1e0d1 JD |
552 | return 0; |
553 | return -1; | |
554 | } | |
555 | ||
715cf83c | 556 | int sort_by_file_read_desc(const void *pf1, const void *pf2) |
32647247 | 557 | { |
715cf83c PBT |
558 | Quark f1 = *(Quark *)pf1; |
559 | Quark f2 = *(Quark *)pf2; | |
560 | int total1, total2; | |
561 | unsigned long birth1, birth2; | |
562 | unsigned long start1 = i_start; | |
563 | unsigned long start2 = i_start; | |
564 | ||
565 | get_attribute_value_at_ulong(i_end, &f1, "file/birth", birth1); | |
566 | get_attribute_value_at_ulong(i_end, &f2, "file/birth", birth2); | |
567 | if (birth1 > i_start) | |
568 | start1 = birth1; | |
569 | if (birth2 > i_start) | |
570 | start2 = birth2; | |
571 | ||
572 | get_interval_value_int(start1, i_end, &f1, "file/read", total1); | |
573 | get_interval_value_int(start2, i_end, &f2, "file/read", total2); | |
574 | ||
575 | if (total1 > total2) | |
32647247 | 576 | return 1; |
715cf83c | 577 | if (total1 == total2) |
32647247 JD |
578 | return 0; |
579 | return -1; | |
580 | } | |
581 | ||
715cf83c | 582 | int sort_by_file_write_desc(const void *pf1, const void *pf2) |
32647247 | 583 | { |
715cf83c PBT |
584 | Quark f1 = *(Quark *)pf1; |
585 | Quark f2 = *(Quark *)pf2; | |
586 | int total1, total2; | |
587 | unsigned long birth1, birth2; | |
588 | unsigned long start1 = i_start; | |
589 | unsigned long start2 = i_start; | |
590 | ||
591 | get_attribute_value_at_ulong(i_end, &f1, "file/birth", birth1); | |
592 | get_attribute_value_at_ulong(i_end, &f2, "file/birth", birth2); | |
593 | if (birth1 > i_start) | |
594 | start1 = birth1; | |
595 | if (birth2 > i_start) | |
596 | start2 = birth2; | |
597 | ||
598 | get_interval_value_int(start1, i_end, &f1, "file/write", total1); | |
599 | get_interval_value_int(start2, i_end, &f2, "file/write", total2); | |
600 | ||
601 | if (total1 > total2) | |
32647247 | 602 | return 1; |
715cf83c | 603 | if (total1 == total2) |
32647247 JD |
604 | return 0; |
605 | return -1; | |
606 | } | |
607 | ||
715cf83c | 608 | int sort_by_file_fd_desc(const void *pf1, const void *pf2) |
32647247 | 609 | { |
715cf83c PBT |
610 | Quark f1 = *(Quark *)pf1; |
611 | Quark f2 = *(Quark *)pf2; | |
612 | int fd1, fd2; | |
32647247 | 613 | |
715cf83c PBT |
614 | get_attribute_value_at_int(i_end, &f1, "file/fd", fd1); |
615 | get_attribute_value_at_int(i_end, &f2, "file/fd", fd2); | |
32647247 | 616 | |
715cf83c | 617 | if (fd1 > fd2) |
32647247 | 618 | return 1; |
715cf83c | 619 | if (fd1 == fd2) |
32647247 JD |
620 | return 0; |
621 | return -1; | |
622 | } | |
623 | ||
715cf83c | 624 | int sort_by_cpu_group_by_threads_desc(const void *pp1, const void *pp2) |
1fc22eb4 | 625 | { |
715cf83c PBT |
626 | Quark p1 = *(Quark *)pp1; |
627 | Quark p2 = *(Quark *)pp2; | |
628 | unsigned long total1, total2; | |
629 | unsigned long birth1, birth2; | |
630 | unsigned long start1 = i_start; | |
631 | unsigned long start2 = i_start; | |
632 | ||
633 | get_attribute_value_at_ulong(i_end, &p1, "birth", birth1); | |
634 | get_attribute_value_at_ulong(i_end, &p2, "birth", birth2); | |
635 | if (birth1 > i_start) | |
636 | start1 = birth1; | |
637 | if (birth2 > i_start) | |
638 | start2 = birth2; | |
639 | ||
640 | get_interval_value_ulong(start1, i_end, &p1, "threadstotalcpunsec", | |
641 | total1); | |
642 | get_interval_value_ulong(start2, i_end, &p2, "threadstotalcpunsec", | |
643 | total2); | |
644 | ||
645 | if (total1 > total2) | |
1fc22eb4 | 646 | return 1; |
715cf83c | 647 | if (total1 == total2) |
1fc22eb4 JD |
648 | return 0; |
649 | return -1; | |
650 | } | |
651 | ||
652 | void update_cputop_display() | |
653 | { | |
715cf83c | 654 | unsigned int i; |
1fc22eb4 | 655 | int header_offset = 2; |
1fc22eb4 JD |
656 | unsigned long elapsed; |
657 | double maxcputime; | |
658 | int nblinedisplayed = 0; | |
659 | int current_line = 0; | |
844d1c9c | 660 | int column; |
715cf83c PBT |
661 | Quark *processes; |
662 | int tid, pid; | |
663 | unsigned long totalcpunsec; | |
664 | std::string comm; | |
665 | ||
666 | Quark cpu_root = state_system->getQuark("cpu"); | |
667 | Quark proc_root = state_system->getQuark("proc"); | |
668 | unsigned int cpu_nb = get_sequence_length(i_end, cpu_root); | |
669 | unsigned int proc_nb = get_sequence_length(i_end, proc_root); | |
670 | ||
671 | elapsed = i_end - i_start; | |
672 | maxcputime = elapsed * cpu_nb / 100.0; | |
1fc22eb4 | 673 | |
715cf83c PBT |
674 | processes = g_new(Quark, proc_nb); |
675 | sequence_to_array(i_end, proc_root, processes, proc_nb); | |
1fc22eb4 | 676 | |
3b15348c | 677 | if (cputopview[0].sort == 1) |
715cf83c | 678 | qsort(processes, proc_nb, sizeof(Quark), sort_by_cpu_desc); |
3b15348c | 679 | else if (cputopview[1].sort == 1) |
715cf83c | 680 | qsort(processes, proc_nb, sizeof(Quark), sort_by_pid_desc); |
3b15348c | 681 | else if (cputopview[2].sort == 1) |
715cf83c | 682 | qsort(processes, proc_nb, sizeof(Quark), sort_by_tid_desc); |
3b15348c | 683 | else if (cputopview[3].sort == 1) |
715cf83c | 684 | qsort(processes, proc_nb, sizeof(Quark), sort_by_cpu_desc); |
3b15348c | 685 | else |
715cf83c | 686 | qsort(processes, proc_nb, sizeof(Quark), sort_by_cpu_desc); |
1fc22eb4 JD |
687 | |
688 | set_window_title(center, "CPU Top"); | |
689 | wattron(center, A_BOLD); | |
844d1c9c JD |
690 | column = 1; |
691 | for (i = 0; i < 4; i++) { | |
41ff0645 | 692 | if (cputopview[i].sort) { |
844d1c9c | 693 | wattron(center, A_UNDERLINE); |
41ff0645 JD |
694 | pref_current_sort = i; |
695 | } | |
844d1c9c JD |
696 | mvwprintw(center, 1, column, cputopview[i].title); |
697 | wattroff(center, A_UNDERLINE); | |
698 | column += 10; | |
699 | } | |
1fc22eb4 JD |
700 | wattroff(center, A_BOLD); |
701 | ||
dc8f04dd | 702 | max_center_lines = LINES - 5 - 7 - 1 - header_offset; |
1fc22eb4 JD |
703 | |
704 | /* iterate the process (thread) list */ | |
715cf83c PBT |
705 | for (i = list_offset; i < proc_nb && nblinedisplayed < max_center_lines; |
706 | i++) { | |
707 | get_attribute_value_at_int(i_end, processes + i, "tid", tid); | |
708 | get_attribute_value_at_int(i_end, processes + i, "pid", pid); | |
709 | ||
710 | if (pid != tid) | |
e15ed00a JD |
711 | if (toggle_threads == -1) |
712 | continue; | |
1fc22eb4 | 713 | |
715cf83c | 714 | if (process_selected(processes[i])) { |
635dc837 | 715 | wattron(center, COLOR_PAIR(6)); |
715cf83c PBT |
716 | mvwhline(center, current_line + header_offset, 1, ' ', |
717 | COLS-3); | |
635dc837 | 718 | } |
1fc22eb4 | 719 | if (current_line == selected_line) { |
715cf83c | 720 | selected_process = processes[i]; |
1fc22eb4 | 721 | wattron(center, COLOR_PAIR(5)); |
715cf83c PBT |
722 | mvwhline(center, current_line + header_offset, 1, ' ', |
723 | COLS-3); | |
1fc22eb4 JD |
724 | } |
725 | /* CPU(%) */ | |
715cf83c PBT |
726 | get_interval_value_ulong(i_start, i_end, processes + i, |
727 | "totalcpunsec", totalcpunsec); | |
1fc22eb4 | 728 | mvwprintw(center, current_line + header_offset, 1, "%1.2f", |
715cf83c | 729 | totalcpunsec / maxcputime); |
1fc22eb4 | 730 | /* PID */ |
715cf83c | 731 | mvwprintw(center, current_line + header_offset, 11, "%d", pid); |
6153ec12 | 732 | /* TID */ |
715cf83c | 733 | mvwprintw(center, current_line + header_offset, 21, "%d", tid); |
1fc22eb4 | 734 | /* NAME */ |
715cf83c PBT |
735 | get_attribute_value_at_string(i_end, processes + i, "comm", |
736 | comm); | |
737 | mvwprintw(center, current_line + header_offset, 31, "%s", | |
738 | comm.c_str()); | |
635dc837 | 739 | wattroff(center, COLOR_PAIR(6)); |
1fc22eb4 JD |
740 | wattroff(center, COLOR_PAIR(5)); |
741 | nblinedisplayed++; | |
742 | current_line++; | |
743 | } | |
715cf83c PBT |
744 | |
745 | g_free(processes); | |
1fc22eb4 JD |
746 | } |
747 | ||
715cf83c | 748 | int sort_perf(const void *pp1, const void *pp2) |
1fc22eb4 | 749 | { |
715cf83c PBT |
750 | Quark p1 = *(Quark *)pp1; |
751 | Quark p2 = *(Quark *)pp2; | |
752 | std::string key = sort_perf_key; | |
753 | int total1; | |
754 | int total2; | |
755 | int tid1; | |
756 | int tid2; | |
1fc22eb4 | 757 | |
715cf83c PBT |
758 | if (!get_attribute_value_at_int(i_end, &p1, "perf/" + key + "/count", |
759 | total1)) | |
760 | total1 = 0; | |
1fc22eb4 | 761 | |
715cf83c PBT |
762 | if (!get_attribute_value_at_int(i_end, &p2, "perf/" + key + "/count", |
763 | total2)) | |
764 | total2 = 0; | |
1fc22eb4 | 765 | |
1fc22eb4 | 766 | |
715cf83c | 767 | if (total1 < total2) |
1fc22eb4 | 768 | return 1; |
715cf83c PBT |
769 | if (total1 == total2) { |
770 | get_attribute_value_at_int(i_end, &p1, "tid", tid1); | |
771 | get_attribute_value_at_int(i_end, &p2, "tid", tid2); | |
772 | if (tid1 < tid2) | |
1fc22eb4 JD |
773 | return 1; |
774 | return -1; | |
775 | } | |
776 | return -1; | |
777 | } | |
778 | ||
715cf83c | 779 | void print_key_title(const char key[], int line) |
1fc22eb4 JD |
780 | { |
781 | wattron(center, A_BOLD); | |
951303cc JD |
782 | mvwprintw(center, line, 1, "%s", key); |
783 | mvwprintw(center, line, 30, " "); | |
1fc22eb4 JD |
784 | wattroff(center, A_BOLD); |
785 | } | |
786 | ||
787 | void update_process_details() | |
788 | { | |
789 | unsigned long elapsed; | |
790 | double maxcputime; | |
715cf83c | 791 | unsigned int i, j = 0; |
69362330 | 792 | char unit[4]; |
97514683 | 793 | char filename_buf[COLS]; |
951303cc | 794 | int line = 1; |
cc30e58d | 795 | int column; |
715cf83c PBT |
796 | unsigned int cpu_nb; |
797 | std::string comm; | |
798 | int tid = -1, pid, ppid, fileread, filewrite; | |
799 | unsigned long totalcpunsec; | |
800 | Quark *global_perf; | |
801 | unsigned int global_perf_nb; | |
802 | std::string key; | |
803 | int count; | |
804 | Quark *files; | |
805 | unsigned int file_nb; | |
806 | int fd, read, write; | |
807 | std::string name; | |
1fc22eb4 JD |
808 | |
809 | set_window_title(center, "Process details"); | |
810 | ||
715cf83c PBT |
811 | elapsed = i_end - i_start; |
812 | cpu_nb = get_sequence_length(i_end, state_system->getQuark("cpu")); | |
813 | maxcputime = elapsed * cpu_nb / 100.0; | |
1fc22eb4 | 814 | |
715cf83c PBT |
815 | get_attribute_value_at_int(i_end, &selected_process, "tid", tid); |
816 | if (tid == -1) { | |
1fc22eb4 JD |
817 | print_key_title("Does not exit at this time", 3); |
818 | return; | |
819 | } | |
820 | ||
715cf83c PBT |
821 | print_key_title("Name", line++); |
822 | get_attribute_value_at_string(i_end, &selected_process, "comm", comm); | |
823 | wprintw(center, "%s", comm.c_str()); | |
824 | print_key_title("TID", line++); | |
825 | wprintw(center, "%d", tid); | |
826 | ||
951303cc | 827 | print_key_title("PID", line++); |
715cf83c PBT |
828 | get_attribute_value_at_int(i_end, &selected_process, "pid", pid); |
829 | wprintw(center, "%d", pid); | |
951303cc | 830 | print_key_title("PPID", line++); |
715cf83c PBT |
831 | get_attribute_value_at_int(i_end, &selected_process, "ppid", ppid); |
832 | wprintw(center, "%d", ppid); | |
951303cc | 833 | print_key_title("CPU", line++); |
715cf83c PBT |
834 | get_attribute_value_at_ulong(i_end, &selected_process, "totalcpunsec", |
835 | totalcpunsec); | |
836 | wprintw(center, "%1.2f %%", totalcpunsec/maxcputime); | |
b093de8a | 837 | |
951303cc | 838 | print_key_title("READ B/s", line++); |
715cf83c PBT |
839 | get_attribute_value_at_int(i_end, &selected_process, "fileread", |
840 | fileread); | |
841 | scale_unit(fileread, unit); | |
69362330 | 842 | wprintw(center, "%s", unit); |
b093de8a | 843 | |
951303cc | 844 | print_key_title("WRITE B/s", line++); |
715cf83c PBT |
845 | get_attribute_value_at_int(i_end, &selected_process, "filewrite", |
846 | filewrite); | |
847 | scale_unit(filewrite, unit); | |
69362330 | 848 | wprintw(center, "%s", unit); |
b093de8a | 849 | |
715cf83c PBT |
850 | |
851 | global_perf_nb = get_global_perf_list_size(i_end); | |
852 | global_perf = g_new(Quark, global_perf_nb); | |
853 | get_global_perf_list(i_end, global_perf, global_perf_nb); | |
854 | for (i = 0; i < global_perf_nb; i++) { | |
855 | get_attribute_value_at_string(i_end, global_perf + i, "key", | |
856 | key); | |
857 | print_key_title(key.c_str(), line++); | |
858 | if (!get_attribute_value_at_int(i_end, global_perf + i, "count", | |
859 | count)) | |
860 | count = 0; | |
861 | wprintw(center, "%d", count); | |
951303cc JD |
862 | } |
863 | line++; | |
864 | ||
93d80d35 | 865 | wattron(center, A_BOLD); |
cc30e58d JD |
866 | column = 1; |
867 | for (i = 0; i < 3; i++) { | |
41ff0645 JD |
868 | if (fileview[i].sort) { |
869 | pref_current_sort = i; | |
cc30e58d | 870 | wattron(center, A_UNDERLINE); |
41ff0645 | 871 | } |
cc30e58d JD |
872 | mvwprintw(center, line, column, fileview[i].title); |
873 | wattroff(center, A_UNDERLINE); | |
874 | column += 10; | |
875 | } | |
876 | mvwprintw(center, line++, column, "FILENAME"); | |
93d80d35 JD |
877 | wattroff(center, A_BOLD); |
878 | ||
715cf83c PBT |
879 | file_nb = get_number_of_opened_files(i_end, selected_process); |
880 | files = g_new(Quark, file_nb); | |
881 | get_opened_files(i_end, selected_process, files, file_nb); | |
32647247 JD |
882 | |
883 | if (fileview[0].sort == 1) | |
715cf83c | 884 | qsort(files, file_nb, sizeof(Quark), sort_by_file_fd_desc); |
32647247 | 885 | else if (fileview[1].sort == 1) |
715cf83c | 886 | qsort(files, file_nb, sizeof(Quark), sort_by_file_read_desc); |
32647247 | 887 | else if (fileview[2].sort == 1) |
715cf83c | 888 | qsort(files, file_nb, sizeof(Quark), sort_by_file_write_desc); |
32647247 | 889 | else |
715cf83c PBT |
890 | qsort(files, file_nb, sizeof(Quark), sort_by_file_fd_desc); |
891 | ||
892 | for (i = selected_line; | |
893 | i < file_nb && i < (selected_line + max_center_lines - line + 2); | |
894 | i++) { | |
895 | get_attribute_value_at_int(i_end, files + i, "fd", fd); | |
896 | mvwprintw(center, line + j, 1, "%d", fd); | |
897 | get_attribute_value_at_int(i_end, files + i, "read", read); | |
898 | scale_unit(read, unit); | |
cc30e58d | 899 | mvwprintw(center, line + j, 11, "%s", unit); |
715cf83c PBT |
900 | get_attribute_value_at_int(i_end, files + i, "write", write); |
901 | scale_unit(write, unit); | |
cc30e58d | 902 | mvwprintw(center, line + j, 21, "%s", unit); |
715cf83c PBT |
903 | get_attribute_value_at_string(i_end, files + i, "name", name); |
904 | snprintf(filename_buf, COLS - 25, "%s", name.c_str()); | |
cc30e58d | 905 | mvwprintw(center, line + j, 31, "%s", filename_buf); |
32647247 | 906 | j++; |
b093de8a | 907 | } |
715cf83c PBT |
908 | g_free(global_perf); |
909 | g_free(files); | |
1fc22eb4 JD |
910 | } |
911 | ||
912 | void update_perf() | |
913 | { | |
715cf83c | 914 | unsigned int i, j; |
1fc22eb4 JD |
915 | int nblinedisplayed = 0; |
916 | int current_line = 0; | |
1fc22eb4 JD |
917 | int header_offset = 2; |
918 | int perf_row = 40; | |
1fc22eb4 | 919 | int value; |
715cf83c PBT |
920 | unsigned int global_perf_nb; |
921 | Quark *global_perf; | |
922 | int sort = 0; | |
923 | int visible = 0; | |
924 | std::string key; | |
925 | bool sort_exists; | |
926 | unsigned int proc_nb; | |
927 | Quark *procs; | |
928 | Quark proc_beg; | |
929 | int tid, pid; | |
930 | std::string comm; | |
1fc22eb4 JD |
931 | |
932 | set_window_title(center, "Perf Top"); | |
933 | wattron(center, A_BOLD); | |
934 | mvwprintw(center, 1, 1, "PID"); | |
935 | mvwprintw(center, 1, 11, "TID"); | |
936 | mvwprintw(center, 1, 22, "NAME"); | |
937 | ||
938 | perf_row = 40; | |
715cf83c PBT |
939 | global_perf_nb = get_global_perf_list_size(i_end); |
940 | global_perf = g_new(Quark, global_perf_nb); | |
941 | get_global_perf_list(i_end, global_perf, global_perf_nb); | |
942 | for (i = 0; i < global_perf_nb; i++) { | |
943 | get_attribute_value_at_int(i_end, global_perf + i, "visible", | |
944 | visible); | |
945 | get_attribute_value_at_string(i_end, global_perf + i, "key", | |
946 | key); | |
947 | sort_exists = get_attribute_value_at_int(i_end, global_perf + i, | |
948 | "sort", sort); | |
949 | if (visible) { | |
950 | if (sort_exists && sort) { | |
41ff0645 | 951 | wattron(center, A_UNDERLINE); |
41ff0645 | 952 | } |
6419078d | 953 | /* + 5 to strip the "perf_" prefix */ |
1fc22eb4 | 954 | mvwprintw(center, 1, perf_row, "%s", |
715cf83c | 955 | key.c_str() + 5); |
41ff0645 | 956 | wattroff(center, A_UNDERLINE); |
1fc22eb4 JD |
957 | perf_row += 20; |
958 | } | |
715cf83c PBT |
959 | if (sort_exists && sort) { |
960 | sort_perf_key = key; | |
1fc22eb4 | 961 | } |
1fc22eb4 JD |
962 | } |
963 | wattroff(center, A_BOLD); | |
964 | ||
715cf83c PBT |
965 | proc_beg = state_system->getQuark("proc"); |
966 | proc_nb = get_sequence_length(i_end, proc_beg); | |
967 | procs = g_new(Quark, proc_nb); | |
968 | sequence_to_array(i_end, proc_beg, procs, proc_nb); | |
969 | for (i = 0; i < proc_nb && nblinedisplayed < max_center_lines; i++) { | |
970 | get_attribute_value_at_int(i_end, procs + i, "tid", tid); | |
971 | get_attribute_value_at_int(i_end, procs + i, "pid", pid); | |
972 | get_attribute_value_at_string(i_end, procs + 1, "comm", comm); | |
85db4618 | 973 | |
715cf83c | 974 | if (pid != tid) |
e15ed00a JD |
975 | if (toggle_threads == -1) |
976 | continue; | |
1fc22eb4 | 977 | |
715cf83c | 978 | if (process_selected(procs[i])) { |
635dc837 | 979 | wattron(center, COLOR_PAIR(6)); |
715cf83c PBT |
980 | mvwhline(center, current_line + header_offset, 1, ' ', |
981 | COLS-3); | |
635dc837 | 982 | } |
1fc22eb4 | 983 | if (current_line == selected_line) { |
715cf83c | 984 | selected_process = procs[i]; |
1fc22eb4 | 985 | wattron(center, COLOR_PAIR(5)); |
715cf83c PBT |
986 | mvwhline(center, current_line + header_offset, 1, ' ', |
987 | COLS-3); | |
1fc22eb4 JD |
988 | } |
989 | ||
715cf83c PBT |
990 | mvwprintw(center, current_line + header_offset, 1, "%d", pid); |
991 | mvwprintw(center, current_line + header_offset, 11, "%d", tid); | |
992 | mvwprintw(center, current_line + header_offset, 22, "%s", | |
993 | comm.c_str()); | |
1fc22eb4 JD |
994 | |
995 | perf_row = 40; | |
715cf83c PBT |
996 | for (j = 0; j < global_perf_nb; j++) { |
997 | get_attribute_value_at_int(i_end, global_perf + j, | |
998 | "visible", visible); | |
999 | get_attribute_value_at_string(i_end, global_perf + j, | |
1000 | "key", key); | |
1001 | ||
1002 | if (visible) { | |
1003 | if (!get_interval_value_int(i_start, i_end, | |
1004 | procs + i, "perf/" + | |
1005 | key + "/count", | |
1006 | value)) { | |
1fc22eb4 | 1007 | value = 0; |
715cf83c | 1008 | } |
b093de8a | 1009 | mvwprintw(center, current_line + header_offset, |
715cf83c | 1010 | perf_row, "%d", value); |
1fc22eb4 JD |
1011 | perf_row += 20; |
1012 | } | |
1fc22eb4 JD |
1013 | } |
1014 | ||
635dc837 | 1015 | wattroff(center, COLOR_PAIR(6)); |
1fc22eb4 JD |
1016 | wattroff(center, COLOR_PAIR(5)); |
1017 | nblinedisplayed++; | |
1018 | current_line++; | |
1019 | } | |
715cf83c PBT |
1020 | g_free(global_perf); |
1021 | g_free(procs); | |
1fc22eb4 JD |
1022 | } |
1023 | ||
1fc22eb4 JD |
1024 | void update_iostream() |
1025 | { | |
715cf83c | 1026 | unsigned int i; |
1fc22eb4 | 1027 | int header_offset = 2; |
1fc22eb4 JD |
1028 | int nblinedisplayed = 0; |
1029 | int current_line = 0; | |
69362330 | 1030 | char unit[4]; |
41f5890b | 1031 | int column; |
715cf83c PBT |
1032 | unsigned int proc_nb; |
1033 | Quark *procs; | |
1034 | Quark proc_root; | |
1035 | int pid, tid, read, write, totalread, totalwrite; | |
1036 | std::string comm; | |
1fc22eb4 JD |
1037 | |
1038 | set_window_title(center, "IO Top"); | |
1039 | wattron(center, A_BOLD); | |
69362330 JD |
1040 | mvwprintw(center, 1, 1, "PID"); |
1041 | mvwprintw(center, 1, 11, "TID"); | |
1042 | mvwprintw(center, 1, 22, "NAME"); | |
41f5890b JD |
1043 | column = 40; |
1044 | for (i = 0; i < 3; i++) { | |
41ff0645 JD |
1045 | if (iostreamtopview[i].sort) { |
1046 | pref_current_sort = i; | |
41f5890b | 1047 | wattron(center, A_UNDERLINE); |
41ff0645 | 1048 | } |
41f5890b JD |
1049 | mvwprintw(center, 1, column, iostreamtopview[i].title); |
1050 | wattroff(center, A_UNDERLINE); | |
1051 | column += 12; | |
1052 | } | |
1fc22eb4 | 1053 | wattroff(center, A_BOLD); |
41f5890b | 1054 | wattroff(center, A_UNDERLINE); |
1fc22eb4 | 1055 | |
715cf83c PBT |
1056 | proc_root = state_system->getQuark("proc"); |
1057 | proc_nb = get_sequence_length(i_end, proc_root); | |
1058 | procs = g_new(Quark, proc_nb); | |
1059 | sequence_to_array(i_end, proc_root, procs, proc_nb); | |
1060 | ||
89f1e0d1 | 1061 | if (iostreamtopview[0].sort == 1) |
715cf83c | 1062 | qsort(procs, proc_nb, sizeof(Quark), sort_by_process_read_desc); |
89f1e0d1 | 1063 | else if (iostreamtopview[1].sort == 1) |
715cf83c PBT |
1064 | qsort(procs, proc_nb, sizeof(Quark), |
1065 | sort_by_process_write_desc); | |
89f1e0d1 | 1066 | else if (iostreamtopview[2].sort == 1) |
715cf83c PBT |
1067 | qsort(procs, proc_nb, sizeof(Quark), |
1068 | sort_by_process_total_desc); | |
89f1e0d1 | 1069 | else |
715cf83c PBT |
1070 | qsort(procs, proc_nb, sizeof(Quark), |
1071 | sort_by_process_total_desc); | |
1072 | ||
1073 | for (i = list_offset; i < proc_nb && nblinedisplayed < max_center_lines; | |
1074 | i++) { | |
1075 | get_attribute_value_at_int(i_end, procs + i, "tid", tid); | |
1076 | get_attribute_value_at_int(i_end, procs + i, "pid", pid); | |
1077 | get_attribute_value_at_string(i_end, procs + i, "comm", comm); | |
1078 | get_attribute_value_at_int(i_end, procs + i, "fileread", | |
1079 | read); | |
1080 | get_attribute_value_at_int(i_end, procs + i, "filewrite", | |
1081 | write); | |
1082 | get_attribute_value_at_int(i_end, procs + i, "totalfileread", | |
1083 | totalread); | |
1084 | get_attribute_value_at_int(i_end, procs + i, "totalfilewrite", | |
1085 | totalwrite); | |
1086 | ||
1087 | ||
1088 | if (pid != tid) | |
e15ed00a JD |
1089 | if (toggle_threads == -1) |
1090 | continue; | |
1fc22eb4 | 1091 | |
715cf83c | 1092 | if (process_selected(procs[i])) { |
635dc837 | 1093 | wattron(center, COLOR_PAIR(6)); |
715cf83c PBT |
1094 | mvwhline(center, current_line + header_offset, 1, ' ', |
1095 | COLS-3); | |
635dc837 | 1096 | } |
1fc22eb4 | 1097 | if (current_line == selected_line) { |
715cf83c | 1098 | selected_process = procs[i]; |
1fc22eb4 | 1099 | wattron(center, COLOR_PAIR(5)); |
715cf83c PBT |
1100 | mvwhline(center, current_line + header_offset, 1, ' ', |
1101 | COLS-3); | |
1fc22eb4 | 1102 | } |
69362330 | 1103 | /* PID */ |
715cf83c PBT |
1104 | mvwprintw(center, current_line + header_offset, 1, "%d", pid); |
1105 | /* TID */ | |
1106 | mvwprintw(center, current_line + header_offset, 11, "%d", tid); | |
69362330 | 1107 | /* NAME */ |
715cf83c PBT |
1108 | mvwprintw(center, current_line + header_offset, 22, "%s", |
1109 | comm.c_str()); | |
b093de8a | 1110 | |
1fc22eb4 | 1111 | /* READ (bytes/sec) */ |
715cf83c | 1112 | scale_unit(read, unit); |
69362330 | 1113 | mvwprintw(center, current_line + header_offset, 40, "%s", unit); |
1fc22eb4 JD |
1114 | |
1115 | /* WRITE (bytes/sec) */ | |
715cf83c | 1116 | scale_unit(write, unit); |
69362330 | 1117 | mvwprintw(center, current_line + header_offset, 52, "%s", unit); |
1fc22eb4 JD |
1118 | |
1119 | /* TOTAL STREAM */ | |
715cf83c | 1120 | scale_unit(totalread + totalwrite, unit); |
69362330 | 1121 | mvwprintw(center, current_line + header_offset, 64, "%s", unit); |
b093de8a | 1122 | |
635dc837 | 1123 | wattroff(center, COLOR_PAIR(6)); |
1fc22eb4 JD |
1124 | wattroff(center, COLOR_PAIR(5)); |
1125 | nblinedisplayed++; | |
1126 | current_line++; | |
1127 | } | |
715cf83c | 1128 | g_free(procs); |
1fc22eb4 JD |
1129 | } |
1130 | ||
1131 | void update_current_view() | |
1132 | { | |
1133 | sem_wait(&update_display_sem); | |
1fc22eb4 JD |
1134 | update_header(); |
1135 | ||
1136 | werase(center); | |
1137 | box(center, 0, 0); | |
1138 | switch (current_view) { | |
1139 | case cpu: | |
1140 | update_cputop_display(); | |
1141 | break; | |
1142 | case perf: | |
1143 | update_perf(); | |
1144 | break; | |
1145 | case process_details: | |
1146 | update_process_details(); | |
1147 | break; | |
1fc22eb4 JD |
1148 | case iostream: |
1149 | update_iostream(); | |
1150 | break; | |
1151 | case tree: | |
1152 | update_cputop_display(); | |
1153 | break; | |
1154 | default: | |
1155 | break; | |
1156 | } | |
1157 | update_panels(); | |
1158 | doupdate(); | |
1159 | sem_post(&update_display_sem); | |
1160 | } | |
1161 | ||
41ff0645 JD |
1162 | void update_process_detail_sort(int *line_selected) |
1163 | { | |
1164 | int i; | |
1165 | int size; | |
1166 | ||
1167 | size = 3; | |
1168 | ||
1169 | if (*line_selected > (size - 1)) | |
1170 | *line_selected = size - 1; | |
1171 | else if (*line_selected < 0) | |
1172 | *line_selected = 0; | |
1173 | ||
1174 | if (fileview[*line_selected].sort == 1) | |
1175 | fileview[*line_selected].reverse = 1; | |
1176 | for (i = 0; i < size; i++) | |
1177 | fileview[i].sort = 0; | |
1178 | fileview[*line_selected].sort = 1; | |
1179 | } | |
1180 | ||
32647247 JD |
1181 | void update_process_detail_pref(int *line_selected, int toggle_view, int toggle_sort) |
1182 | { | |
1183 | int i; | |
1184 | int size; | |
1185 | ||
32647247 JD |
1186 | if (pref_panel_window) { |
1187 | del_panel(pref_panel); | |
1188 | delwin(pref_panel_window); | |
1189 | } | |
1190 | size = 3; | |
1191 | ||
1192 | pref_panel_window = create_window(size + 2, 30, 10, 10); | |
1193 | pref_panel = new_panel(pref_panel_window); | |
1194 | ||
1195 | werase(pref_panel_window); | |
1196 | box(pref_panel_window, 0 , 0); | |
1197 | set_window_title(pref_panel_window, "Process Detail Preferences "); | |
1198 | wattron(pref_panel_window, A_BOLD); | |
1199 | mvwprintw(pref_panel_window, size + 1, 1, | |
d2fd8c70 | 1200 | " 's' : sort, space : toggle"); |
32647247 JD |
1201 | wattroff(pref_panel_window, A_BOLD); |
1202 | ||
1203 | if (*line_selected > (size - 1)) | |
1204 | *line_selected = size - 1; | |
41ff0645 JD |
1205 | else if (*line_selected < 0) |
1206 | *line_selected = 0; | |
32647247 | 1207 | if (toggle_sort == 1) { |
41ff0645 | 1208 | update_process_detail_sort(line_selected); |
32647247 JD |
1209 | update_current_view(); |
1210 | } | |
1211 | ||
1212 | for (i = 0; i < size; i++) { | |
1213 | if (i == *line_selected) { | |
1214 | wattron(pref_panel_window, COLOR_PAIR(5)); | |
1215 | mvwhline(pref_panel_window, i + 1, 1, ' ', 30 - 2); | |
1216 | } | |
1217 | if (fileview[i].sort == 1) | |
1218 | wattron(pref_panel_window, A_BOLD); | |
d33aae69 | 1219 | mvwprintw(pref_panel_window, i + 1, 1, "[-] %s", |
32647247 JD |
1220 | fileview[i].title); |
1221 | wattroff(pref_panel_window, A_BOLD); | |
1222 | wattroff(pref_panel_window, COLOR_PAIR(5)); | |
1223 | ||
1224 | } | |
1225 | update_panels(); | |
1226 | doupdate(); | |
1227 | } | |
1228 | ||
41ff0645 JD |
1229 | void update_iostream_sort(int *line_selected) |
1230 | { | |
1231 | int i; | |
1232 | int size; | |
1233 | ||
1234 | size = 3; | |
1235 | if (*line_selected > (size - 1)) | |
1236 | *line_selected = size - 1; | |
1237 | else if (*line_selected < 0) | |
1238 | *line_selected = 0; | |
1239 | if (iostreamtopview[*line_selected].sort == 1) | |
1240 | iostreamtopview[*line_selected].reverse = 1; | |
1241 | for (i = 0; i < size; i++) | |
1242 | iostreamtopview[i].sort = 0; | |
1243 | iostreamtopview[*line_selected].sort = 1; | |
1244 | ||
1245 | } | |
1246 | ||
89f1e0d1 JD |
1247 | void update_iostream_pref(int *line_selected, int toggle_view, int toggle_sort) |
1248 | { | |
1249 | int i; | |
1250 | int size; | |
1251 | ||
89f1e0d1 JD |
1252 | if (pref_panel_window) { |
1253 | del_panel(pref_panel); | |
1254 | delwin(pref_panel_window); | |
1255 | } | |
1256 | size = 3; | |
1257 | ||
1258 | pref_panel_window = create_window(size + 2, 30, 10, 10); | |
1259 | pref_panel = new_panel(pref_panel_window); | |
1260 | ||
1261 | werase(pref_panel_window); | |
1262 | box(pref_panel_window, 0 , 0); | |
1263 | set_window_title(pref_panel_window, "IOTop Preferences "); | |
1264 | wattron(pref_panel_window, A_BOLD); | |
1265 | mvwprintw(pref_panel_window, size + 1, 1, | |
d2fd8c70 | 1266 | " 's' : sort, space : toggle"); |
89f1e0d1 JD |
1267 | wattroff(pref_panel_window, A_BOLD); |
1268 | ||
1269 | if (*line_selected > (size - 1)) | |
1270 | *line_selected = size - 1; | |
41ff0645 JD |
1271 | else if (*line_selected < 0) |
1272 | *line_selected = 0; | |
89f1e0d1 | 1273 | if (toggle_sort == 1) { |
41ff0645 | 1274 | update_iostream_sort(line_selected); |
89f1e0d1 JD |
1275 | update_current_view(); |
1276 | } | |
1277 | ||
1278 | for (i = 0; i < size; i++) { | |
1279 | if (i == *line_selected) { | |
1280 | wattron(pref_panel_window, COLOR_PAIR(5)); | |
1281 | mvwhline(pref_panel_window, i + 1, 1, ' ', 30 - 2); | |
1282 | } | |
1283 | if (iostreamtopview[i].sort == 1) | |
1284 | wattron(pref_panel_window, A_BOLD); | |
d33aae69 | 1285 | mvwprintw(pref_panel_window, i + 1, 1, "[-] %s", |
89f1e0d1 JD |
1286 | iostreamtopview[i].title); |
1287 | wattroff(pref_panel_window, A_BOLD); | |
1288 | wattroff(pref_panel_window, COLOR_PAIR(5)); | |
1289 | ||
1290 | } | |
1291 | update_panels(); | |
1292 | doupdate(); | |
1293 | } | |
1294 | ||
41ff0645 JD |
1295 | void update_cpu_sort(int *line_selected) |
1296 | { | |
1297 | int i; | |
1298 | int size = 3; | |
1299 | ||
1300 | if (*line_selected > (size - 1)) | |
1301 | *line_selected = size - 1; | |
1302 | else if (*line_selected < 0) | |
1303 | *line_selected = 0; | |
1304 | ||
1305 | /* special case, we don't support sorting by procname for now */ | |
1306 | if (*line_selected != 3) { | |
1307 | if (cputopview[*line_selected].sort == 1) | |
1308 | cputopview[*line_selected].reverse = 1; | |
1309 | for (i = 0; i < size; i++) | |
1310 | cputopview[i].sort = 0; | |
1311 | cputopview[*line_selected].sort = 1; | |
1312 | } | |
1313 | } | |
1314 | ||
3b15348c JD |
1315 | void update_cpu_pref(int *line_selected, int toggle_view, int toggle_sort) |
1316 | { | |
1317 | int i; | |
1318 | int size; | |
1319 | ||
3b15348c JD |
1320 | if (pref_panel_window) { |
1321 | del_panel(pref_panel); | |
1322 | delwin(pref_panel_window); | |
1323 | } | |
1324 | size = 4; | |
1325 | ||
1326 | pref_panel_window = create_window(size + 2, 30, 10, 10); | |
1327 | pref_panel = new_panel(pref_panel_window); | |
1328 | ||
1329 | werase(pref_panel_window); | |
1330 | box(pref_panel_window, 0 , 0); | |
1331 | set_window_title(pref_panel_window, "CPUTop Preferences "); | |
1332 | wattron(pref_panel_window, A_BOLD); | |
1333 | mvwprintw(pref_panel_window, size + 1, 1, | |
d2fd8c70 | 1334 | " 's' : sort, space : toggle"); |
3b15348c JD |
1335 | wattroff(pref_panel_window, A_BOLD); |
1336 | ||
89f1e0d1 JD |
1337 | if (*line_selected > (size - 1)) |
1338 | *line_selected = size - 1; | |
41ff0645 JD |
1339 | else if (*line_selected < 0) |
1340 | *line_selected = 0; | |
3b15348c | 1341 | if (toggle_sort == 1) { |
41ff0645 JD |
1342 | update_cpu_sort(line_selected); |
1343 | update_current_view(); | |
3b15348c JD |
1344 | } |
1345 | ||
89f1e0d1 | 1346 | for (i = 0; i < size; i++) { |
3b15348c JD |
1347 | if (i == *line_selected) { |
1348 | wattron(pref_panel_window, COLOR_PAIR(5)); | |
1349 | mvwhline(pref_panel_window, i + 1, 1, ' ', 30 - 2); | |
1350 | } | |
1351 | if (cputopview[i].sort == 1) | |
1352 | wattron(pref_panel_window, A_BOLD); | |
d33aae69 | 1353 | mvwprintw(pref_panel_window, i + 1, 1, "[-] %s", |
3b15348c JD |
1354 | cputopview[i].title); |
1355 | wattroff(pref_panel_window, A_BOLD); | |
1356 | wattroff(pref_panel_window, COLOR_PAIR(5)); | |
1357 | ||
1358 | } | |
1359 | update_panels(); | |
1360 | doupdate(); | |
1361 | } | |
1362 | ||
41ff0645 JD |
1363 | void update_perf_sort(int *line_selected) |
1364 | { | |
1365 | int i; | |
41ff0645 | 1366 | int size; |
715cf83c PBT |
1367 | Quark *global_perf; |
1368 | ||
1369 | size = get_global_perf_list_size(i_end); | |
1370 | global_perf = g_new(Quark, size); | |
1371 | get_global_perf_list(i_end, global_perf, size); | |
41ff0645 | 1372 | |
41ff0645 JD |
1373 | if (*line_selected > (size - 1)) |
1374 | *line_selected = size - 1; | |
1375 | else if (*line_selected < 0) | |
1376 | *line_selected = 0; | |
1377 | ||
715cf83c | 1378 | for (i = 0; i < size; i++) { |
41ff0645 | 1379 | if (i != *line_selected) |
715cf83c | 1380 | modify_attribute(i_end, global_perf + i, "sort", 0); |
41ff0645 | 1381 | else |
715cf83c | 1382 | modify_attribute(i_end, global_perf + i, "sort", 1); |
41ff0645 | 1383 | } |
715cf83c PBT |
1384 | |
1385 | g_free(global_perf); | |
41ff0645 JD |
1386 | } |
1387 | ||
3b15348c | 1388 | void update_perf_pref(int *line_selected, int toggle_view, int toggle_sort) |
1fc22eb4 | 1389 | { |
1e05f0ae | 1390 | int i; |
1fc22eb4 | 1391 | int size; |
715cf83c PBT |
1392 | Quark *global_perf; |
1393 | int visible; | |
1394 | int sort; | |
1395 | std::string key; | |
1e05f0ae | 1396 | |
0d91c12a JD |
1397 | if (pref_panel_window) { |
1398 | del_panel(pref_panel); | |
1399 | delwin(pref_panel_window); | |
1fc22eb4 | 1400 | } |
715cf83c PBT |
1401 | |
1402 | size = get_global_perf_list_size(i_end); | |
1403 | global_perf = g_new(Quark, size); | |
1404 | get_global_perf_list(i_end, global_perf, size); | |
1e05f0ae | 1405 | |
0d91c12a JD |
1406 | pref_panel_window = create_window(size + 2, 30, 10, 10); |
1407 | pref_panel = new_panel(pref_panel_window); | |
1fc22eb4 | 1408 | |
0d91c12a JD |
1409 | werase(pref_panel_window); |
1410 | box(pref_panel_window, 0 , 0); | |
1411 | set_window_title(pref_panel_window, "Perf Preferences "); | |
1412 | wattron(pref_panel_window, A_BOLD); | |
715cf83c | 1413 | mvwprintw(pref_panel_window, size + 1, 1, |
d2fd8c70 | 1414 | " 's' : sort, space : toggle"); |
0d91c12a | 1415 | wattroff(pref_panel_window, A_BOLD); |
1fc22eb4 | 1416 | |
41ff0645 JD |
1417 | if (*line_selected > (size - 1)) |
1418 | *line_selected = size - 1; | |
1419 | else if (*line_selected < 0) | |
1420 | *line_selected = 0; | |
1421 | ||
1fc22eb4 | 1422 | if (toggle_sort == 1) { |
41ff0645 | 1423 | update_perf_sort(line_selected); |
1fc22eb4 JD |
1424 | update_current_view(); |
1425 | } | |
1426 | ||
715cf83c PBT |
1427 | for (i = 0; i < size; i++) { |
1428 | get_attribute_value_at_int(i_end, global_perf + i, | |
1429 | "visible", visible); | |
1430 | get_attribute_value_at_string(i_end, global_perf + i, "key", | |
1431 | key); | |
3b15348c | 1432 | if (i == *line_selected && toggle_view == 1) { |
715cf83c PBT |
1433 | visible = visible == 1 ? 0 : 1; |
1434 | modify_attribute(i_end, global_perf + i, "visible", | |
1435 | visible); | |
1fc22eb4 JD |
1436 | update_current_view(); |
1437 | } | |
3b15348c | 1438 | if (i == *line_selected) { |
0d91c12a JD |
1439 | wattron(pref_panel_window, COLOR_PAIR(5)); |
1440 | mvwhline(pref_panel_window, i + 1, 1, ' ', 30 - 2); | |
1fc22eb4 | 1441 | } |
715cf83c PBT |
1442 | |
1443 | if (get_attribute_value_at_int(i_end, global_perf + 1, "sort", | |
1444 | sort) && sort) { | |
0d91c12a | 1445 | wattron(pref_panel_window, A_BOLD); |
715cf83c | 1446 | } |
0d91c12a | 1447 | mvwprintw(pref_panel_window, i + 1, 1, "[%c] %s", |
715cf83c | 1448 | visible == 1 ? 'x' : ' ', key.c_str() + 5); |
0d91c12a JD |
1449 | wattroff(pref_panel_window, A_BOLD); |
1450 | wattroff(pref_panel_window, COLOR_PAIR(5)); | |
1fc22eb4 JD |
1451 | } |
1452 | update_panels(); | |
1453 | doupdate(); | |
715cf83c PBT |
1454 | |
1455 | g_free(global_perf); | |
1fc22eb4 JD |
1456 | } |
1457 | ||
3b15348c | 1458 | int update_preference_panel(int *line_selected, int toggle_view, int toggle_sort) |
1fc22eb4 | 1459 | { |
1e05f0ae JD |
1460 | int ret = 0; |
1461 | ||
0d91c12a JD |
1462 | switch(current_view) { |
1463 | case perf: | |
3b15348c JD |
1464 | update_perf_pref(line_selected, toggle_view, toggle_sort); |
1465 | break; | |
1466 | case cpu: | |
1467 | update_cpu_pref(line_selected, toggle_view, toggle_sort); | |
0d91c12a | 1468 | break; |
89f1e0d1 JD |
1469 | case iostream: |
1470 | update_iostream_pref(line_selected, toggle_view, toggle_sort); | |
1471 | break; | |
32647247 JD |
1472 | case process_details: |
1473 | update_process_detail_pref(line_selected, toggle_view, toggle_sort); | |
1474 | break; | |
0d91c12a | 1475 | default: |
1e05f0ae | 1476 | ret = -1; |
0d91c12a JD |
1477 | break; |
1478 | } | |
1e05f0ae JD |
1479 | |
1480 | return ret; | |
0d91c12a JD |
1481 | } |
1482 | ||
41ff0645 JD |
1483 | int update_sort(int *line_selected) |
1484 | { | |
1485 | int ret = 0; | |
1486 | ||
1487 | switch(current_view) { | |
1488 | case perf: | |
1489 | update_perf_sort(line_selected); | |
1490 | break; | |
1491 | case cpu: | |
1492 | update_cpu_sort(line_selected); | |
1493 | break; | |
1494 | case iostream: | |
1495 | update_iostream_sort(line_selected); | |
1496 | break; | |
1497 | case process_details: | |
1498 | update_process_detail_sort(line_selected); | |
1499 | break; | |
1500 | default: | |
1501 | ret = -1; | |
1502 | break; | |
1503 | } | |
1504 | ||
1505 | return ret; | |
1506 | } | |
1507 | ||
1508 | ||
0d91c12a JD |
1509 | void toggle_pref_panel(void) |
1510 | { | |
1e05f0ae JD |
1511 | int ret; |
1512 | ||
0d91c12a JD |
1513 | if (pref_panel_visible) { |
1514 | hide_panel(pref_panel); | |
1515 | pref_panel_visible = 0; | |
1fc22eb4 | 1516 | } else { |
3b15348c | 1517 | ret = update_preference_panel(&pref_line_selected, 0, 0); |
1e05f0ae JD |
1518 | if (ret < 0) |
1519 | return; | |
0d91c12a JD |
1520 | show_panel(pref_panel); |
1521 | pref_panel_visible = 1; | |
1fc22eb4 JD |
1522 | } |
1523 | update_panels(); | |
1524 | doupdate(); | |
1525 | } | |
1526 | ||
715cf83c | 1527 | void display() |
1fc22eb4 | 1528 | { |
715cf83c PBT |
1529 | if (i_start == 0) |
1530 | i_start = first_display_update; | |
1531 | else | |
1532 | i_start += refresh_display; | |
1533 | i_end = i_start + refresh_display; | |
1534 | ||
1535 | max_elements = get_sequence_length( | |
1536 | i_end, state_system->getQuark("proc")); | |
1fc22eb4 JD |
1537 | update_current_view(); |
1538 | update_footer(); | |
1539 | update_panels(); | |
1540 | doupdate(); | |
1541 | } | |
1542 | ||
1543 | void pause_display() | |
1544 | { | |
1545 | toggle_pause = 1; | |
1546 | print_log("Pause"); | |
1547 | sem_wait(&pause_sem); | |
1548 | } | |
1549 | ||
1550 | void resume_display() | |
1551 | { | |
1552 | toggle_pause = -1; | |
1553 | print_log("Resume"); | |
1554 | sem_post(&pause_sem); | |
1555 | } | |
1556 | ||
1557 | void *handle_keyboard(void *p) | |
1558 | { | |
1559 | int ch; | |
1560 | while((ch = getch())) { | |
1561 | switch(ch) { | |
1562 | /* Move the cursor and scroll */ | |
8c05e516 | 1563 | case 'j': |
1fc22eb4 | 1564 | case KEY_DOWN: |
0d91c12a | 1565 | if (pref_panel_visible) { |
3b15348c JD |
1566 | pref_line_selected++; |
1567 | update_preference_panel(&pref_line_selected, 0, 0); | |
1fc22eb4 JD |
1568 | } else { |
1569 | if (selected_line < (max_center_lines - 1) && | |
1570 | selected_line < max_elements - 1) { | |
1571 | selected_line++; | |
1572 | selected_in_list++; | |
1573 | } else if (selected_in_list < (max_elements - 1) | |
1574 | && (list_offset < (max_elements - max_center_lines))) { | |
1575 | selected_in_list++; | |
1576 | list_offset++; | |
1577 | } | |
1578 | update_current_view(); | |
1579 | } | |
1580 | break; | |
1581 | case KEY_NPAGE: | |
1fc22eb4 | 1582 | break; |
8c05e516 | 1583 | case 'k': |
1fc22eb4 | 1584 | case KEY_UP: |
0d91c12a | 1585 | if (pref_panel_visible) { |
3b15348c JD |
1586 | if (pref_line_selected > 0) |
1587 | pref_line_selected--; | |
1588 | update_preference_panel(&pref_line_selected, 0, 0); | |
1fc22eb4 JD |
1589 | } else { |
1590 | if (selected_line > 0) { | |
1591 | selected_line--; | |
1592 | selected_in_list--; | |
1593 | } else if (selected_in_list > 0 && list_offset > 0) { | |
1594 | selected_in_list--; | |
1595 | list_offset--; | |
1596 | } | |
1597 | update_current_view(); | |
1598 | } | |
1599 | break; | |
1600 | case KEY_PPAGE: | |
1fc22eb4 JD |
1601 | break; |
1602 | ||
1603 | /* Navigate the history with arrows */ | |
1604 | case KEY_LEFT: | |
715cf83c PBT |
1605 | if ((i_start - refresh_display) >= |
1606 | first_display_update) { | |
1607 | i_start -= refresh_display; | |
1608 | i_end = i_start + refresh_display; | |
1fc22eb4 JD |
1609 | print_log("Going back in time"); |
1610 | } else { | |
1611 | print_log("Cannot rewind, last data is already displayed"); | |
1612 | } | |
715cf83c PBT |
1613 | max_elements = get_sequence_length( |
1614 | i_end, state_system->getQuark("proc")); | |
1fc22eb4 JD |
1615 | |
1616 | /* we force to pause the display when moving in time */ | |
1617 | if (toggle_pause < 0) | |
1618 | pause_display(); | |
1619 | ||
1620 | update_current_view(); | |
1621 | update_footer(); | |
1622 | break; | |
1623 | case KEY_RIGHT: | |
715cf83c PBT |
1624 | if ((i_end + refresh_display) <= |
1625 | last_display_update) { | |
1626 | i_end += refresh_display; | |
1627 | i_start = i_end - refresh_display; | |
1628 | print_log("Going forward in time"); | |
1629 | max_elements = get_sequence_length( | |
1630 | i_end, state_system->getQuark( | |
1631 | "proc")); | |
1632 | update_current_view(); | |
1633 | update_footer(); | |
1fc22eb4 JD |
1634 | } else { |
1635 | print_log("Manually moving forward"); | |
1636 | sem_post(&timer); | |
3e59e768 JD |
1637 | if (toggle_pause > 0) { |
1638 | sem_post(&pause_sem); | |
1639 | update_current_view(); | |
1640 | sem_wait(&pause_sem); | |
1641 | } | |
1fc22eb4 JD |
1642 | } |
1643 | ||
1644 | break; | |
1645 | case ' ': | |
0d91c12a | 1646 | if (pref_panel_visible) { |
3b15348c | 1647 | update_preference_panel(&pref_line_selected, 1, 0); |
635dc837 JD |
1648 | } else { |
1649 | update_selected_processes(); | |
1650 | update_current_view(); | |
1651 | } | |
1fc22eb4 JD |
1652 | break; |
1653 | case 's': | |
0d91c12a | 1654 | if (pref_panel_visible) |
3b15348c | 1655 | update_preference_panel(&pref_line_selected, 0, 1); |
1fc22eb4 | 1656 | break; |
41ff0645 | 1657 | case '>': |
bc958efa JD |
1658 | /* perf uses a hashtable, it is ordered backward */ |
1659 | if (current_view == perf) { | |
1660 | pref_current_sort--; | |
1661 | } else if (!pref_panel_visible) { | |
41ff0645 | 1662 | pref_current_sort++; |
41ff0645 | 1663 | } |
bc958efa JD |
1664 | update_sort(&pref_current_sort); |
1665 | update_current_view(); | |
41ff0645 JD |
1666 | break; |
1667 | case '<': | |
bc958efa JD |
1668 | /* perf uses a hashtable, it is ordered backward */ |
1669 | if (current_view == perf) { | |
1670 | pref_current_sort++; | |
1671 | } else if (!pref_panel_visible) { | |
1672 | pref_current_sort--; | |
41ff0645 | 1673 | } |
bc958efa JD |
1674 | update_sort(&pref_current_sort); |
1675 | update_current_view(); | |
41ff0645 | 1676 | break; |
1fc22eb4 JD |
1677 | |
1678 | case 13: /* FIXME : KEY_ENTER ?? */ | |
d2fd8c70 JD |
1679 | if (pref_panel_visible) |
1680 | break; | |
041aa219 JD |
1681 | if (current_view != process_details) { |
1682 | previous_view = current_view; | |
1fc22eb4 | 1683 | current_view = process_details; |
041aa219 JD |
1684 | } else { |
1685 | current_view = previous_view; | |
1686 | previous_view = process_details; | |
1fc22eb4 JD |
1687 | } |
1688 | update_current_view(); | |
1689 | break; | |
1690 | ||
1691 | case KEY_F(1): | |
3b15348c JD |
1692 | if (pref_panel_visible) |
1693 | toggle_pref_panel(); | |
1fc22eb4 | 1694 | current_view = cpu; |
af54ebcf | 1695 | selected_line = 0; |
1fc22eb4 JD |
1696 | update_current_view(); |
1697 | break; | |
1698 | case KEY_F(2): | |
3b15348c JD |
1699 | if (pref_panel_visible) |
1700 | toggle_pref_panel(); | |
1fc22eb4 | 1701 | current_view = cpu; |
af54ebcf | 1702 | selected_line = 0; |
1fc22eb4 JD |
1703 | update_current_view(); |
1704 | break; | |
1705 | case KEY_F(3): | |
3b15348c JD |
1706 | if (pref_panel_visible) |
1707 | toggle_pref_panel(); | |
1fc22eb4 | 1708 | current_view = perf; |
af54ebcf | 1709 | selected_line = 0; |
1fc22eb4 JD |
1710 | update_current_view(); |
1711 | break; | |
1712 | case KEY_F(4): | |
3b15348c JD |
1713 | if (pref_panel_visible) |
1714 | toggle_pref_panel(); | |
1fc22eb4 | 1715 | current_view = iostream; |
af54ebcf | 1716 | selected_line = 0; |
1fc22eb4 JD |
1717 | update_current_view(); |
1718 | break; | |
1719 | case KEY_F(10): | |
1720 | case 'q': | |
1721 | reset_ncurses(); | |
1722 | break; | |
1723 | case 't': | |
1724 | toggle_threads *= -1; | |
1725 | update_current_view(); | |
1726 | break; | |
1727 | case 'p': | |
1728 | if (toggle_pause < 0) { | |
1729 | pause_display(); | |
1730 | } else { | |
1731 | resume_display(); | |
1732 | } | |
1733 | break; | |
f9ff6939 | 1734 | case 'r': |
0d91c12a | 1735 | toggle_pref_panel(); |
1fc22eb4 | 1736 | break; |
d2fd8c70 JD |
1737 | /* ESCAPE, but slow to process, don't know why */ |
1738 | case 27: | |
1739 | if (pref_panel_visible) | |
1740 | toggle_pref_panel(); | |
1741 | else if (current_view == process_details) { | |
1742 | current_view = previous_view; | |
1743 | previous_view = process_details; | |
1744 | } | |
1745 | update_current_view(); | |
1746 | break; | |
1fc22eb4 | 1747 | default: |
715cf83c | 1748 | update_current_view(); |
1fc22eb4 JD |
1749 | break; |
1750 | } | |
1751 | update_footer(); | |
1752 | } | |
1753 | return NULL; | |
1754 | } | |
1755 | ||
89f1e0d1 JD |
1756 | void init_view_headers() |
1757 | { | |
1758 | cputopview[0].title = strdup("CPU(%)"); | |
1759 | cputopview[0].sort = 1; | |
6153ec12 JD |
1760 | cputopview[1].title = strdup("PID"); |
1761 | cputopview[2].title = strdup("TID"); | |
89f1e0d1 JD |
1762 | cputopview[3].title = strdup("NAME"); |
1763 | ||
1764 | iostreamtopview[0].title = strdup("R (B/sec)"); | |
1765 | iostreamtopview[1].title = strdup("W (B/sec)"); | |
1766 | iostreamtopview[2].title = strdup("Total (B)"); | |
1767 | iostreamtopview[2].sort = 1; | |
32647247 JD |
1768 | |
1769 | fileview[0].title = strdup("FD"); | |
1770 | fileview[1].title = strdup("READ"); | |
1771 | fileview[1].sort = 1; | |
1772 | fileview[2].title = strdup("WRITE"); | |
89f1e0d1 JD |
1773 | } |
1774 | ||
1fc22eb4 JD |
1775 | void init_ncurses() |
1776 | { | |
635dc837 | 1777 | selected_processes = g_ptr_array_new(); |
1fc22eb4 | 1778 | sem_init(&update_display_sem, 0, 1); |
89f1e0d1 | 1779 | init_view_headers(); |
1fc22eb4 JD |
1780 | init_screen(); |
1781 | ||
dc8f04dd JD |
1782 | header = create_window(5, COLS - 1, 0, 0); |
1783 | center = create_window(LINES - 5 - 7, COLS - 1, 5, 0); | |
1fc22eb4 JD |
1784 | status = create_window(MAX_LOG_LINES + 2, COLS - 1, LINES - 7, 0); |
1785 | footer = create_window(1, COLS - 1, LINES - 1, 0); | |
1786 | ||
1787 | print_log("Starting display"); | |
1788 | ||
1789 | main_panel = new_panel(center); | |
1fc22eb4 JD |
1790 | |
1791 | current_view = cpu; | |
1792 | ||
1793 | basic_header(); | |
1794 | update_footer(); | |
1795 | ||
1796 | pthread_create(&keyboard_thread, NULL, handle_keyboard, (void *)NULL); | |
1797 | } |