Example #1
0
void F_print_thread(void)
{
  print_thread();
  pc++;
}
Example #2
0
/*
 * The event loop for display. It displays data on screen and handles hotkey
 * presses.
 *
 * Parameter :
 *		duration - returns after 'duration'
 *
 * The function also returns if user presses 'q', 'Ctrl+C' or 'r'.
 *
 * Return value:
 *		0 - main() exits
 *		1 - main() calls it again
 */
int
lt_display_loop(int duration)
{
	uint64_t start;
	int remaining;
	struct timeval timeout;
	fd_set read_fd;
	int need_refresh = TRUE;
	pid_t *plist = NULL;
	id_t *tlist = NULL;
	int list_len = 0;
	int list_index = 0;
	int retval = 1;
	int next_snap;
	int gpipe;

	start = lt_millisecond();
	gpipe = lt_gpipe_readfd();

	if (!show_help) {
		print_hint(NULL);
		print_sysglobal();
	}

	get_plist(&plist, &tlist, &list_len, &list_index);

	for (;;) {
		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_empty_process_bar();
			}
		}

		need_refresh = TRUE;	/* Usually we need refresh. */
		remaining = duration - (int)(lt_millisecond() - start);

		if (remaining <= 0) {
			break;
		}

		/* Embedded dtrace snap action here. */
		next_snap = lt_dtrace_work(0);

		if (next_snap == 0) {
			/*
			 * Just did a snap, check time for the next one.
			 */
			next_snap = lt_dtrace_work(0);
		}

		if (next_snap > 0 && remaining > next_snap) {
			remaining = next_snap;
		}

		timeout.tv_sec = remaining / 1000;
		timeout.tv_usec = (remaining % 1000) * 1000;

		FD_ZERO(&read_fd);
		FD_SET(0, &read_fd);
		FD_SET(gpipe, &read_fd);

		/* Wait for keyboard input, or signal from gpipe */
		if (select(gpipe + 1, &read_fd, NULL, NULL, &timeout) > 0) {
			int k = 0;

			if (FD_ISSET(gpipe, &read_fd)) {
				/* Data from pipe has priority */
				char ch;
				(void) read(gpipe, &ch, 1);
				k = ch; /* Need this for big-endianness */
			} else {
				k = getch();
			}

			/*
			 * Check if we need to update the hint line whenever we
			 * get a chance.
			 * NOTE: current implementation depends on
			 * g_config.lt_cfg_snap_interval, but it's OK because it
			 * doesn't have to be precise.
			 */
			print_hint(NULL);
			/*
			 * If help is on display right now, and a key press
			 * happens, we need to clear the help and continue.
			 */
			if (show_help) {
				(void) werase(stdscr);
				(void) refresh();
				print_title();
				print_sysglobal();
				show_help = FALSE;
				/* Drop this key and continue */
				continue;
			}

			switch (k) {
			case 'Q':
			case 'q':
				retval = 0;
				goto quit;
			case 'R':
			case 'r':
				lt_display_deinit();
				lt_display_init();
				goto quit;
			case 'H':
			case 'h':
				show_help = TRUE;
				(void) werase(stdscr);
				(void) refresh();
				print_help();
				break;
			case ',':
			case '<':
			case KEY_LEFT:
				--list_index;

				if (list_index < 0) {
					list_index = 0;
				}

				break;
			case '.':
			case '>':
			case KEY_RIGHT:
				++list_index;

				if (list_index >= list_len) {
					list_index = list_len - 1;
				}

				break;
			case 'a':
			case 'A':
				sort_type = LT_SORT_AVG;
				print_sysglobal();
				break;
			case 'p':
			case 'P':
				sort_type = LT_SORT_TOTAL;
				print_sysglobal();
				break;
			case 'm':
			case 'M':
				sort_type = LT_SORT_MAX;
				print_sysglobal();
				break;
			case 'c':
			case 'C':
				sort_type = LT_SORT_COUNT;
				print_sysglobal();
				break;
			case 't':
			case 'T':
				if (plist != NULL) {
					selected_pid = plist[list_index];
				}

				selected_tid = INVALID_TID;
				thread_mode = !thread_mode;
				get_plist(&plist, &tlist,
				    &list_len, &list_index);
				break;
			case '1':
			case '!':
				current_list_type = LT_LIST_CAUSE;
				print_sysglobal();
				break;
			case '2':
			case '@':
				if (g_config.lt_cfg_low_overhead_mode) {
					lt_display_error("Switching mode is "
					    "not available for '-f low'.");
				} else {
					current_list_type = LT_LIST_SPECIALS;
					print_sysglobal();
				}

				break;
			case '3':
			case '#':
				if (g_config.lt_cfg_trace_syncobj) {
					current_list_type = LT_LIST_SOBJ;
					print_sysglobal();
				} else if (g_config.lt_cfg_low_overhead_mode) {
					lt_display_error("Switching mode is "
					    "not available for '-f low'.");
				} else {
					lt_display_error("Tracing "
					    "synchronization objects is "
					    "disabled.");
				}

				break;
			default:
				/* Wake up for nothing; no refresh is needed */
				need_refresh = FALSE;
				break;
			}
		} else {
			need_refresh = FALSE;
		}
	}

quit:
	if (plist != NULL) {
		selected_pid = plist[list_index];
	}

	if (tlist != NULL) {
		selected_tid = tlist[list_index];
	}

	lt_stat_proc_list_free(plist, tlist);

	return (retval);
}