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