Convert LTTngTop to C++ and state system
[lttngtop.git] / src / cursesdisplay.cpp
CommitLineData
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
46using namespace State;
47
48enum view_list current_view;
49enum view_list previous_view;
50
1fc22eb4
JD
51/* to prevent concurrent updates of the different windows */
52sem_t update_display_sem;
53
54char *termtype;
55WINDOW *footer, *header, *center, *status;
0d91c12a
JD
56WINDOW *pref_panel_window = NULL;
57PANEL *pref_panel, *main_panel;
1fc22eb4 58
0d91c12a 59int pref_panel_visible = 0;
3b15348c 60int pref_line_selected = 0;
41ff0645 61int pref_current_sort = 0;
1fc22eb4 62
715cf83c 63Quark selected_process;
1fc22eb4
JD
64int selected_ret;
65
66int selected_line = 0; /* select bar position */
67int selected_in_list = 0; /* selection relative to the whole list */
68int list_offset = 0; /* first index in the list to display (scroll) */
69int nb_log_lines = 0;
70char log_lines[MAX_LINE_LENGTH * MAX_LOG_LINES + MAX_LOG_LINES];
71
72int max_elements = 80;
73
e15ed00a 74int toggle_threads = 1;
1fc22eb4 75int toggle_pause = -1;
1fc22eb4
JD
76
77int max_center_lines;
635dc837 78GPtrArray *selected_processes;
1fc22eb4
JD
79
80pthread_t keyboard_thread;
81
89f1e0d1
JD
82struct header_view cputopview[4];
83struct header_view iostreamtopview[3];
32647247 84struct header_view fileview[3];
3b15348c 85
715cf83c
PBT
86unsigned long i_start = 0;
87unsigned long i_end = 0;
88
89std::string sort_perf_key;
90
91
1fc22eb4
JD
92void reset_ncurses()
93{
94 curs_set(1);
95 endwin();
96 exit(0);
97}
98
99static void handle_sigterm(int signal)
100{
101 reset_ncurses();
102}
103
104void 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
145WINDOW *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
154WINDOW *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
162void 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
177void 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 186void 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 197void 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 204void 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 243int 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
250void 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 262void 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
275void 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
294void 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
307struct 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
324static 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
336uint64_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
365void 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 412int 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 438int 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 454int 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
471int 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 497int 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 523int 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 556int 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 582int 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 608int 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 624int 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
652void 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 748int 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 779void 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
787void 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
912void 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
1024void 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
1131void 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
1162void 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
1181void 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
1229void 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
1247void 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
1295void 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
1315void 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
1363void 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 1388void 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 1458int 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
1483int 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
1509void 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 1527void 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
1543void pause_display()
1544{
1545 toggle_pause = 1;
1546 print_log("Pause");
1547 sem_wait(&pause_sem);
1548}
1549
1550void resume_display()
1551{
1552 toggle_pause = -1;
1553 print_log("Resume");
1554 sem_post(&pause_sem);
1555}
1556
1557void *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
1756void 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
1775void 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}
This page took 0.111775 seconds and 4 git commands to generate.