diff options
Diffstat (limited to 'usr/src/cmd/latencytop')
| -rw-r--r-- | usr/src/cmd/latencytop/common/display.c | 50 | ||||
| -rw-r--r-- | usr/src/cmd/latencytop/common/dwrapper.c | 25 | ||||
| -rw-r--r-- | usr/src/cmd/latencytop/common/latencytop.c | 60 | ||||
| -rw-r--r-- | usr/src/cmd/latencytop/common/latencytop.d | 19 | ||||
| -rw-r--r-- | usr/src/cmd/latencytop/common/latencytop.h | 2 |
5 files changed, 138 insertions, 18 deletions
diff --git a/usr/src/cmd/latencytop/common/display.c b/usr/src/cmd/latencytop/common/display.c index edc2c20ae1..723f9873a7 100644 --- a/usr/src/cmd/latencytop/common/display.c +++ b/usr/src/cmd/latencytop/common/display.c @@ -272,6 +272,31 @@ print_current_mode() } /* + * Print process window bar when the list is empty. + */ +static void +print_empty_process_bar() +{ + char header[256]; + + if (!display_initialized) { + return; + } + + (void) werase(process_window); + (void) wattron(process_window, A_REVERSE); + (void) snprintf(header, sizeof (header), + "No process/thread data is available"); + fill_space_right(header, screen_width, sizeof (header)); + (void) mvwprintw(process_window, 0, 0, "%s", header); + + print_current_mode(); + (void) wattroff(process_window, A_REVERSE); + + (void) wrefresh(process_window); +} + +/* * Print per-process statistics in process pane. * This is called when mode of operation is process. */ @@ -521,7 +546,7 @@ print_hint(const char *hint) "Press 'r' to refresh immediately.", "Press 't' to toggle Process/Thread display mode.", "Press 'h' for help.", - "Use 'c', 'a', 'm', 'p' to change sort criteria." + "Use 'c', 'a', 'm', 'p' to change sort criteria.", "Use '1', '2', '3' to switch between windows." }; const uint64_t update_interval = 5000; /* 5 seconds */ @@ -565,7 +590,6 @@ get_plist(pid_t **plist, id_t **tlist, int *list_len, int *list_index) if (!thread_mode) { /* Per-process mode */ *list_len = lt_stat_proc_list_create(plist, NULL); - /* Search for previously selected PID */ for (*list_index = 0; *list_index < *list_len && (*plist)[*list_index] != selected_pid; @@ -785,16 +809,20 @@ lt_display_loop(int duration) get_plist(&plist, &tlist, &list_len, &list_index); for (;;) { - if (list_len != 0 && need_refresh && !show_help) { - if (!thread_mode) { - print_taskbar_process(plist, list_len, - list_index); - print_process(plist[list_index]); + if (need_refresh && !show_help) { + if (list_len != 0) { + if (!thread_mode) { + print_taskbar_process(plist, list_len, + list_index); + print_process(plist[list_index]); + } else { + print_taskbar_thread(plist, tlist, + list_len, list_index); + print_thread(plist[list_index], + tlist[list_index]); + } } else { - print_taskbar_thread(plist, tlist, - list_len, list_index); - print_thread(plist[list_index], - tlist[list_index]); + print_empty_process_bar(); } } diff --git a/usr/src/cmd/latencytop/common/dwrapper.c b/usr/src/cmd/latencytop/common/dwrapper.c index f634065e38..851c581af7 100644 --- a/usr/src/cmd/latencytop/common/dwrapper.c +++ b/usr/src/cmd/latencytop/common/dwrapper.c @@ -402,6 +402,7 @@ lt_dtrace_init(void) dtrace_proginfo_t info; int err; FILE *fp_script = NULL; + char tmp[64]; pid_self = getpid(); @@ -439,7 +440,27 @@ lt_dtrace_init(void) if ((err = dtrace_setopt(g_dtp, "define", "ENABLE_SCHED")) != 0) { lt_display_error( - "Failed to set option ENABLE_SYNCOBJ.\n"); + "Failed to set option ENABLE_SCHED.\n"); + return (err); + } + } + + if (g_config.lt_cfg_trace_pid != 0) { + (void) snprintf(tmp, sizeof (tmp), "TRACE_PID=%u", + g_config.lt_cfg_trace_pid); + if ((err = dtrace_setopt(g_dtp, "define", tmp)) != 0) { + lt_display_error( + "Failed to set option TRACE_PID.\n"); + return (err); + } + } + + if (g_config.lt_cfg_trace_pgid != 0) { + (void) snprintf(tmp, sizeof (tmp), "TRACE_PGID=%u", + g_config.lt_cfg_trace_pgid); + if ((err = dtrace_setopt(g_dtp, "define", tmp)) != 0) { + lt_display_error( + "Failed to set option TRACE_PGID.\n"); return (err); } } @@ -448,7 +469,7 @@ lt_dtrace_init(void) if ((err = dtrace_setopt(g_dtp, "define", "ENABLE_LOW_OVERHEAD")) != 0) { lt_display_error( - "Failed to set option ENABLE_SYNCOBJ.\n"); + "Failed to set option ENABLE_LOW_OVERHEAD.\n"); return (err); } } diff --git a/usr/src/cmd/latencytop/common/latencytop.c b/usr/src/cmd/latencytop/common/latencytop.c index 154dffb699..65778798bd 100644 --- a/usr/src/cmd/latencytop/common/latencytop.c +++ b/usr/src/cmd/latencytop/common/latencytop.c @@ -53,7 +53,8 @@ typedef enum { LT_CMDOPT_F_SCHED, LT_CMDOPT_F_SOBJ, LT_CMDOPT_F_LOW, - LT_CMDOPT__LAST /* Must be last one */ + LT_CMDOPT_SELECT, + LT_CMDOPT__LAST /* Must be the last one */ } lt_cmd_option_id_t; /* @@ -77,6 +78,7 @@ check_opt_dup(lt_cmd_option_id_t id, uint64_t value) { "-f [no]sched is set more than once with different values.", "-f [no]sobj is set more than once with different values.", "-f [no]low is set more than once with different values.", + "-s is set more than once with different values." }; g_assert(sizeof (errmsg)/sizeof (errmsg[0]) == (int)LT_CMDOPT__LAST); @@ -142,7 +144,10 @@ print_usage(const char *execname, int long_help) " [no]low:\n" " Lower overhead by sampling small latencies.\n" " -l, --log-period TIME\n" - " Write and restart log every TIME seconds, TIME >= 60\n"); + " Write and restart log every TIME seconds, TIME >= 60\n" + " -s --select [ pid=<pid> | pgid=<pgid> ]\n" + " Monitor only the given process or processes in the " + "given process group.\n"); } /* @@ -185,7 +190,7 @@ to_int(const char *str, int *result) int main(int argc, char *argv[]) { - const char *opt_string = "t:o:k:hf:l:c:"; + const char *opt_string = "t:o:k:hf:l:c:s:"; struct option const longopts[] = { {"interval", required_argument, NULL, 't'}, {"output-log-file", required_argument, NULL, 'o'}, @@ -194,6 +199,7 @@ main(int argc, char *argv[]) {"feature", required_argument, NULL, 'f'}, {"log-period", required_argument, NULL, 'l'}, {"config", required_argument, NULL, 'c'}, + {"select", required_argument, NULL, 's'}, {NULL, 0, NULL, 0} }; @@ -213,6 +219,9 @@ main(int argc, char *argv[]) uint64_t current_time; uint64_t delta_time; char logfile[PATH_MAX] = ""; + int select_id; + int select_value; + char *select_str; boolean_t no_dtrace_cleanup = B_TRUE; lt_gpipe_init(); @@ -224,6 +233,8 @@ main(int argc, char *argv[]) g_config.lt_cfg_trace_sched = 0; g_config.lt_cfg_trace_syncobj = 1; g_config.lt_cfg_low_overhead_mode = 0; + g_config.lt_cfg_trace_pid = 0; + g_config.lt_cfg_trace_pgid = 0; /* dtrace snapshot every 1 second */ g_config.lt_cfg_snap_interval = 1000; #ifdef EMBED_CONFIGS @@ -354,6 +365,47 @@ main(int argc, char *argv[]) } break; + case 's': + if (strncmp(optarg, "pid=", 4) == 0) { + select_id = 0; + select_str = &optarg[4]; + } else if (strncmp(optarg, "pgid=", 5) == 0) { + select_id = 1; + select_str = &optarg[5]; + } else { + lt_display_error( + "Invalid select option: %s\n", optarg); + unknown_option = TRUE; + break; + } + + if (to_int(select_str, &select_value) != 0) { + lt_display_error( + "Invalid select option: %s\n", optarg); + unknown_option = TRUE; + break; + } + + if (select_value <= 0) { + lt_display_error( + "Process/process group ID must be " + "greater than 0: %s\n", optarg); + unknown_option = TRUE; + break; + } + + if (check_opt_dup(LT_CMDOPT_SELECT, + (((uint64_t)select_id) << 32) | select_value)) { + unknown_option = TRUE; + break; + } + + if (select_id == 0) { + g_config.lt_cfg_trace_pid = select_value; + } else { + g_config.lt_cfg_trace_pgid = select_value; + } + break; default: unknown_option = TRUE; break; @@ -429,7 +481,7 @@ main(int argc, char *argv[]) } /* - * Interval when we call dtrace_status() and collect + * Interval when we call dtrace_status() and collect * aggregated data. */ if (tsleep > g_config.lt_cfg_snap_interval) { diff --git a/usr/src/cmd/latencytop/common/latencytop.d b/usr/src/cmd/latencytop/common/latencytop.d index 95381b12de..c6686fa3b5 100644 --- a/usr/src/cmd/latencytop/common/latencytop.d +++ b/usr/src/cmd/latencytop/common/latencytop.d @@ -39,12 +39,29 @@ #pragma D option zdefs #if defined(ENABLE_SCHED) +#if defined(TRACE_PID) +#define TRACE_FILTER / pid == 0 || pid == TRACE_PID / +#define TRACE_FILTER_COND(a) / (pid == 0 || pid == TRACE_PID) && (a) / +#elif defined(TRACE_PGID) +#define TRACE_FILTER / pid == 0 || curpsinfo->pr_pgid == TRACE_PGID / +#define TRACE_FILTER_COND(a) + / (pid == 0 || curpsinfo->pr_pgid == TRACE_PGID) && (a) / +#else #define TRACE_FILTER #define TRACE_FILTER_COND(a) / (a) / +#endif +#else /* ENABLE_SCHED */ +#if defined(TRACE_PID) +#define TRACE_FILTER / pid == TRACE_PID / +#define TRACE_FILTER_COND(a) / (pid == TRACE_PID) && (a) / +#elif defined(TRACE_PGID) +#define TRACE_FILTER / curpsinfo->pr_pgid == TRACE_PGID / +#define TRACE_FILTER_COND(a) / (curpsinfo->pr_pgid == TRACE_PGID) && (a) / #else #define TRACE_FILTER / pid != 0 / -#define TRACE_FILTER_COND(a) / pid != 0 && (a) / +#define TRACE_FILTER_COND(a) / (pid != 0) && (a) / #endif +#endif /* ENABLE_SCHED */ /* Threshold to filter WAKEABLE latencies. */ #define FILTER_THRESHOLD 5000000 diff --git a/usr/src/cmd/latencytop/common/latencytop.h b/usr/src/cmd/latencytop/common/latencytop.h index ee77dee3b1..d1cd3483c3 100644 --- a/usr/src/cmd/latencytop/common/latencytop.h +++ b/usr/src/cmd/latencytop/common/latencytop.h @@ -148,6 +148,8 @@ typedef struct { int lt_cfg_low_overhead_mode; int lt_cfg_snap_interval; char *lt_cfg_config_name; + unsigned int lt_cfg_trace_pid; + unsigned int lt_cfg_trace_pgid; } lt_config_t; extern lt_config_t g_config; /* The global settings */ |
