xref: /onnv-gate/usr/src/cmd/latencytop/common/display.c (revision 10673:b22eb20aa9ca)
1*10673SKrishnendu.Sadhukhan@Sun.COM /*
2*10673SKrishnendu.Sadhukhan@Sun.COM  * CDDL HEADER START
3*10673SKrishnendu.Sadhukhan@Sun.COM  *
4*10673SKrishnendu.Sadhukhan@Sun.COM  * The contents of this file are subject to the terms of the
5*10673SKrishnendu.Sadhukhan@Sun.COM  * Common Development and Distribution License (the "License").
6*10673SKrishnendu.Sadhukhan@Sun.COM  * You may not use this file except in compliance with the License.
7*10673SKrishnendu.Sadhukhan@Sun.COM  *
8*10673SKrishnendu.Sadhukhan@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*10673SKrishnendu.Sadhukhan@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*10673SKrishnendu.Sadhukhan@Sun.COM  * See the License for the specific language governing permissions
11*10673SKrishnendu.Sadhukhan@Sun.COM  * and limitations under the License.
12*10673SKrishnendu.Sadhukhan@Sun.COM  *
13*10673SKrishnendu.Sadhukhan@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*10673SKrishnendu.Sadhukhan@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*10673SKrishnendu.Sadhukhan@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*10673SKrishnendu.Sadhukhan@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*10673SKrishnendu.Sadhukhan@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*10673SKrishnendu.Sadhukhan@Sun.COM  *
19*10673SKrishnendu.Sadhukhan@Sun.COM  * CDDL HEADER END
20*10673SKrishnendu.Sadhukhan@Sun.COM  */
21*10673SKrishnendu.Sadhukhan@Sun.COM /*
22*10673SKrishnendu.Sadhukhan@Sun.COM  * Copyright (c) 2008-2009, Intel Corporation.
23*10673SKrishnendu.Sadhukhan@Sun.COM  * All Rights Reserved.
24*10673SKrishnendu.Sadhukhan@Sun.COM  */
25*10673SKrishnendu.Sadhukhan@Sun.COM 
26*10673SKrishnendu.Sadhukhan@Sun.COM #include <stdio.h>
27*10673SKrishnendu.Sadhukhan@Sun.COM #include <stdlib.h>
28*10673SKrishnendu.Sadhukhan@Sun.COM #include <unistd.h>
29*10673SKrishnendu.Sadhukhan@Sun.COM #include <string.h>
30*10673SKrishnendu.Sadhukhan@Sun.COM #include <sys/types.h>
31*10673SKrishnendu.Sadhukhan@Sun.COM #include <sys/time.h>
32*10673SKrishnendu.Sadhukhan@Sun.COM #include <dirent.h>
33*10673SKrishnendu.Sadhukhan@Sun.COM #include <curses.h>
34*10673SKrishnendu.Sadhukhan@Sun.COM #include <time.h>
35*10673SKrishnendu.Sadhukhan@Sun.COM #include <wchar.h>
36*10673SKrishnendu.Sadhukhan@Sun.COM #include <ctype.h>
37*10673SKrishnendu.Sadhukhan@Sun.COM #include <stdarg.h>
38*10673SKrishnendu.Sadhukhan@Sun.COM #include <signal.h>
39*10673SKrishnendu.Sadhukhan@Sun.COM 
40*10673SKrishnendu.Sadhukhan@Sun.COM #include "latencytop.h"
41*10673SKrishnendu.Sadhukhan@Sun.COM 
42*10673SKrishnendu.Sadhukhan@Sun.COM #define	LT_WINDOW_X			80
43*10673SKrishnendu.Sadhukhan@Sun.COM #define	LT_WINDOW_Y			24
44*10673SKrishnendu.Sadhukhan@Sun.COM 
45*10673SKrishnendu.Sadhukhan@Sun.COM #define	LT_COLOR_DEFAULT		1
46*10673SKrishnendu.Sadhukhan@Sun.COM #define	LT_COLOR_HEADER			2
47*10673SKrishnendu.Sadhukhan@Sun.COM 
48*10673SKrishnendu.Sadhukhan@Sun.COM /* Windows created by libcurses */
49*10673SKrishnendu.Sadhukhan@Sun.COM static WINDOW	*titlebar = NULL;
50*10673SKrishnendu.Sadhukhan@Sun.COM static WINDOW	*captionbar = NULL;
51*10673SKrishnendu.Sadhukhan@Sun.COM static WINDOW	*sysglobal_window = NULL;
52*10673SKrishnendu.Sadhukhan@Sun.COM static WINDOW	*taskbar = NULL;
53*10673SKrishnendu.Sadhukhan@Sun.COM static WINDOW	*process_window = NULL;
54*10673SKrishnendu.Sadhukhan@Sun.COM static WINDOW	*hintbar = NULL;
55*10673SKrishnendu.Sadhukhan@Sun.COM /* Screen dimension */
56*10673SKrishnendu.Sadhukhan@Sun.COM static int	screen_width = 1, screen_height = 1;
57*10673SKrishnendu.Sadhukhan@Sun.COM /* Is display initialized, i.e. are window pointers set up. */
58*10673SKrishnendu.Sadhukhan@Sun.COM static int	display_initialized = FALSE;
59*10673SKrishnendu.Sadhukhan@Sun.COM /* Is initscr() called */
60*10673SKrishnendu.Sadhukhan@Sun.COM static int	curses_inited = FALSE;
61*10673SKrishnendu.Sadhukhan@Sun.COM 
62*10673SKrishnendu.Sadhukhan@Sun.COM /* To handle user key presses */
63*10673SKrishnendu.Sadhukhan@Sun.COM static pid_t selected_pid = INVALID_PID;
64*10673SKrishnendu.Sadhukhan@Sun.COM static id_t selected_tid = INVALID_TID;
65*10673SKrishnendu.Sadhukhan@Sun.COM static lt_sort_t sort_type = LT_SORT_TOTAL;
66*10673SKrishnendu.Sadhukhan@Sun.COM static int thread_mode = FALSE;
67*10673SKrishnendu.Sadhukhan@Sun.COM /* Type of list being displayed */
68*10673SKrishnendu.Sadhukhan@Sun.COM static int current_list_type = LT_LIST_CAUSE;
69*10673SKrishnendu.Sadhukhan@Sun.COM static int show_help = FALSE;
70*10673SKrishnendu.Sadhukhan@Sun.COM 
71*10673SKrishnendu.Sadhukhan@Sun.COM /* Help functions that append/prepend a blank to the given string */
72*10673SKrishnendu.Sadhukhan@Sun.COM #define	fill_space_right(a, b, c)	fill_space((a), (b), (c), TRUE)
73*10673SKrishnendu.Sadhukhan@Sun.COM #define	fill_space_left(a, b, c)	fill_space((a), (b), (c), FALSE)
74*10673SKrishnendu.Sadhukhan@Sun.COM 
75*10673SKrishnendu.Sadhukhan@Sun.COM static void
76*10673SKrishnendu.Sadhukhan@Sun.COM fill_space(char *buffer, int len, int buffer_limit, int is_right)
77*10673SKrishnendu.Sadhukhan@Sun.COM {
78*10673SKrishnendu.Sadhukhan@Sun.COM 	int i = 0;
79*10673SKrishnendu.Sadhukhan@Sun.COM 	int tofill;
80*10673SKrishnendu.Sadhukhan@Sun.COM 
81*10673SKrishnendu.Sadhukhan@Sun.COM 	if (len >= buffer_limit) {
82*10673SKrishnendu.Sadhukhan@Sun.COM 		len = buffer_limit - 1;
83*10673SKrishnendu.Sadhukhan@Sun.COM 	}
84*10673SKrishnendu.Sadhukhan@Sun.COM 
85*10673SKrishnendu.Sadhukhan@Sun.COM 	i = strlen(buffer);
86*10673SKrishnendu.Sadhukhan@Sun.COM 
87*10673SKrishnendu.Sadhukhan@Sun.COM 	if (i >= len) {
88*10673SKrishnendu.Sadhukhan@Sun.COM 		return;
89*10673SKrishnendu.Sadhukhan@Sun.COM 	}
90*10673SKrishnendu.Sadhukhan@Sun.COM 
91*10673SKrishnendu.Sadhukhan@Sun.COM 	tofill = len - i;
92*10673SKrishnendu.Sadhukhan@Sun.COM 
93*10673SKrishnendu.Sadhukhan@Sun.COM 	if (is_right) {
94*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) memset(&buffer[i], ' ', tofill);
95*10673SKrishnendu.Sadhukhan@Sun.COM 		buffer[len] = '\0';
96*10673SKrishnendu.Sadhukhan@Sun.COM 	} else {
97*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) memmove(&buffer[tofill], buffer, i+1);
98*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) memset(buffer, ' ', tofill);
99*10673SKrishnendu.Sadhukhan@Sun.COM 	}
100*10673SKrishnendu.Sadhukhan@Sun.COM }
101*10673SKrishnendu.Sadhukhan@Sun.COM 
102*10673SKrishnendu.Sadhukhan@Sun.COM /* Convert the nanosecond value to a human readable string */
103*10673SKrishnendu.Sadhukhan@Sun.COM static const char *
104*10673SKrishnendu.Sadhukhan@Sun.COM get_time_string(double nanoseconds, char *buffer, int len, int fill_width)
105*10673SKrishnendu.Sadhukhan@Sun.COM {
106*10673SKrishnendu.Sadhukhan@Sun.COM 	const double ONE_USEC = 1000.0;
107*10673SKrishnendu.Sadhukhan@Sun.COM 	const double ONE_MSEC = 1000000.0;
108*10673SKrishnendu.Sadhukhan@Sun.COM 	const double ONE_SEC  = 1000000000.0;
109*10673SKrishnendu.Sadhukhan@Sun.COM 
110*10673SKrishnendu.Sadhukhan@Sun.COM 	if (nanoseconds < (ONE_USEC - .5)) {
111*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) snprintf(buffer, len, "%3.1f nsec", nanoseconds);
112*10673SKrishnendu.Sadhukhan@Sun.COM 	} else if (nanoseconds < (ONE_MSEC - .5 * ONE_USEC)) {
113*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) snprintf(buffer, len,
114*10673SKrishnendu.Sadhukhan@Sun.COM 		    "%3.1f usec", nanoseconds / ONE_USEC);
115*10673SKrishnendu.Sadhukhan@Sun.COM 	} else if (nanoseconds < (ONE_SEC - .5 * ONE_MSEC)) {
116*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) snprintf(buffer, len,
117*10673SKrishnendu.Sadhukhan@Sun.COM 		    "%3.1f msec", nanoseconds / ONE_MSEC);
118*10673SKrishnendu.Sadhukhan@Sun.COM 	} else if (nanoseconds < 999.5 * ONE_SEC) {
119*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) snprintf(buffer, len,
120*10673SKrishnendu.Sadhukhan@Sun.COM 		    "%3.1f  sec", nanoseconds / ONE_SEC);
121*10673SKrishnendu.Sadhukhan@Sun.COM 	} else {
122*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) snprintf(buffer, len,
123*10673SKrishnendu.Sadhukhan@Sun.COM 		    "%.0e sec", nanoseconds / ONE_SEC);
124*10673SKrishnendu.Sadhukhan@Sun.COM 	}
125*10673SKrishnendu.Sadhukhan@Sun.COM 
126*10673SKrishnendu.Sadhukhan@Sun.COM 	fill_space_left(buffer, fill_width, len);
127*10673SKrishnendu.Sadhukhan@Sun.COM 	return (buffer);
128*10673SKrishnendu.Sadhukhan@Sun.COM }
129*10673SKrishnendu.Sadhukhan@Sun.COM 
130*10673SKrishnendu.Sadhukhan@Sun.COM /* Used in print_statistics below */
131*10673SKrishnendu.Sadhukhan@Sun.COM #define	WIDTH_REASON_STRING	36
132*10673SKrishnendu.Sadhukhan@Sun.COM #define	WIDTH_COUNT		12
133*10673SKrishnendu.Sadhukhan@Sun.COM #define	WIDTH_AVG		12
134*10673SKrishnendu.Sadhukhan@Sun.COM #define	WIDTH_MAX		12
135*10673SKrishnendu.Sadhukhan@Sun.COM #define	WIDTH_PCT		8
136*10673SKrishnendu.Sadhukhan@Sun.COM #define	BEGIN_COUNT		WIDTH_REASON_STRING
137*10673SKrishnendu.Sadhukhan@Sun.COM #define	BEGIN_AVG		(BEGIN_COUNT + WIDTH_COUNT)
138*10673SKrishnendu.Sadhukhan@Sun.COM #define	BEGIN_MAX		(BEGIN_AVG + WIDTH_AVG)
139*10673SKrishnendu.Sadhukhan@Sun.COM #define	BEGIN_PCT		(BEGIN_MAX + WIDTH_MAX)
140*10673SKrishnendu.Sadhukhan@Sun.COM 
141*10673SKrishnendu.Sadhukhan@Sun.COM /*
142*10673SKrishnendu.Sadhukhan@Sun.COM  * Print statistics in global/process pane. Called by print_sysglobal
143*10673SKrishnendu.Sadhukhan@Sun.COM  * print_process.
144*10673SKrishnendu.Sadhukhan@Sun.COM  *
145*10673SKrishnendu.Sadhukhan@Sun.COM  * Parameters:
146*10673SKrishnendu.Sadhukhan@Sun.COM  *		window - the global or process statistics window.
147*10673SKrishnendu.Sadhukhan@Sun.COM  *		begin_line - where to start printing.
148*10673SKrishnendu.Sadhukhan@Sun.COM  *		count - how many lines should be printed.
149*10673SKrishnendu.Sadhukhan@Sun.COM  *		list - a stat_list.
150*10673SKrishnendu.Sadhukhan@Sun.COM  */
151*10673SKrishnendu.Sadhukhan@Sun.COM static void
152*10673SKrishnendu.Sadhukhan@Sun.COM print_statistics(WINDOW * window, int begin_line, int nlines, void *list)
153*10673SKrishnendu.Sadhukhan@Sun.COM {
154*10673SKrishnendu.Sadhukhan@Sun.COM 	uint64_t total;
155*10673SKrishnendu.Sadhukhan@Sun.COM 	int i = 0;
156*10673SKrishnendu.Sadhukhan@Sun.COM 
157*10673SKrishnendu.Sadhukhan@Sun.COM 	if (!display_initialized) {
158*10673SKrishnendu.Sadhukhan@Sun.COM 		return;
159*10673SKrishnendu.Sadhukhan@Sun.COM 	}
160*10673SKrishnendu.Sadhukhan@Sun.COM 
161*10673SKrishnendu.Sadhukhan@Sun.COM 	total = lt_stat_list_get_gtotal(list);
162*10673SKrishnendu.Sadhukhan@Sun.COM 
163*10673SKrishnendu.Sadhukhan@Sun.COM 	if (total == 0) {
164*10673SKrishnendu.Sadhukhan@Sun.COM 		return;
165*10673SKrishnendu.Sadhukhan@Sun.COM 	}
166*10673SKrishnendu.Sadhukhan@Sun.COM 
167*10673SKrishnendu.Sadhukhan@Sun.COM 	while (i < nlines && lt_stat_list_has_item(list, i)) {
168*10673SKrishnendu.Sadhukhan@Sun.COM 
169*10673SKrishnendu.Sadhukhan@Sun.COM 		char tmp[WIDTH_REASON_STRING];
170*10673SKrishnendu.Sadhukhan@Sun.COM 		const char *reason = lt_stat_list_get_reason(list, i);
171*10673SKrishnendu.Sadhukhan@Sun.COM 		uint64_t count = lt_stat_list_get_count(list, i);
172*10673SKrishnendu.Sadhukhan@Sun.COM 
173*10673SKrishnendu.Sadhukhan@Sun.COM 		if (count == 0) {
174*10673SKrishnendu.Sadhukhan@Sun.COM 			continue;
175*10673SKrishnendu.Sadhukhan@Sun.COM 		}
176*10673SKrishnendu.Sadhukhan@Sun.COM 
177*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) snprintf(tmp, sizeof (tmp), "%s", reason);
178*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) mvwprintw(window, i + begin_line, 0, "%s", tmp);
179*10673SKrishnendu.Sadhukhan@Sun.COM 
180*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) snprintf(tmp, sizeof (tmp), "%llu", count);
181*10673SKrishnendu.Sadhukhan@Sun.COM 		fill_space_left(tmp, WIDTH_COUNT, sizeof (tmp));
182*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) mvwprintw(window, i + begin_line, BEGIN_COUNT,
183*10673SKrishnendu.Sadhukhan@Sun.COM 		    "%s", tmp);
184*10673SKrishnendu.Sadhukhan@Sun.COM 
185*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) mvwprintw(window, i + begin_line, BEGIN_AVG,
186*10673SKrishnendu.Sadhukhan@Sun.COM 		    "%s", get_time_string(
187*10673SKrishnendu.Sadhukhan@Sun.COM 		    (double)lt_stat_list_get_sum(list, i) / count,
188*10673SKrishnendu.Sadhukhan@Sun.COM 		    tmp, sizeof (tmp), WIDTH_AVG));
189*10673SKrishnendu.Sadhukhan@Sun.COM 
190*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) mvwprintw(window, i + begin_line, BEGIN_MAX,
191*10673SKrishnendu.Sadhukhan@Sun.COM 		    "%s", get_time_string(
192*10673SKrishnendu.Sadhukhan@Sun.COM 		    (double)lt_stat_list_get_max(list, i),
193*10673SKrishnendu.Sadhukhan@Sun.COM 		    tmp, sizeof (tmp), WIDTH_MAX));
194*10673SKrishnendu.Sadhukhan@Sun.COM 
195*10673SKrishnendu.Sadhukhan@Sun.COM 		if (LT_LIST_SPECIALS != current_list_type) {
196*10673SKrishnendu.Sadhukhan@Sun.COM 			(void) snprintf(tmp, sizeof (tmp), "%.1f %%",
197*10673SKrishnendu.Sadhukhan@Sun.COM 			    (double)lt_stat_list_get_sum(list, i)
198*10673SKrishnendu.Sadhukhan@Sun.COM 			    / total * 100.0);
199*10673SKrishnendu.Sadhukhan@Sun.COM 		} else {
200*10673SKrishnendu.Sadhukhan@Sun.COM 			(void) snprintf(tmp, sizeof (tmp), "--- ");
201*10673SKrishnendu.Sadhukhan@Sun.COM 		}
202*10673SKrishnendu.Sadhukhan@Sun.COM 
203*10673SKrishnendu.Sadhukhan@Sun.COM 		fill_space_left(tmp, WIDTH_PCT, sizeof (tmp));
204*10673SKrishnendu.Sadhukhan@Sun.COM 
205*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) mvwprintw(window, i + begin_line, BEGIN_PCT,
206*10673SKrishnendu.Sadhukhan@Sun.COM 		    "%s", tmp);
207*10673SKrishnendu.Sadhukhan@Sun.COM 		i++;
208*10673SKrishnendu.Sadhukhan@Sun.COM 	}
209*10673SKrishnendu.Sadhukhan@Sun.COM }
210*10673SKrishnendu.Sadhukhan@Sun.COM 
211*10673SKrishnendu.Sadhukhan@Sun.COM /*
212*10673SKrishnendu.Sadhukhan@Sun.COM  * Print statistics in global pane.
213*10673SKrishnendu.Sadhukhan@Sun.COM  */
214*10673SKrishnendu.Sadhukhan@Sun.COM static void
215*10673SKrishnendu.Sadhukhan@Sun.COM print_sysglobal(void)
216*10673SKrishnendu.Sadhukhan@Sun.COM {
217*10673SKrishnendu.Sadhukhan@Sun.COM 	void *list;
218*10673SKrishnendu.Sadhukhan@Sun.COM 	char header[256];
219*10673SKrishnendu.Sadhukhan@Sun.COM 
220*10673SKrishnendu.Sadhukhan@Sun.COM 	if (!display_initialized) {
221*10673SKrishnendu.Sadhukhan@Sun.COM 		return;
222*10673SKrishnendu.Sadhukhan@Sun.COM 	}
223*10673SKrishnendu.Sadhukhan@Sun.COM 
224*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) werase(sysglobal_window);
225*10673SKrishnendu.Sadhukhan@Sun.COM 
226*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) wattron(sysglobal_window, A_REVERSE);
227*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) snprintf(header, sizeof (header),
228*10673SKrishnendu.Sadhukhan@Sun.COM 	    "%s", "System wide latencies");
229*10673SKrishnendu.Sadhukhan@Sun.COM 	fill_space_right(header, screen_width, sizeof (header));
230*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) mvwprintw(sysglobal_window, 0, 0, "%s", header);
231*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) wattroff(sysglobal_window, A_REVERSE);
232*10673SKrishnendu.Sadhukhan@Sun.COM 
233*10673SKrishnendu.Sadhukhan@Sun.COM 	list = lt_stat_list_create(current_list_type,
234*10673SKrishnendu.Sadhukhan@Sun.COM 	    LT_LEVEL_GLOBAL, 0, 0, 10, sort_type);
235*10673SKrishnendu.Sadhukhan@Sun.COM 	print_statistics(sysglobal_window, 1, 10, list);
236*10673SKrishnendu.Sadhukhan@Sun.COM 	lt_stat_list_free(list);
237*10673SKrishnendu.Sadhukhan@Sun.COM 
238*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) wrefresh(sysglobal_window);
239*10673SKrishnendu.Sadhukhan@Sun.COM }
240*10673SKrishnendu.Sadhukhan@Sun.COM 
241*10673SKrishnendu.Sadhukhan@Sun.COM /*
242*10673SKrishnendu.Sadhukhan@Sun.COM  * Prints current operation mode. Mode is combination of:
243*10673SKrishnendu.Sadhukhan@Sun.COM  *
244*10673SKrishnendu.Sadhukhan@Sun.COM  * 	"Process or Thread", and "1 or 2 or 3".
245*10673SKrishnendu.Sadhukhan@Sun.COM  */
246*10673SKrishnendu.Sadhukhan@Sun.COM static void
247*10673SKrishnendu.Sadhukhan@Sun.COM print_current_mode()
248*10673SKrishnendu.Sadhukhan@Sun.COM {
249*10673SKrishnendu.Sadhukhan@Sun.COM 	char type;
250*10673SKrishnendu.Sadhukhan@Sun.COM 
251*10673SKrishnendu.Sadhukhan@Sun.COM 	if (!display_initialized) {
252*10673SKrishnendu.Sadhukhan@Sun.COM 		return;
253*10673SKrishnendu.Sadhukhan@Sun.COM 	}
254*10673SKrishnendu.Sadhukhan@Sun.COM 
255*10673SKrishnendu.Sadhukhan@Sun.COM 	switch (current_list_type) {
256*10673SKrishnendu.Sadhukhan@Sun.COM 	case LT_LIST_CAUSE:
257*10673SKrishnendu.Sadhukhan@Sun.COM 		type = '1';
258*10673SKrishnendu.Sadhukhan@Sun.COM 		break;
259*10673SKrishnendu.Sadhukhan@Sun.COM 	case LT_LIST_SPECIALS:
260*10673SKrishnendu.Sadhukhan@Sun.COM 		type = '2';
261*10673SKrishnendu.Sadhukhan@Sun.COM 		break;
262*10673SKrishnendu.Sadhukhan@Sun.COM 	case LT_LIST_SOBJ:
263*10673SKrishnendu.Sadhukhan@Sun.COM 		type = '3';
264*10673SKrishnendu.Sadhukhan@Sun.COM 		break;
265*10673SKrishnendu.Sadhukhan@Sun.COM 	default:
266*10673SKrishnendu.Sadhukhan@Sun.COM 		type = '?';
267*10673SKrishnendu.Sadhukhan@Sun.COM 		break;
268*10673SKrishnendu.Sadhukhan@Sun.COM 	}
269*10673SKrishnendu.Sadhukhan@Sun.COM 
270*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) mvwprintw(process_window, 0, screen_width - 8, "View: %c%c",
271*10673SKrishnendu.Sadhukhan@Sun.COM 	    type, thread_mode ? 'T' : 'P');
272*10673SKrishnendu.Sadhukhan@Sun.COM }
273*10673SKrishnendu.Sadhukhan@Sun.COM 
274*10673SKrishnendu.Sadhukhan@Sun.COM /*
275*10673SKrishnendu.Sadhukhan@Sun.COM  * Print per-process statistics in process pane.
276*10673SKrishnendu.Sadhukhan@Sun.COM  * This is called when mode of operation is process.
277*10673SKrishnendu.Sadhukhan@Sun.COM  */
278*10673SKrishnendu.Sadhukhan@Sun.COM static void
279*10673SKrishnendu.Sadhukhan@Sun.COM print_process(unsigned int pid)
280*10673SKrishnendu.Sadhukhan@Sun.COM {
281*10673SKrishnendu.Sadhukhan@Sun.COM 	void *list;
282*10673SKrishnendu.Sadhukhan@Sun.COM 	char header[256];
283*10673SKrishnendu.Sadhukhan@Sun.COM 	char tmp[30];
284*10673SKrishnendu.Sadhukhan@Sun.COM 
285*10673SKrishnendu.Sadhukhan@Sun.COM 	if (!display_initialized) {
286*10673SKrishnendu.Sadhukhan@Sun.COM 		return;
287*10673SKrishnendu.Sadhukhan@Sun.COM 	}
288*10673SKrishnendu.Sadhukhan@Sun.COM 
289*10673SKrishnendu.Sadhukhan@Sun.COM 	list = lt_stat_list_create(current_list_type, LT_LEVEL_PROCESS,
290*10673SKrishnendu.Sadhukhan@Sun.COM 	    pid, 0, 8, sort_type);
291*10673SKrishnendu.Sadhukhan@Sun.COM 
292*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) werase(process_window);
293*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) wattron(process_window, A_REVERSE);
294*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) snprintf(header, sizeof (header), "Process %s (%i), %d threads",
295*10673SKrishnendu.Sadhukhan@Sun.COM 	    lt_stat_proc_get_name(pid), pid, lt_stat_proc_get_nthreads(pid));
296*10673SKrishnendu.Sadhukhan@Sun.COM 	fill_space_right(header, screen_width, sizeof (header));
297*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) mvwprintw(process_window, 0, 0, "%s", header);
298*10673SKrishnendu.Sadhukhan@Sun.COM 
299*10673SKrishnendu.Sadhukhan@Sun.COM 	if (current_list_type != LT_LIST_SPECIALS) {
300*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) mvwprintw(process_window, 0, 48, "Total: %s",
301*10673SKrishnendu.Sadhukhan@Sun.COM 		    get_time_string((double)lt_stat_list_get_gtotal(list),
302*10673SKrishnendu.Sadhukhan@Sun.COM 		    tmp, sizeof (tmp), 12));
303*10673SKrishnendu.Sadhukhan@Sun.COM 	}
304*10673SKrishnendu.Sadhukhan@Sun.COM 
305*10673SKrishnendu.Sadhukhan@Sun.COM 	print_current_mode();
306*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) wattroff(process_window, A_REVERSE);
307*10673SKrishnendu.Sadhukhan@Sun.COM 	print_statistics(process_window, 1, 8, list);
308*10673SKrishnendu.Sadhukhan@Sun.COM 	lt_stat_list_free(list);
309*10673SKrishnendu.Sadhukhan@Sun.COM 
310*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) wrefresh(process_window);
311*10673SKrishnendu.Sadhukhan@Sun.COM }
312*10673SKrishnendu.Sadhukhan@Sun.COM 
313*10673SKrishnendu.Sadhukhan@Sun.COM /*
314*10673SKrishnendu.Sadhukhan@Sun.COM  * Display the list of processes that are tracked, in task bar.
315*10673SKrishnendu.Sadhukhan@Sun.COM  * This one is called when mode of operation is process.
316*10673SKrishnendu.Sadhukhan@Sun.COM  */
317*10673SKrishnendu.Sadhukhan@Sun.COM static void
318*10673SKrishnendu.Sadhukhan@Sun.COM print_taskbar_process(pid_t *pidlist, int pidlist_len, int pidlist_index)
319*10673SKrishnendu.Sadhukhan@Sun.COM {
320*10673SKrishnendu.Sadhukhan@Sun.COM 	const int ITEM_WIDTH = 8;
321*10673SKrishnendu.Sadhukhan@Sun.COM 
322*10673SKrishnendu.Sadhukhan@Sun.COM 	int number_item;
323*10673SKrishnendu.Sadhukhan@Sun.COM 	int i;
324*10673SKrishnendu.Sadhukhan@Sun.COM 	int xpos = 0;
325*10673SKrishnendu.Sadhukhan@Sun.COM 
326*10673SKrishnendu.Sadhukhan@Sun.COM 	if (!display_initialized) {
327*10673SKrishnendu.Sadhukhan@Sun.COM 		return;
328*10673SKrishnendu.Sadhukhan@Sun.COM 	}
329*10673SKrishnendu.Sadhukhan@Sun.COM 
330*10673SKrishnendu.Sadhukhan@Sun.COM 	number_item = (screen_width / ITEM_WIDTH) - 1;
331*10673SKrishnendu.Sadhukhan@Sun.COM 	i = pidlist_index - (pidlist_index % number_item);
332*10673SKrishnendu.Sadhukhan@Sun.COM 
333*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) werase(taskbar);
334*10673SKrishnendu.Sadhukhan@Sun.COM 
335*10673SKrishnendu.Sadhukhan@Sun.COM 	if (i != 0) {
336*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) mvwprintw(taskbar, 0, xpos, "<-");
337*10673SKrishnendu.Sadhukhan@Sun.COM 	}
338*10673SKrishnendu.Sadhukhan@Sun.COM 
339*10673SKrishnendu.Sadhukhan@Sun.COM 	xpos = ITEM_WIDTH / 2;
340*10673SKrishnendu.Sadhukhan@Sun.COM 
341*10673SKrishnendu.Sadhukhan@Sun.COM 	while (xpos + ITEM_WIDTH <= screen_width && i < pidlist_len) {
342*10673SKrishnendu.Sadhukhan@Sun.COM 		char str[ITEM_WIDTH+1];
343*10673SKrishnendu.Sadhukhan@Sun.COM 		int slen;
344*10673SKrishnendu.Sadhukhan@Sun.COM 		const char *pname = lt_stat_proc_get_name(pidlist[i]);
345*10673SKrishnendu.Sadhukhan@Sun.COM 
346*10673SKrishnendu.Sadhukhan@Sun.COM 		if (pname && pname[0]) {
347*10673SKrishnendu.Sadhukhan@Sun.COM 			(void) snprintf(str, sizeof (str) - 1, "%s", pname);
348*10673SKrishnendu.Sadhukhan@Sun.COM 		} else {
349*10673SKrishnendu.Sadhukhan@Sun.COM 			(void) snprintf(str, sizeof (str) - 1,
350*10673SKrishnendu.Sadhukhan@Sun.COM 			    "<%d>", pidlist[i]);
351*10673SKrishnendu.Sadhukhan@Sun.COM 		}
352*10673SKrishnendu.Sadhukhan@Sun.COM 
353*10673SKrishnendu.Sadhukhan@Sun.COM 		slen = strlen(str);
354*10673SKrishnendu.Sadhukhan@Sun.COM 
355*10673SKrishnendu.Sadhukhan@Sun.COM 		if (slen < ITEM_WIDTH) {
356*10673SKrishnendu.Sadhukhan@Sun.COM 			(void) memset(&str[slen], ' ', ITEM_WIDTH - slen);
357*10673SKrishnendu.Sadhukhan@Sun.COM 		}
358*10673SKrishnendu.Sadhukhan@Sun.COM 
359*10673SKrishnendu.Sadhukhan@Sun.COM 		str[sizeof (str) - 1] = '\0';
360*10673SKrishnendu.Sadhukhan@Sun.COM 
361*10673SKrishnendu.Sadhukhan@Sun.COM 		if (i == pidlist_index) {
362*10673SKrishnendu.Sadhukhan@Sun.COM 			(void) wattron(taskbar, A_REVERSE);
363*10673SKrishnendu.Sadhukhan@Sun.COM 		}
364*10673SKrishnendu.Sadhukhan@Sun.COM 
365*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) mvwprintw(taskbar, 0, xpos, "%s", str);
366*10673SKrishnendu.Sadhukhan@Sun.COM 
367*10673SKrishnendu.Sadhukhan@Sun.COM 		if (i == pidlist_index) {
368*10673SKrishnendu.Sadhukhan@Sun.COM 			(void) wattroff(taskbar, A_REVERSE);
369*10673SKrishnendu.Sadhukhan@Sun.COM 		}
370*10673SKrishnendu.Sadhukhan@Sun.COM 
371*10673SKrishnendu.Sadhukhan@Sun.COM 		xpos += ITEM_WIDTH;
372*10673SKrishnendu.Sadhukhan@Sun.COM 		i++;
373*10673SKrishnendu.Sadhukhan@Sun.COM 	}
374*10673SKrishnendu.Sadhukhan@Sun.COM 
375*10673SKrishnendu.Sadhukhan@Sun.COM 	if (i != pidlist_len) {
376*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) mvwprintw(taskbar, 0, screen_width - 2, "->");
377*10673SKrishnendu.Sadhukhan@Sun.COM 	}
378*10673SKrishnendu.Sadhukhan@Sun.COM 
379*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) wrefresh(taskbar);
380*10673SKrishnendu.Sadhukhan@Sun.COM }
381*10673SKrishnendu.Sadhukhan@Sun.COM 
382*10673SKrishnendu.Sadhukhan@Sun.COM /*
383*10673SKrishnendu.Sadhukhan@Sun.COM  * Display the list of processes that are tracked, in task bar.
384*10673SKrishnendu.Sadhukhan@Sun.COM  * This one is called when mode of operation is thread.
385*10673SKrishnendu.Sadhukhan@Sun.COM  */
386*10673SKrishnendu.Sadhukhan@Sun.COM static void
387*10673SKrishnendu.Sadhukhan@Sun.COM print_taskbar_thread(pid_t *pidlist, id_t *tidlist, int list_len,
388*10673SKrishnendu.Sadhukhan@Sun.COM     int list_index)
389*10673SKrishnendu.Sadhukhan@Sun.COM {
390*10673SKrishnendu.Sadhukhan@Sun.COM 	const int ITEM_WIDTH = 12;
391*10673SKrishnendu.Sadhukhan@Sun.COM 
392*10673SKrishnendu.Sadhukhan@Sun.COM 	int number_item;
393*10673SKrishnendu.Sadhukhan@Sun.COM 	int i;
394*10673SKrishnendu.Sadhukhan@Sun.COM 	int xpos = 0;
395*10673SKrishnendu.Sadhukhan@Sun.COM 	const char *pname = NULL;
396*10673SKrishnendu.Sadhukhan@Sun.COM 	pid_t last_pid = INVALID_PID;
397*10673SKrishnendu.Sadhukhan@Sun.COM 
398*10673SKrishnendu.Sadhukhan@Sun.COM 
399*10673SKrishnendu.Sadhukhan@Sun.COM 	if (!display_initialized) {
400*10673SKrishnendu.Sadhukhan@Sun.COM 		return;
401*10673SKrishnendu.Sadhukhan@Sun.COM 	}
402*10673SKrishnendu.Sadhukhan@Sun.COM 
403*10673SKrishnendu.Sadhukhan@Sun.COM 	number_item = (screen_width - 8) / ITEM_WIDTH;
404*10673SKrishnendu.Sadhukhan@Sun.COM 	i = list_index - (list_index % number_item);
405*10673SKrishnendu.Sadhukhan@Sun.COM 
406*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) werase(taskbar);
407*10673SKrishnendu.Sadhukhan@Sun.COM 
408*10673SKrishnendu.Sadhukhan@Sun.COM 	if (i != 0) {
409*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) mvwprintw(taskbar, 0, xpos, "<-");
410*10673SKrishnendu.Sadhukhan@Sun.COM 	}
411*10673SKrishnendu.Sadhukhan@Sun.COM 
412*10673SKrishnendu.Sadhukhan@Sun.COM 	xpos = 4;
413*10673SKrishnendu.Sadhukhan@Sun.COM 
414*10673SKrishnendu.Sadhukhan@Sun.COM 	while (xpos + ITEM_WIDTH <= screen_width && i < list_len) {
415*10673SKrishnendu.Sadhukhan@Sun.COM 		char str[ITEM_WIDTH+1];
416*10673SKrishnendu.Sadhukhan@Sun.COM 		int slen, tlen;
417*10673SKrishnendu.Sadhukhan@Sun.COM 
418*10673SKrishnendu.Sadhukhan@Sun.COM 		if (pidlist[i] != last_pid) {
419*10673SKrishnendu.Sadhukhan@Sun.COM 			pname = lt_stat_proc_get_name(pidlist[i]);
420*10673SKrishnendu.Sadhukhan@Sun.COM 			last_pid = pidlist[i];
421*10673SKrishnendu.Sadhukhan@Sun.COM 		}
422*10673SKrishnendu.Sadhukhan@Sun.COM 
423*10673SKrishnendu.Sadhukhan@Sun.COM 		/*
424*10673SKrishnendu.Sadhukhan@Sun.COM 		 * Calculate length of thread's ID; use shorter process name
425*10673SKrishnendu.Sadhukhan@Sun.COM 		 * in order to save space on the screen.
426*10673SKrishnendu.Sadhukhan@Sun.COM 		 */
427*10673SKrishnendu.Sadhukhan@Sun.COM 		tlen = snprintf(NULL, 0, "_%d", tidlist[i]);
428*10673SKrishnendu.Sadhukhan@Sun.COM 
429*10673SKrishnendu.Sadhukhan@Sun.COM 		if (pname && pname[0]) {
430*10673SKrishnendu.Sadhukhan@Sun.COM 			(void) snprintf(str, sizeof (str) - tlen - 1,
431*10673SKrishnendu.Sadhukhan@Sun.COM 			    "%s", pname);
432*10673SKrishnendu.Sadhukhan@Sun.COM 		} else {
433*10673SKrishnendu.Sadhukhan@Sun.COM 			(void) snprintf(str, sizeof (str) - tlen - 1,
434*10673SKrishnendu.Sadhukhan@Sun.COM 			    "<%d>", pidlist[i]);
435*10673SKrishnendu.Sadhukhan@Sun.COM 		}
436*10673SKrishnendu.Sadhukhan@Sun.COM 
437*10673SKrishnendu.Sadhukhan@Sun.COM 		slen = strlen(str);
438*10673SKrishnendu.Sadhukhan@Sun.COM 
439*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) snprintf(&str[slen], sizeof (str) - slen,
440*10673SKrishnendu.Sadhukhan@Sun.COM 		    "_%d", tidlist[i]);
441*10673SKrishnendu.Sadhukhan@Sun.COM 
442*10673SKrishnendu.Sadhukhan@Sun.COM 		slen += tlen;
443*10673SKrishnendu.Sadhukhan@Sun.COM 
444*10673SKrishnendu.Sadhukhan@Sun.COM 		if (slen < ITEM_WIDTH) {
445*10673SKrishnendu.Sadhukhan@Sun.COM 			(void) memset(&str[slen], ' ', ITEM_WIDTH - slen);
446*10673SKrishnendu.Sadhukhan@Sun.COM 		}
447*10673SKrishnendu.Sadhukhan@Sun.COM 
448*10673SKrishnendu.Sadhukhan@Sun.COM 		str[sizeof (str) - 1] = '\0';
449*10673SKrishnendu.Sadhukhan@Sun.COM 
450*10673SKrishnendu.Sadhukhan@Sun.COM 		if (i == list_index) {
451*10673SKrishnendu.Sadhukhan@Sun.COM 			(void) wattron(taskbar, A_REVERSE);
452*10673SKrishnendu.Sadhukhan@Sun.COM 		}
453*10673SKrishnendu.Sadhukhan@Sun.COM 
454*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) mvwprintw(taskbar, 0, xpos, "%s", str);
455*10673SKrishnendu.Sadhukhan@Sun.COM 
456*10673SKrishnendu.Sadhukhan@Sun.COM 		if (i == list_index) {
457*10673SKrishnendu.Sadhukhan@Sun.COM 			(void) wattroff(taskbar, A_REVERSE);
458*10673SKrishnendu.Sadhukhan@Sun.COM 		}
459*10673SKrishnendu.Sadhukhan@Sun.COM 
460*10673SKrishnendu.Sadhukhan@Sun.COM 		xpos += ITEM_WIDTH;
461*10673SKrishnendu.Sadhukhan@Sun.COM 		i++;
462*10673SKrishnendu.Sadhukhan@Sun.COM 	}
463*10673SKrishnendu.Sadhukhan@Sun.COM 
464*10673SKrishnendu.Sadhukhan@Sun.COM 	if (i != list_len) {
465*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) mvwprintw(taskbar, 0, screen_width - 2, "->");
466*10673SKrishnendu.Sadhukhan@Sun.COM 	}
467*10673SKrishnendu.Sadhukhan@Sun.COM 
468*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) wrefresh(taskbar);
469*10673SKrishnendu.Sadhukhan@Sun.COM }
470*10673SKrishnendu.Sadhukhan@Sun.COM 
471*10673SKrishnendu.Sadhukhan@Sun.COM /*
472*10673SKrishnendu.Sadhukhan@Sun.COM  * Print per-thread statistics in process pane.
473*10673SKrishnendu.Sadhukhan@Sun.COM  * This is called when mode of operation is thread.
474*10673SKrishnendu.Sadhukhan@Sun.COM  */
475*10673SKrishnendu.Sadhukhan@Sun.COM static void
476*10673SKrishnendu.Sadhukhan@Sun.COM print_thread(pid_t pid, id_t tid)
477*10673SKrishnendu.Sadhukhan@Sun.COM {
478*10673SKrishnendu.Sadhukhan@Sun.COM 	void *list;
479*10673SKrishnendu.Sadhukhan@Sun.COM 	char header[256];
480*10673SKrishnendu.Sadhukhan@Sun.COM 	char tmp[30];
481*10673SKrishnendu.Sadhukhan@Sun.COM 
482*10673SKrishnendu.Sadhukhan@Sun.COM 	if (!display_initialized) {
483*10673SKrishnendu.Sadhukhan@Sun.COM 		return;
484*10673SKrishnendu.Sadhukhan@Sun.COM 	}
485*10673SKrishnendu.Sadhukhan@Sun.COM 
486*10673SKrishnendu.Sadhukhan@Sun.COM 	list = lt_stat_list_create(current_list_type, LT_LEVEL_THREAD,
487*10673SKrishnendu.Sadhukhan@Sun.COM 	    pid, tid, 8, sort_type);
488*10673SKrishnendu.Sadhukhan@Sun.COM 
489*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) werase(process_window);
490*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) wattron(process_window, A_REVERSE);
491*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) snprintf(header, sizeof (header),
492*10673SKrishnendu.Sadhukhan@Sun.COM 	    "Process %s (%i), LWP %d",
493*10673SKrishnendu.Sadhukhan@Sun.COM 	    lt_stat_proc_get_name(pid), pid, tid);
494*10673SKrishnendu.Sadhukhan@Sun.COM 	fill_space_right(header, screen_width, sizeof (header));
495*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) mvwprintw(process_window, 0, 0, "%s", header);
496*10673SKrishnendu.Sadhukhan@Sun.COM 
497*10673SKrishnendu.Sadhukhan@Sun.COM 	if (current_list_type != LT_LIST_SPECIALS) {
498*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) mvwprintw(process_window, 0, 48, "Total: %s",
499*10673SKrishnendu.Sadhukhan@Sun.COM 		    get_time_string(
500*10673SKrishnendu.Sadhukhan@Sun.COM 		    (double)lt_stat_list_get_gtotal(list),
501*10673SKrishnendu.Sadhukhan@Sun.COM 		    tmp, sizeof (tmp), 12));
502*10673SKrishnendu.Sadhukhan@Sun.COM 	}
503*10673SKrishnendu.Sadhukhan@Sun.COM 
504*10673SKrishnendu.Sadhukhan@Sun.COM 	print_current_mode();
505*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) wattroff(process_window, A_REVERSE);
506*10673SKrishnendu.Sadhukhan@Sun.COM 	print_statistics(process_window, 1, 8, list);
507*10673SKrishnendu.Sadhukhan@Sun.COM 	lt_stat_list_free(list);
508*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) wrefresh(process_window);
509*10673SKrishnendu.Sadhukhan@Sun.COM }
510*10673SKrishnendu.Sadhukhan@Sun.COM 
511*10673SKrishnendu.Sadhukhan@Sun.COM /*
512*10673SKrishnendu.Sadhukhan@Sun.COM  * Update hint string at the bottom line. The message to print is stored in
513*10673SKrishnendu.Sadhukhan@Sun.COM  * hint. If hint is NULL, the function will display its own message.
514*10673SKrishnendu.Sadhukhan@Sun.COM  */
515*10673SKrishnendu.Sadhukhan@Sun.COM static void
516*10673SKrishnendu.Sadhukhan@Sun.COM print_hint(const char *hint)
517*10673SKrishnendu.Sadhukhan@Sun.COM {
518*10673SKrishnendu.Sadhukhan@Sun.COM 	const char *HINTS[] =    {
519*10673SKrishnendu.Sadhukhan@Sun.COM 		"Press '<' or '>' to switch between processes.",
520*10673SKrishnendu.Sadhukhan@Sun.COM 		"Press 'q' to exit.",
521*10673SKrishnendu.Sadhukhan@Sun.COM 		"Press 'r' to refresh immediately.",
522*10673SKrishnendu.Sadhukhan@Sun.COM 		"Press 't' to toggle Process/Thread display mode.",
523*10673SKrishnendu.Sadhukhan@Sun.COM 		"Press 'h' for help.",
524*10673SKrishnendu.Sadhukhan@Sun.COM 		"Use 'c', 'a', 'm', 'p' to change sort criteria."
525*10673SKrishnendu.Sadhukhan@Sun.COM 		"Use '1', '2', '3' to switch between windows."
526*10673SKrishnendu.Sadhukhan@Sun.COM 	};
527*10673SKrishnendu.Sadhukhan@Sun.COM 	const uint64_t update_interval = 5000; /* 5 seconds */
528*10673SKrishnendu.Sadhukhan@Sun.COM 
529*10673SKrishnendu.Sadhukhan@Sun.COM 	static int index = 0;
530*10673SKrishnendu.Sadhukhan@Sun.COM 	static uint64_t next_hint = 0;
531*10673SKrishnendu.Sadhukhan@Sun.COM 	uint64_t now = lt_millisecond();
532*10673SKrishnendu.Sadhukhan@Sun.COM 
533*10673SKrishnendu.Sadhukhan@Sun.COM 	if (!display_initialized) {
534*10673SKrishnendu.Sadhukhan@Sun.COM 		return;
535*10673SKrishnendu.Sadhukhan@Sun.COM 	}
536*10673SKrishnendu.Sadhukhan@Sun.COM 
537*10673SKrishnendu.Sadhukhan@Sun.COM 	if (hint == NULL) {
538*10673SKrishnendu.Sadhukhan@Sun.COM 		if (now < next_hint) {
539*10673SKrishnendu.Sadhukhan@Sun.COM 			return;
540*10673SKrishnendu.Sadhukhan@Sun.COM 		}
541*10673SKrishnendu.Sadhukhan@Sun.COM 
542*10673SKrishnendu.Sadhukhan@Sun.COM 		hint = HINTS[index];
543*10673SKrishnendu.Sadhukhan@Sun.COM 		index = (index + 1) % (sizeof (HINTS) / sizeof (HINTS[0]));
544*10673SKrishnendu.Sadhukhan@Sun.COM 		next_hint = now + update_interval;
545*10673SKrishnendu.Sadhukhan@Sun.COM 	} else {
546*10673SKrishnendu.Sadhukhan@Sun.COM 		/*
547*10673SKrishnendu.Sadhukhan@Sun.COM 		 * Important messages are displayed at least every 2 cycles.
548*10673SKrishnendu.Sadhukhan@Sun.COM 		 */
549*10673SKrishnendu.Sadhukhan@Sun.COM 		next_hint = now + update_interval * 2;
550*10673SKrishnendu.Sadhukhan@Sun.COM 	}
551*10673SKrishnendu.Sadhukhan@Sun.COM 
552*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) werase(hintbar);
553*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) mvwprintw(hintbar, 0, (screen_width - strlen(hint)) / 2,
554*10673SKrishnendu.Sadhukhan@Sun.COM 	    "%s", hint);
555*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) wrefresh(hintbar);
556*10673SKrishnendu.Sadhukhan@Sun.COM }
557*10673SKrishnendu.Sadhukhan@Sun.COM 
558*10673SKrishnendu.Sadhukhan@Sun.COM /*
559*10673SKrishnendu.Sadhukhan@Sun.COM  * Create a PID list or a PID/TID list (if operation mode is thread) from
560*10673SKrishnendu.Sadhukhan@Sun.COM  * available statistics.
561*10673SKrishnendu.Sadhukhan@Sun.COM  */
562*10673SKrishnendu.Sadhukhan@Sun.COM static void
563*10673SKrishnendu.Sadhukhan@Sun.COM get_plist(pid_t **plist, id_t **tlist, int *list_len, int *list_index)
564*10673SKrishnendu.Sadhukhan@Sun.COM {
565*10673SKrishnendu.Sadhukhan@Sun.COM 	if (!thread_mode) {
566*10673SKrishnendu.Sadhukhan@Sun.COM 		/* Per-process mode */
567*10673SKrishnendu.Sadhukhan@Sun.COM 		*list_len = lt_stat_proc_list_create(plist, NULL);
568*10673SKrishnendu.Sadhukhan@Sun.COM 
569*10673SKrishnendu.Sadhukhan@Sun.COM 		/* Search for previously selected PID */
570*10673SKrishnendu.Sadhukhan@Sun.COM 		for (*list_index = 0; *list_index < *list_len &&
571*10673SKrishnendu.Sadhukhan@Sun.COM 		    (*plist)[*list_index] != selected_pid;
572*10673SKrishnendu.Sadhukhan@Sun.COM 		    ++*list_index) {
573*10673SKrishnendu.Sadhukhan@Sun.COM 		}
574*10673SKrishnendu.Sadhukhan@Sun.COM 
575*10673SKrishnendu.Sadhukhan@Sun.COM 		if (*list_index >= *list_len) {
576*10673SKrishnendu.Sadhukhan@Sun.COM 			/*
577*10673SKrishnendu.Sadhukhan@Sun.COM 			 * The previously selected pid is gone.
578*10673SKrishnendu.Sadhukhan@Sun.COM 			 * Select the first one.
579*10673SKrishnendu.Sadhukhan@Sun.COM 			 */
580*10673SKrishnendu.Sadhukhan@Sun.COM 			*list_index = 0;
581*10673SKrishnendu.Sadhukhan@Sun.COM 		}
582*10673SKrishnendu.Sadhukhan@Sun.COM 	} else {
583*10673SKrishnendu.Sadhukhan@Sun.COM 		/* Per-thread mode */
584*10673SKrishnendu.Sadhukhan@Sun.COM 		*list_len = lt_stat_proc_list_create(plist, tlist);
585*10673SKrishnendu.Sadhukhan@Sun.COM 
586*10673SKrishnendu.Sadhukhan@Sun.COM 		/* Search for previously selected PID & TID */
587*10673SKrishnendu.Sadhukhan@Sun.COM 		for (*list_index = 0; *list_index < *list_len;
588*10673SKrishnendu.Sadhukhan@Sun.COM 		    ++*list_index) {
589*10673SKrishnendu.Sadhukhan@Sun.COM 			if ((*plist)[*list_index] == selected_pid &&
590*10673SKrishnendu.Sadhukhan@Sun.COM 			    (*tlist)[*list_index] == selected_tid) {
591*10673SKrishnendu.Sadhukhan@Sun.COM 				break;
592*10673SKrishnendu.Sadhukhan@Sun.COM 			}
593*10673SKrishnendu.Sadhukhan@Sun.COM 		}
594*10673SKrishnendu.Sadhukhan@Sun.COM 
595*10673SKrishnendu.Sadhukhan@Sun.COM 		if (*list_index >= *list_len) {
596*10673SKrishnendu.Sadhukhan@Sun.COM 			/*
597*10673SKrishnendu.Sadhukhan@Sun.COM 			 * The previously selected pid/tid is gone.
598*10673SKrishnendu.Sadhukhan@Sun.COM 			 * Select the first one.
599*10673SKrishnendu.Sadhukhan@Sun.COM 			 */
600*10673SKrishnendu.Sadhukhan@Sun.COM 			for (*list_index = 0;
601*10673SKrishnendu.Sadhukhan@Sun.COM 			    *list_index < *list_len &&
602*10673SKrishnendu.Sadhukhan@Sun.COM 			    (*plist)[*list_index] != selected_pid;
603*10673SKrishnendu.Sadhukhan@Sun.COM 			    ++*list_index) {
604*10673SKrishnendu.Sadhukhan@Sun.COM 			}
605*10673SKrishnendu.Sadhukhan@Sun.COM 		}
606*10673SKrishnendu.Sadhukhan@Sun.COM 
607*10673SKrishnendu.Sadhukhan@Sun.COM 		if (*list_index >= *list_len) {
608*10673SKrishnendu.Sadhukhan@Sun.COM 			/*
609*10673SKrishnendu.Sadhukhan@Sun.COM 			 * The previously selected pid is gone.
610*10673SKrishnendu.Sadhukhan@Sun.COM 			 * Select the first one
611*10673SKrishnendu.Sadhukhan@Sun.COM 			 */
612*10673SKrishnendu.Sadhukhan@Sun.COM 			*list_index = 0;
613*10673SKrishnendu.Sadhukhan@Sun.COM 		}
614*10673SKrishnendu.Sadhukhan@Sun.COM 	}
615*10673SKrishnendu.Sadhukhan@Sun.COM }
616*10673SKrishnendu.Sadhukhan@Sun.COM 
617*10673SKrishnendu.Sadhukhan@Sun.COM /* Print help message when user presses 'h' hot key */
618*10673SKrishnendu.Sadhukhan@Sun.COM static void
619*10673SKrishnendu.Sadhukhan@Sun.COM print_help(void)
620*10673SKrishnendu.Sadhukhan@Sun.COM {
621*10673SKrishnendu.Sadhukhan@Sun.COM 	const char *HELP[] =    {
622*10673SKrishnendu.Sadhukhan@Sun.COM 		TITLE,
623*10673SKrishnendu.Sadhukhan@Sun.COM 		COPYRIGHT,
624*10673SKrishnendu.Sadhukhan@Sun.COM 		"",
625*10673SKrishnendu.Sadhukhan@Sun.COM 		"These single-character commands are available:",
626*10673SKrishnendu.Sadhukhan@Sun.COM 		"<       - Move to previous process/thread.",
627*10673SKrishnendu.Sadhukhan@Sun.COM 		">       - Move to next process/thread.",
628*10673SKrishnendu.Sadhukhan@Sun.COM 		"q       - Exit.",
629*10673SKrishnendu.Sadhukhan@Sun.COM 		"r       - Refresh.",
630*10673SKrishnendu.Sadhukhan@Sun.COM 		"t       - Toggle process/thread mode.",
631*10673SKrishnendu.Sadhukhan@Sun.COM 		"c       - Sort by count.",
632*10673SKrishnendu.Sadhukhan@Sun.COM 		"a       - Sort by average.",
633*10673SKrishnendu.Sadhukhan@Sun.COM 		"m       - Sort by maximum.",
634*10673SKrishnendu.Sadhukhan@Sun.COM 		"p       - Sort by percent.",
635*10673SKrishnendu.Sadhukhan@Sun.COM 		"1       - Show list by causes.",
636*10673SKrishnendu.Sadhukhan@Sun.COM 		"2       - Show list of special entries.",
637*10673SKrishnendu.Sadhukhan@Sun.COM 		"3       - Show list by synchronization objects.",
638*10673SKrishnendu.Sadhukhan@Sun.COM 		"h       - Show this help.",
639*10673SKrishnendu.Sadhukhan@Sun.COM 		"",
640*10673SKrishnendu.Sadhukhan@Sun.COM 		"Press any key to continue..."
641*10673SKrishnendu.Sadhukhan@Sun.COM 	};
642*10673SKrishnendu.Sadhukhan@Sun.COM 	int i;
643*10673SKrishnendu.Sadhukhan@Sun.COM 
644*10673SKrishnendu.Sadhukhan@Sun.COM 	if (!display_initialized) {
645*10673SKrishnendu.Sadhukhan@Sun.COM 		return;
646*10673SKrishnendu.Sadhukhan@Sun.COM 	}
647*10673SKrishnendu.Sadhukhan@Sun.COM 
648*10673SKrishnendu.Sadhukhan@Sun.COM 	for (i = 0; i < sizeof (HELP) / sizeof (HELP[0]); ++i) {
649*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) mvwprintw(stdscr, i, 0, "%s", HELP[i]);
650*10673SKrishnendu.Sadhukhan@Sun.COM 	}
651*10673SKrishnendu.Sadhukhan@Sun.COM 
652*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) refresh();
653*10673SKrishnendu.Sadhukhan@Sun.COM }
654*10673SKrishnendu.Sadhukhan@Sun.COM 
655*10673SKrishnendu.Sadhukhan@Sun.COM /*
656*10673SKrishnendu.Sadhukhan@Sun.COM  * Print title on screen
657*10673SKrishnendu.Sadhukhan@Sun.COM  */
658*10673SKrishnendu.Sadhukhan@Sun.COM static void
659*10673SKrishnendu.Sadhukhan@Sun.COM print_title(void)
660*10673SKrishnendu.Sadhukhan@Sun.COM {
661*10673SKrishnendu.Sadhukhan@Sun.COM 	if (!display_initialized) {
662*10673SKrishnendu.Sadhukhan@Sun.COM 		return;
663*10673SKrishnendu.Sadhukhan@Sun.COM 	}
664*10673SKrishnendu.Sadhukhan@Sun.COM 
665*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) wattrset(titlebar, COLOR_PAIR(LT_COLOR_HEADER));
666*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) wbkgd(titlebar, COLOR_PAIR(LT_COLOR_HEADER));
667*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) werase(titlebar);
668*10673SKrishnendu.Sadhukhan@Sun.COM 
669*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) mvwprintw(titlebar, 0, (screen_width - strlen(TITLE)) / 2,
670*10673SKrishnendu.Sadhukhan@Sun.COM 	    "%s", TITLE);
671*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) wrefresh(titlebar);
672*10673SKrishnendu.Sadhukhan@Sun.COM 
673*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) werase(captionbar);
674*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) mvwprintw(captionbar, 0, 0, "%s",
675*10673SKrishnendu.Sadhukhan@Sun.COM 	    "               Cause                    "
676*10673SKrishnendu.Sadhukhan@Sun.COM 	    "Count      Average     Maximum   Percent");
677*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) wrefresh(captionbar);
678*10673SKrishnendu.Sadhukhan@Sun.COM 
679*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) wattrset(hintbar, COLOR_PAIR(LT_COLOR_HEADER));
680*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) wbkgd(hintbar, COLOR_PAIR(LT_COLOR_HEADER));
681*10673SKrishnendu.Sadhukhan@Sun.COM }
682*10673SKrishnendu.Sadhukhan@Sun.COM 
683*10673SKrishnendu.Sadhukhan@Sun.COM /*
684*10673SKrishnendu.Sadhukhan@Sun.COM  * Handle signal from terminal resize
685*10673SKrishnendu.Sadhukhan@Sun.COM  */
686*10673SKrishnendu.Sadhukhan@Sun.COM /* ARGSUSED */
687*10673SKrishnendu.Sadhukhan@Sun.COM static void
688*10673SKrishnendu.Sadhukhan@Sun.COM on_resize(int sig)
689*10673SKrishnendu.Sadhukhan@Sun.COM {
690*10673SKrishnendu.Sadhukhan@Sun.COM 	lt_gpipe_break("r");
691*10673SKrishnendu.Sadhukhan@Sun.COM }
692*10673SKrishnendu.Sadhukhan@Sun.COM 
693*10673SKrishnendu.Sadhukhan@Sun.COM /*
694*10673SKrishnendu.Sadhukhan@Sun.COM  * Initialize display. Display will be cleared when this function returns.
695*10673SKrishnendu.Sadhukhan@Sun.COM  */
696*10673SKrishnendu.Sadhukhan@Sun.COM void
697*10673SKrishnendu.Sadhukhan@Sun.COM lt_display_init(void)
698*10673SKrishnendu.Sadhukhan@Sun.COM {
699*10673SKrishnendu.Sadhukhan@Sun.COM 	if (display_initialized) {
700*10673SKrishnendu.Sadhukhan@Sun.COM 		return;
701*10673SKrishnendu.Sadhukhan@Sun.COM 	}
702*10673SKrishnendu.Sadhukhan@Sun.COM 
703*10673SKrishnendu.Sadhukhan@Sun.COM 	/* Window resize signal */
704*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) signal(SIGWINCH, on_resize);
705*10673SKrishnendu.Sadhukhan@Sun.COM 
706*10673SKrishnendu.Sadhukhan@Sun.COM 	/* Initialize curses library */
707*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) initscr();
708*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) start_color();
709*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) keypad(stdscr, TRUE);
710*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) nonl();
711*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) cbreak();
712*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) noecho();
713*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) curs_set(0);
714*10673SKrishnendu.Sadhukhan@Sun.COM 
715*10673SKrishnendu.Sadhukhan@Sun.COM 	/* Set up color pairs */
716*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) init_pair(LT_COLOR_DEFAULT, COLOR_WHITE, COLOR_BLACK);
717*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) init_pair(LT_COLOR_HEADER, COLOR_BLACK, COLOR_WHITE);
718*10673SKrishnendu.Sadhukhan@Sun.COM 
719*10673SKrishnendu.Sadhukhan@Sun.COM 	curses_inited = TRUE;
720*10673SKrishnendu.Sadhukhan@Sun.COM 	getmaxyx(stdscr, screen_height, screen_width);
721*10673SKrishnendu.Sadhukhan@Sun.COM 
722*10673SKrishnendu.Sadhukhan@Sun.COM 	if (screen_width < LT_WINDOW_X || screen_height < LT_WINDOW_Y) {
723*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) mvwprintw(stdscr, 0, 0, "Terminal size is too small.");
724*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) mvwprintw(stdscr, 1, 0,
725*10673SKrishnendu.Sadhukhan@Sun.COM 		    "Please resize it to 80x24 or larger.");
726*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) mvwprintw(stdscr, 2, 0, "Press q to quit.");
727*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) refresh();
728*10673SKrishnendu.Sadhukhan@Sun.COM 		return;
729*10673SKrishnendu.Sadhukhan@Sun.COM 	}
730*10673SKrishnendu.Sadhukhan@Sun.COM 
731*10673SKrishnendu.Sadhukhan@Sun.COM 	/* Set up all window panes */
732*10673SKrishnendu.Sadhukhan@Sun.COM 	titlebar = subwin(stdscr, 1, screen_width, 0, 0);
733*10673SKrishnendu.Sadhukhan@Sun.COM 	captionbar = subwin(stdscr, 1, screen_width, 1, 0);
734*10673SKrishnendu.Sadhukhan@Sun.COM 	sysglobal_window = subwin(stdscr, screen_height / 2 - 1,
735*10673SKrishnendu.Sadhukhan@Sun.COM 	    screen_width, 2, 0);
736*10673SKrishnendu.Sadhukhan@Sun.COM 	process_window = subwin(stdscr, screen_height / 2 - 3,
737*10673SKrishnendu.Sadhukhan@Sun.COM 	    screen_width, screen_height / 2 + 1, 0);
738*10673SKrishnendu.Sadhukhan@Sun.COM 	taskbar = subwin(stdscr, 1, screen_width, screen_height - 2, 0);
739*10673SKrishnendu.Sadhukhan@Sun.COM 	hintbar = subwin(stdscr, 1, screen_width, screen_height - 1, 0);
740*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) werase(stdscr);
741*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) refresh();
742*10673SKrishnendu.Sadhukhan@Sun.COM 
743*10673SKrishnendu.Sadhukhan@Sun.COM 	display_initialized = TRUE;
744*10673SKrishnendu.Sadhukhan@Sun.COM 
745*10673SKrishnendu.Sadhukhan@Sun.COM 	print_title();
746*10673SKrishnendu.Sadhukhan@Sun.COM }
747*10673SKrishnendu.Sadhukhan@Sun.COM 
748*10673SKrishnendu.Sadhukhan@Sun.COM /*
749*10673SKrishnendu.Sadhukhan@Sun.COM  * The event loop for display. It displays data on screen and handles hotkey
750*10673SKrishnendu.Sadhukhan@Sun.COM  * presses.
751*10673SKrishnendu.Sadhukhan@Sun.COM  *
752*10673SKrishnendu.Sadhukhan@Sun.COM  * Parameter :
753*10673SKrishnendu.Sadhukhan@Sun.COM  *		duration - returns after 'duration'
754*10673SKrishnendu.Sadhukhan@Sun.COM  *
755*10673SKrishnendu.Sadhukhan@Sun.COM  * The function also returns if user presses 'q', 'Ctrl+C' or 'r'.
756*10673SKrishnendu.Sadhukhan@Sun.COM  *
757*10673SKrishnendu.Sadhukhan@Sun.COM  * Return value:
758*10673SKrishnendu.Sadhukhan@Sun.COM  *		0 - main() exits
759*10673SKrishnendu.Sadhukhan@Sun.COM  *		1 - main() calls it again
760*10673SKrishnendu.Sadhukhan@Sun.COM  */
761*10673SKrishnendu.Sadhukhan@Sun.COM int
762*10673SKrishnendu.Sadhukhan@Sun.COM lt_display_loop(int duration)
763*10673SKrishnendu.Sadhukhan@Sun.COM {
764*10673SKrishnendu.Sadhukhan@Sun.COM 	uint64_t start;
765*10673SKrishnendu.Sadhukhan@Sun.COM 	int remaining;
766*10673SKrishnendu.Sadhukhan@Sun.COM 	struct timeval timeout;
767*10673SKrishnendu.Sadhukhan@Sun.COM 	fd_set read_fd;
768*10673SKrishnendu.Sadhukhan@Sun.COM 	int need_refresh = TRUE;
769*10673SKrishnendu.Sadhukhan@Sun.COM 	pid_t *plist = NULL;
770*10673SKrishnendu.Sadhukhan@Sun.COM 	id_t *tlist = NULL;
771*10673SKrishnendu.Sadhukhan@Sun.COM 	int list_len = 0;
772*10673SKrishnendu.Sadhukhan@Sun.COM 	int list_index = 0;
773*10673SKrishnendu.Sadhukhan@Sun.COM 	int retval = 1;
774*10673SKrishnendu.Sadhukhan@Sun.COM 	int next_snap;
775*10673SKrishnendu.Sadhukhan@Sun.COM 	int gpipe;
776*10673SKrishnendu.Sadhukhan@Sun.COM 
777*10673SKrishnendu.Sadhukhan@Sun.COM 	start = lt_millisecond();
778*10673SKrishnendu.Sadhukhan@Sun.COM 	gpipe = lt_gpipe_readfd();
779*10673SKrishnendu.Sadhukhan@Sun.COM 
780*10673SKrishnendu.Sadhukhan@Sun.COM 	if (!show_help) {
781*10673SKrishnendu.Sadhukhan@Sun.COM 		print_hint(NULL);
782*10673SKrishnendu.Sadhukhan@Sun.COM 		print_sysglobal();
783*10673SKrishnendu.Sadhukhan@Sun.COM 	}
784*10673SKrishnendu.Sadhukhan@Sun.COM 
785*10673SKrishnendu.Sadhukhan@Sun.COM 	get_plist(&plist, &tlist, &list_len, &list_index);
786*10673SKrishnendu.Sadhukhan@Sun.COM 
787*10673SKrishnendu.Sadhukhan@Sun.COM 	for (;;) {
788*10673SKrishnendu.Sadhukhan@Sun.COM 		if (list_len != 0 && need_refresh && !show_help) {
789*10673SKrishnendu.Sadhukhan@Sun.COM 			if (!thread_mode) {
790*10673SKrishnendu.Sadhukhan@Sun.COM 				print_taskbar_process(plist, list_len,
791*10673SKrishnendu.Sadhukhan@Sun.COM 				    list_index);
792*10673SKrishnendu.Sadhukhan@Sun.COM 				print_process(plist[list_index]);
793*10673SKrishnendu.Sadhukhan@Sun.COM 			} else {
794*10673SKrishnendu.Sadhukhan@Sun.COM 				print_taskbar_thread(plist, tlist,
795*10673SKrishnendu.Sadhukhan@Sun.COM 				    list_len, list_index);
796*10673SKrishnendu.Sadhukhan@Sun.COM 				print_thread(plist[list_index],
797*10673SKrishnendu.Sadhukhan@Sun.COM 				    tlist[list_index]);
798*10673SKrishnendu.Sadhukhan@Sun.COM 			}
799*10673SKrishnendu.Sadhukhan@Sun.COM 		}
800*10673SKrishnendu.Sadhukhan@Sun.COM 
801*10673SKrishnendu.Sadhukhan@Sun.COM 		need_refresh = TRUE;	/* Usually we need refresh. */
802*10673SKrishnendu.Sadhukhan@Sun.COM 		remaining = duration - (int)(lt_millisecond() - start);
803*10673SKrishnendu.Sadhukhan@Sun.COM 
804*10673SKrishnendu.Sadhukhan@Sun.COM 		if (remaining <= 0) {
805*10673SKrishnendu.Sadhukhan@Sun.COM 			break;
806*10673SKrishnendu.Sadhukhan@Sun.COM 		}
807*10673SKrishnendu.Sadhukhan@Sun.COM 
808*10673SKrishnendu.Sadhukhan@Sun.COM 		/* Embedded dtrace snap action here. */
809*10673SKrishnendu.Sadhukhan@Sun.COM 		next_snap = lt_dtrace_work(0);
810*10673SKrishnendu.Sadhukhan@Sun.COM 
811*10673SKrishnendu.Sadhukhan@Sun.COM 		if (next_snap == 0) {
812*10673SKrishnendu.Sadhukhan@Sun.COM 			/*
813*10673SKrishnendu.Sadhukhan@Sun.COM 			 * Just did a snap, check time for the next one.
814*10673SKrishnendu.Sadhukhan@Sun.COM 			 */
815*10673SKrishnendu.Sadhukhan@Sun.COM 			next_snap = lt_dtrace_work(0);
816*10673SKrishnendu.Sadhukhan@Sun.COM 		}
817*10673SKrishnendu.Sadhukhan@Sun.COM 
818*10673SKrishnendu.Sadhukhan@Sun.COM 		if (next_snap > 0 && remaining > next_snap) {
819*10673SKrishnendu.Sadhukhan@Sun.COM 			remaining = next_snap;
820*10673SKrishnendu.Sadhukhan@Sun.COM 		}
821*10673SKrishnendu.Sadhukhan@Sun.COM 
822*10673SKrishnendu.Sadhukhan@Sun.COM 		timeout.tv_sec = remaining / 1000;
823*10673SKrishnendu.Sadhukhan@Sun.COM 		timeout.tv_usec = (remaining % 1000) * 1000;
824*10673SKrishnendu.Sadhukhan@Sun.COM 
825*10673SKrishnendu.Sadhukhan@Sun.COM 		FD_ZERO(&read_fd);
826*10673SKrishnendu.Sadhukhan@Sun.COM 		FD_SET(0, &read_fd);
827*10673SKrishnendu.Sadhukhan@Sun.COM 		FD_SET(gpipe, &read_fd);
828*10673SKrishnendu.Sadhukhan@Sun.COM 
829*10673SKrishnendu.Sadhukhan@Sun.COM 		/* Wait for keyboard input, or signal from gpipe */
830*10673SKrishnendu.Sadhukhan@Sun.COM 		if (select(gpipe + 1, &read_fd, NULL, NULL, &timeout) > 0) {
831*10673SKrishnendu.Sadhukhan@Sun.COM 			int k = 0;
832*10673SKrishnendu.Sadhukhan@Sun.COM 
833*10673SKrishnendu.Sadhukhan@Sun.COM 			if (FD_ISSET(gpipe, &read_fd)) {
834*10673SKrishnendu.Sadhukhan@Sun.COM 				/* Data from pipe has priority */
835*10673SKrishnendu.Sadhukhan@Sun.COM 				char ch;
836*10673SKrishnendu.Sadhukhan@Sun.COM 				(void) read(gpipe, &ch, 1);
837*10673SKrishnendu.Sadhukhan@Sun.COM 				k = ch; /* Need this for big-endianness */
838*10673SKrishnendu.Sadhukhan@Sun.COM 			} else {
839*10673SKrishnendu.Sadhukhan@Sun.COM 				k = getch();
840*10673SKrishnendu.Sadhukhan@Sun.COM 			}
841*10673SKrishnendu.Sadhukhan@Sun.COM 
842*10673SKrishnendu.Sadhukhan@Sun.COM 			/*
843*10673SKrishnendu.Sadhukhan@Sun.COM 			 * Check if we need to update the hint line whenever we
844*10673SKrishnendu.Sadhukhan@Sun.COM 			 * get a chance.
845*10673SKrishnendu.Sadhukhan@Sun.COM 			 * NOTE: current implementation depends on
846*10673SKrishnendu.Sadhukhan@Sun.COM 			 * g_config.lt_cfg_snap_interval, but it's OK because it
847*10673SKrishnendu.Sadhukhan@Sun.COM 			 * doesn't have to be precise.
848*10673SKrishnendu.Sadhukhan@Sun.COM 			 */
849*10673SKrishnendu.Sadhukhan@Sun.COM 			print_hint(NULL);
850*10673SKrishnendu.Sadhukhan@Sun.COM 			/*
851*10673SKrishnendu.Sadhukhan@Sun.COM 			 * If help is on display right now, and a key press
852*10673SKrishnendu.Sadhukhan@Sun.COM 			 * happens, we need to clear the help and continue.
853*10673SKrishnendu.Sadhukhan@Sun.COM 			 */
854*10673SKrishnendu.Sadhukhan@Sun.COM 			if (show_help) {
855*10673SKrishnendu.Sadhukhan@Sun.COM 				(void) werase(stdscr);
856*10673SKrishnendu.Sadhukhan@Sun.COM 				(void) refresh();
857*10673SKrishnendu.Sadhukhan@Sun.COM 				print_title();
858*10673SKrishnendu.Sadhukhan@Sun.COM 				print_sysglobal();
859*10673SKrishnendu.Sadhukhan@Sun.COM 				show_help = FALSE;
860*10673SKrishnendu.Sadhukhan@Sun.COM 				/* Drop this key and continue */
861*10673SKrishnendu.Sadhukhan@Sun.COM 				continue;
862*10673SKrishnendu.Sadhukhan@Sun.COM 			}
863*10673SKrishnendu.Sadhukhan@Sun.COM 
864*10673SKrishnendu.Sadhukhan@Sun.COM 			switch (k) {
865*10673SKrishnendu.Sadhukhan@Sun.COM 			case 'Q':
866*10673SKrishnendu.Sadhukhan@Sun.COM 			case 'q':
867*10673SKrishnendu.Sadhukhan@Sun.COM 				retval = 0;
868*10673SKrishnendu.Sadhukhan@Sun.COM 				goto quit;
869*10673SKrishnendu.Sadhukhan@Sun.COM 			case 'R':
870*10673SKrishnendu.Sadhukhan@Sun.COM 			case 'r':
871*10673SKrishnendu.Sadhukhan@Sun.COM 				lt_display_deinit();
872*10673SKrishnendu.Sadhukhan@Sun.COM 				lt_display_init();
873*10673SKrishnendu.Sadhukhan@Sun.COM 				goto quit;
874*10673SKrishnendu.Sadhukhan@Sun.COM 			case 'H':
875*10673SKrishnendu.Sadhukhan@Sun.COM 			case 'h':
876*10673SKrishnendu.Sadhukhan@Sun.COM 				show_help = TRUE;
877*10673SKrishnendu.Sadhukhan@Sun.COM 				(void) werase(stdscr);
878*10673SKrishnendu.Sadhukhan@Sun.COM 				(void) refresh();
879*10673SKrishnendu.Sadhukhan@Sun.COM 				print_help();
880*10673SKrishnendu.Sadhukhan@Sun.COM 				break;
881*10673SKrishnendu.Sadhukhan@Sun.COM 			case ',':
882*10673SKrishnendu.Sadhukhan@Sun.COM 			case '<':
883*10673SKrishnendu.Sadhukhan@Sun.COM 			case KEY_LEFT:
884*10673SKrishnendu.Sadhukhan@Sun.COM 				--list_index;
885*10673SKrishnendu.Sadhukhan@Sun.COM 
886*10673SKrishnendu.Sadhukhan@Sun.COM 				if (list_index < 0) {
887*10673SKrishnendu.Sadhukhan@Sun.COM 					list_index = 0;
888*10673SKrishnendu.Sadhukhan@Sun.COM 				}
889*10673SKrishnendu.Sadhukhan@Sun.COM 
890*10673SKrishnendu.Sadhukhan@Sun.COM 				break;
891*10673SKrishnendu.Sadhukhan@Sun.COM 			case '.':
892*10673SKrishnendu.Sadhukhan@Sun.COM 			case '>':
893*10673SKrishnendu.Sadhukhan@Sun.COM 			case KEY_RIGHT:
894*10673SKrishnendu.Sadhukhan@Sun.COM 				++list_index;
895*10673SKrishnendu.Sadhukhan@Sun.COM 
896*10673SKrishnendu.Sadhukhan@Sun.COM 				if (list_index >= list_len) {
897*10673SKrishnendu.Sadhukhan@Sun.COM 					list_index = list_len - 1;
898*10673SKrishnendu.Sadhukhan@Sun.COM 				}
899*10673SKrishnendu.Sadhukhan@Sun.COM 
900*10673SKrishnendu.Sadhukhan@Sun.COM 				break;
901*10673SKrishnendu.Sadhukhan@Sun.COM 			case 'a':
902*10673SKrishnendu.Sadhukhan@Sun.COM 			case 'A':
903*10673SKrishnendu.Sadhukhan@Sun.COM 				sort_type = LT_SORT_AVG;
904*10673SKrishnendu.Sadhukhan@Sun.COM 				print_sysglobal();
905*10673SKrishnendu.Sadhukhan@Sun.COM 				break;
906*10673SKrishnendu.Sadhukhan@Sun.COM 			case 'p':
907*10673SKrishnendu.Sadhukhan@Sun.COM 			case 'P':
908*10673SKrishnendu.Sadhukhan@Sun.COM 				sort_type = LT_SORT_TOTAL;
909*10673SKrishnendu.Sadhukhan@Sun.COM 				print_sysglobal();
910*10673SKrishnendu.Sadhukhan@Sun.COM 				break;
911*10673SKrishnendu.Sadhukhan@Sun.COM 			case 'm':
912*10673SKrishnendu.Sadhukhan@Sun.COM 			case 'M':
913*10673SKrishnendu.Sadhukhan@Sun.COM 				sort_type = LT_SORT_MAX;
914*10673SKrishnendu.Sadhukhan@Sun.COM 				print_sysglobal();
915*10673SKrishnendu.Sadhukhan@Sun.COM 				break;
916*10673SKrishnendu.Sadhukhan@Sun.COM 			case 'c':
917*10673SKrishnendu.Sadhukhan@Sun.COM 			case 'C':
918*10673SKrishnendu.Sadhukhan@Sun.COM 				sort_type = LT_SORT_COUNT;
919*10673SKrishnendu.Sadhukhan@Sun.COM 				print_sysglobal();
920*10673SKrishnendu.Sadhukhan@Sun.COM 				break;
921*10673SKrishnendu.Sadhukhan@Sun.COM 			case 't':
922*10673SKrishnendu.Sadhukhan@Sun.COM 			case 'T':
923*10673SKrishnendu.Sadhukhan@Sun.COM 				if (plist != NULL) {
924*10673SKrishnendu.Sadhukhan@Sun.COM 					selected_pid = plist[list_index];
925*10673SKrishnendu.Sadhukhan@Sun.COM 				}
926*10673SKrishnendu.Sadhukhan@Sun.COM 
927*10673SKrishnendu.Sadhukhan@Sun.COM 				selected_tid = INVALID_TID;
928*10673SKrishnendu.Sadhukhan@Sun.COM 				thread_mode = !thread_mode;
929*10673SKrishnendu.Sadhukhan@Sun.COM 				get_plist(&plist, &tlist,
930*10673SKrishnendu.Sadhukhan@Sun.COM 				    &list_len, &list_index);
931*10673SKrishnendu.Sadhukhan@Sun.COM 				break;
932*10673SKrishnendu.Sadhukhan@Sun.COM 			case '1':
933*10673SKrishnendu.Sadhukhan@Sun.COM 			case '!':
934*10673SKrishnendu.Sadhukhan@Sun.COM 				current_list_type = LT_LIST_CAUSE;
935*10673SKrishnendu.Sadhukhan@Sun.COM 				print_sysglobal();
936*10673SKrishnendu.Sadhukhan@Sun.COM 				break;
937*10673SKrishnendu.Sadhukhan@Sun.COM 			case '2':
938*10673SKrishnendu.Sadhukhan@Sun.COM 			case '@':
939*10673SKrishnendu.Sadhukhan@Sun.COM 				if (g_config.lt_cfg_low_overhead_mode) {
940*10673SKrishnendu.Sadhukhan@Sun.COM 					lt_display_error("Switching mode is "
941*10673SKrishnendu.Sadhukhan@Sun.COM 					    "not available for '-f low'.");
942*10673SKrishnendu.Sadhukhan@Sun.COM 				} else {
943*10673SKrishnendu.Sadhukhan@Sun.COM 					current_list_type = LT_LIST_SPECIALS;
944*10673SKrishnendu.Sadhukhan@Sun.COM 					print_sysglobal();
945*10673SKrishnendu.Sadhukhan@Sun.COM 				}
946*10673SKrishnendu.Sadhukhan@Sun.COM 
947*10673SKrishnendu.Sadhukhan@Sun.COM 				break;
948*10673SKrishnendu.Sadhukhan@Sun.COM 			case '3':
949*10673SKrishnendu.Sadhukhan@Sun.COM 			case '#':
950*10673SKrishnendu.Sadhukhan@Sun.COM 				if (g_config.lt_cfg_trace_syncobj) {
951*10673SKrishnendu.Sadhukhan@Sun.COM 					current_list_type = LT_LIST_SOBJ;
952*10673SKrishnendu.Sadhukhan@Sun.COM 					print_sysglobal();
953*10673SKrishnendu.Sadhukhan@Sun.COM 				} else if (g_config.lt_cfg_low_overhead_mode) {
954*10673SKrishnendu.Sadhukhan@Sun.COM 					lt_display_error("Switching mode is "
955*10673SKrishnendu.Sadhukhan@Sun.COM 					    "not available for '-f low'.");
956*10673SKrishnendu.Sadhukhan@Sun.COM 				} else {
957*10673SKrishnendu.Sadhukhan@Sun.COM 					lt_display_error("Tracing "
958*10673SKrishnendu.Sadhukhan@Sun.COM 					    "synchronization objects is "
959*10673SKrishnendu.Sadhukhan@Sun.COM 					    "disabled.");
960*10673SKrishnendu.Sadhukhan@Sun.COM 				}
961*10673SKrishnendu.Sadhukhan@Sun.COM 
962*10673SKrishnendu.Sadhukhan@Sun.COM 				break;
963*10673SKrishnendu.Sadhukhan@Sun.COM 			default:
964*10673SKrishnendu.Sadhukhan@Sun.COM 				/* Wake up for nothing; no refresh is needed */
965*10673SKrishnendu.Sadhukhan@Sun.COM 				need_refresh = FALSE;
966*10673SKrishnendu.Sadhukhan@Sun.COM 				break;
967*10673SKrishnendu.Sadhukhan@Sun.COM 			}
968*10673SKrishnendu.Sadhukhan@Sun.COM 		} else {
969*10673SKrishnendu.Sadhukhan@Sun.COM 			need_refresh = FALSE;
970*10673SKrishnendu.Sadhukhan@Sun.COM 		}
971*10673SKrishnendu.Sadhukhan@Sun.COM 	}
972*10673SKrishnendu.Sadhukhan@Sun.COM 
973*10673SKrishnendu.Sadhukhan@Sun.COM quit:
974*10673SKrishnendu.Sadhukhan@Sun.COM 	if (plist != NULL) {
975*10673SKrishnendu.Sadhukhan@Sun.COM 		selected_pid = plist[list_index];
976*10673SKrishnendu.Sadhukhan@Sun.COM 	}
977*10673SKrishnendu.Sadhukhan@Sun.COM 
978*10673SKrishnendu.Sadhukhan@Sun.COM 	if (tlist != NULL) {
979*10673SKrishnendu.Sadhukhan@Sun.COM 		selected_tid = tlist[list_index];
980*10673SKrishnendu.Sadhukhan@Sun.COM 	}
981*10673SKrishnendu.Sadhukhan@Sun.COM 
982*10673SKrishnendu.Sadhukhan@Sun.COM 	lt_stat_proc_list_free(plist, tlist);
983*10673SKrishnendu.Sadhukhan@Sun.COM 
984*10673SKrishnendu.Sadhukhan@Sun.COM 	return (retval);
985*10673SKrishnendu.Sadhukhan@Sun.COM }
986*10673SKrishnendu.Sadhukhan@Sun.COM 
987*10673SKrishnendu.Sadhukhan@Sun.COM /*
988*10673SKrishnendu.Sadhukhan@Sun.COM  * Clean up display.
989*10673SKrishnendu.Sadhukhan@Sun.COM  */
990*10673SKrishnendu.Sadhukhan@Sun.COM void
991*10673SKrishnendu.Sadhukhan@Sun.COM lt_display_deinit(void)
992*10673SKrishnendu.Sadhukhan@Sun.COM {
993*10673SKrishnendu.Sadhukhan@Sun.COM 	if (curses_inited) {
994*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) clear();
995*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) refresh();
996*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) endwin();
997*10673SKrishnendu.Sadhukhan@Sun.COM 	}
998*10673SKrishnendu.Sadhukhan@Sun.COM 
999*10673SKrishnendu.Sadhukhan@Sun.COM 	titlebar = NULL;
1000*10673SKrishnendu.Sadhukhan@Sun.COM 	captionbar = NULL;
1001*10673SKrishnendu.Sadhukhan@Sun.COM 	sysglobal_window = NULL;
1002*10673SKrishnendu.Sadhukhan@Sun.COM 	taskbar = NULL;
1003*10673SKrishnendu.Sadhukhan@Sun.COM 	process_window = NULL;
1004*10673SKrishnendu.Sadhukhan@Sun.COM 	hintbar = NULL;
1005*10673SKrishnendu.Sadhukhan@Sun.COM 	screen_width = 1;
1006*10673SKrishnendu.Sadhukhan@Sun.COM 	screen_height = 1;
1007*10673SKrishnendu.Sadhukhan@Sun.COM 
1008*10673SKrishnendu.Sadhukhan@Sun.COM 	display_initialized = FALSE;
1009*10673SKrishnendu.Sadhukhan@Sun.COM 	curses_inited = FALSE;
1010*10673SKrishnendu.Sadhukhan@Sun.COM }
1011*10673SKrishnendu.Sadhukhan@Sun.COM 
1012*10673SKrishnendu.Sadhukhan@Sun.COM /*
1013*10673SKrishnendu.Sadhukhan@Sun.COM  * Print message when display error happens.
1014*10673SKrishnendu.Sadhukhan@Sun.COM  */
1015*10673SKrishnendu.Sadhukhan@Sun.COM /* ARGSUSED */
1016*10673SKrishnendu.Sadhukhan@Sun.COM void
1017*10673SKrishnendu.Sadhukhan@Sun.COM lt_display_error(const char *fmt, ...)
1018*10673SKrishnendu.Sadhukhan@Sun.COM {
1019*10673SKrishnendu.Sadhukhan@Sun.COM 	va_list vl;
1020*10673SKrishnendu.Sadhukhan@Sun.COM 	char tmp[81];
1021*10673SKrishnendu.Sadhukhan@Sun.COM 	int l;
1022*10673SKrishnendu.Sadhukhan@Sun.COM 
1023*10673SKrishnendu.Sadhukhan@Sun.COM 	va_start(vl, fmt);
1024*10673SKrishnendu.Sadhukhan@Sun.COM 	(void) vsnprintf(tmp, sizeof (tmp), fmt, vl);
1025*10673SKrishnendu.Sadhukhan@Sun.COM 	va_end(vl);
1026*10673SKrishnendu.Sadhukhan@Sun.COM 
1027*10673SKrishnendu.Sadhukhan@Sun.COM 	l = strlen(tmp);
1028*10673SKrishnendu.Sadhukhan@Sun.COM 
1029*10673SKrishnendu.Sadhukhan@Sun.COM 	while (l > 0 && (tmp[l - 1] == '\n' || tmp[l - 1] == '\r')) {
1030*10673SKrishnendu.Sadhukhan@Sun.COM 		tmp[l - 1] = '\0';
1031*10673SKrishnendu.Sadhukhan@Sun.COM 		--l;
1032*10673SKrishnendu.Sadhukhan@Sun.COM 	}
1033*10673SKrishnendu.Sadhukhan@Sun.COM 
1034*10673SKrishnendu.Sadhukhan@Sun.COM 	if (!display_initialized) {
1035*10673SKrishnendu.Sadhukhan@Sun.COM 		(void) fprintf(stderr, "%s\n", tmp);
1036*10673SKrishnendu.Sadhukhan@Sun.COM 	} else if (!show_help) {
1037*10673SKrishnendu.Sadhukhan@Sun.COM 		print_hint(tmp);
1038*10673SKrishnendu.Sadhukhan@Sun.COM 	}
1039*10673SKrishnendu.Sadhukhan@Sun.COM 
1040*10673SKrishnendu.Sadhukhan@Sun.COM }
1041