Esempio n. 1
0
void
benchmark::BenchRunner::RunAll(double elapsedTimeForOne)
{
    perf_init();
    std::cout << "#Benchmark" << "," << "count" << "," << "min" << "," << "max" << "," << "average" << ","
              << "min_cycles" << "," << "max_cycles" << "," << "average_cycles" << "\n";

    for (const auto &p: benchmarks()) {
        State state(p.first, elapsedTimeForOne);
        p.second(state);
    }
    perf_fini();
}
Esempio n. 2
0
/*
 * The main function.
 */
int
main(int argc, char *argv[])
{
	int ret = 1, debug_level = 0;
	FILE *log = NULL, *dump = NULL;
	char c;

	/*
	 * The numatop requires some authorities to setup perf and increase the hard limit of
	 * fd. So either the user runs as root or following condtions need to be satisfied.
	 *
	 * 1. Set "-1" in /proc/sys/kernel/perf_event_paranoid to let the non-root be able to
	 *    setup perf. e.g.
	 *    echo -1 > /proc/sys/kernel/perf_event_paranoid
	 *
	 * 2. The CAP_SYS_RESOURCE capability is required to user for increasing the hard
	 *    limit of fd.
	 */

	g_sortkey = SORT_KEY_CPU;
	g_precise = PRECISE_NORMAL;
	g_numatop_pid = getpid();
	g_run_secs = TIME_NSEC_MAX;
	optind = 1;
	opterr = 0;

	/*
	 * Parse command line arguments.
	 */
	while ((c = getopt(argc, argv, "d:l:o:f:t:hf:s:")) != EOF) {
		switch (c) {
		case 'h':
			print_usage(argv[0]);
			ret = 0;
			goto L_EXIT0;

		case 'l':
			debug_level = atoi(optarg);
			if ((debug_level < 0) || (debug_level > 2)) {
				stderr_print("Invalid log_level %d.\n",
				    debug_level);
				print_usage(argv[0]);
				goto L_EXIT0;
			}
			break;

		case 'f':
			if (optarg == NULL) {
				stderr_print("Invalid output file.\n");
				goto L_EXIT0;
			}

			if ((log = fopen(optarg, "w")) == NULL) {
				stderr_print("Cannot open '%s' for writing.\n",
				    optarg);
				goto L_EXIT0;
			}
			break;

		case 's':
			if (optarg == NULL) {
				print_usage(argv[0]);
				goto L_EXIT0;
			}

			if (strcasecmp(optarg, "high") == 0) {
				g_precise = PRECISE_HIGH;
				break;
			}

			if (strcasecmp(optarg, "low") == 0) {
				g_precise = PRECISE_LOW;
				break;
			}

			if (strcasecmp(optarg, "normal") == 0) {
				g_precise = PRECISE_NORMAL;
				break;
			}

			stderr_print("Invalid sampling_precision '%s'.\n",
			    optarg);
			print_usage(argv[0]);
			goto L_EXIT0;

		case 'd':
			if (optarg == NULL) {
				stderr_print("Invalid dump file.\n");
				goto L_EXIT0;
			}

			if ((dump = fopen(optarg, "w")) == NULL) {
				stderr_print("Cannot open '%s' for dump.\n",
				    optarg);
				goto L_EXIT0;
			}
			break;

		case 't':
			g_run_secs = atoi(optarg);
			if (g_run_secs <= 0) {
				stderr_print("Invalid run time %d.\n",
				    g_run_secs);
				print_usage(argv[0]);
				goto L_EXIT0;
			}
			break;

		case ':':
			stderr_print("Missed argument for option %c.\n",
			    optopt);
			print_usage(argv[0]);
			goto L_EXIT0;

		case '?':
			stderr_print("Unrecognized option %c.\n", optopt);
			print_usage(argv[0]);
			goto L_EXIT0;
		}
	}

	if (plat_detect() != 0) {
		stderr_print("CPU is not supported!\n");
		ret = 2;
		goto L_EXIT0;
	}

	/*
	 * It could be failed if user doesn't have authority.
	 */
	(void) ulimit_expand(PERF_FD_NUM);

	/*
	 * Get the number of online cores in system.
	 */
	if ((g_ncpus = sysfs_online_ncpus()) == -1) {
		stderr_print("Platform is not supported "
		    "(numatop supports up to %d CPUs)\n", NCPUS_MAX);
		goto L_EXIT0;
	}

	pagesize_init();
	gettimeofday(&g_tvbase, 0);

	if (debug_init(debug_level, log) != 0) {
		goto L_EXIT1;
	}

	debug_print(NULL, 2, "Detected %d online CPU.\n", g_ncpus);
	log = NULL;
	sym_init();

	if (dump_init(dump) != 0) {
		goto L_EXIT2;
	}

	dump = NULL;

	/*
	 * Calculate how many nanoseconds for a TSC cycle.
	 */
	calibrate();

	/*
	 * Initialize for the "window-switching" table.
	 */
	switch_table_init();

	if (proc_group_init() != 0) {
		goto L_EXIT3;
	}

	if (node_group_init() != 0) {
		stderr_print("The node/cpu number is out of range, \n"
			"numatop supports up to %d nodes and %d CPUs\n",
			NNODES_MAX, NCPUS_MAX);
		goto L_EXIT4;
	}

	if (disp_cons_ctl_init() != 0) {
		goto L_EXIT5;
	}

	/*
	 * Catch signals from terminal.
	 */
	if ((signal(SIGINT, sigint_handler) == SIG_ERR) ||
	    (signal(SIGHUP, sigint_handler) == SIG_ERR) ||
	    (signal(SIGQUIT, sigint_handler) == SIG_ERR) ||
	    (signal(SIGTERM, sigint_handler) == SIG_ERR) ||
	    (signal(SIGPIPE, sigint_handler) == SIG_ERR)) {
		goto L_EXIT6;
	}

	/*
	 * Initialize the perf sampling facility.
	 */
	if (perf_init() != 0) {
		debug_print(NULL, 2, "perf_init() is failed\n");
		goto L_EXIT6;
	}

	/*
	 * Initialize for display and create console thread & display thread.
	 */
	if (disp_init() != 0) {
		perf_fini();
		goto L_EXIT6;
	}

	/*
	 * Wait the disp thread to exit. The disp thread would
	 * exit when user hits the hotkey 'Q' or press "CTRL+C".
	 */
	disp_dispthr_quit_wait();

	/*
	 * Notify cons thread to exit.
	 */
	disp_consthr_quit();
	
	disp_fini();
	stderr_print("NumaTOP is exiting ...\n");
	(void) fflush(stdout);
	ret = 0;

L_EXIT6:
	disp_cons_ctl_fini();

L_EXIT5:
	node_group_fini();

L_EXIT4:
	proc_group_fini();

L_EXIT3:
	dump_fini();

L_EXIT2:
	sym_fini();
	debug_fini();

L_EXIT1:
	exit_msg_print();

L_EXIT0:
	if (dump != NULL) {
		(void) fclose(dump);
	}

	if (log != NULL) {
		(void) fclose(log);
	}

	return (ret);
}
Esempio n. 3
0
/* ARGSUSED */
static void *
disp_handler(void *arg)
{
	disp_flag_t flag;
	int status = 0;
	cmd_t cmd;
	boolean_t quit, pagelist_inited = B_FALSE;
	struct timespec timeout;
	uint64_t start_ms;
	int64_t diff_ms;

	/*
	 * Wait cons thread to complete initialization.
	 */
	if (!consthr_init_wait()) {
		debug_print(NULL, 2, "Timeout for waiting cons thread to "
		    "complete initialization\n");

		/*
		 * The cons thread should exit with error or startup failed,
		 * disp thread stops running.
		 */
		goto L_EXIT;
	}

	/*
	 * NumaTOP contains multiple windows. It uses double linked list
	 * to link all of windows.
	 */
	page_list_init();
	pagelist_inited = B_TRUE;

	timeout_set(&timeout, 0);
	start_ms = current_ms();

	for (;;) {
		status = 0;
		(void) pthread_mutex_lock(&s_disp_ctl.mutex);
		flag = s_disp_ctl.flag;
		while (flag == DISP_FLAG_NONE) {
			status = pthread_cond_timedwait(&s_disp_ctl.cond,
			    &s_disp_ctl.mutex, &timeout);
			flag = s_disp_ctl.flag;
			if (status == ETIMEDOUT) {
				break;
			}
		}

		if (flag == DISP_FLAG_CMD) {
			(void) memcpy(&cmd, &s_disp_ctl.cmd, sizeof (cmd));
		}

		s_disp_ctl.flag = DISP_FLAG_NONE;
		(void) pthread_mutex_unlock(&s_disp_ctl.mutex);

		diff_ms = current_ms() - start_ms;
		if (g_run_secs <= diff_ms / MS_SEC) {
			g_run_secs = TIME_NSEC_MAX;
			debug_print(NULL, 2,
			    "disp: it's time to exit\n");
			continue;
		}

		if ((status == ETIMEDOUT) && (flag == DISP_FLAG_NONE)) {
			if (page_current_get() == NULL) {
				timeout_set(&timeout, DISP_DEFAULT_INTVAL);
				continue;
			}

			/*
			 * Force a 'refresh' operation.
			 */
			CMD_ID_SET(&cmd, CMD_REFRESH_ID);
			cmd_execute(&cmd, NULL);
			timeout_set(&timeout, DISP_DEFAULT_INTVAL);
			continue;
		}

		switch (flag) {
		case DISP_FLAG_QUIT:
			debug_print(NULL, 2,
			    "disp: received DISP_FLAG_QUIT\n");
			goto L_EXIT;

		case DISP_FLAG_CMD:
			cmd_received(&cmd, &quit, &timeout);
			if (quit) {
				debug_print(NULL, 2,
				    "disp thread received CMD_QUIT_ID\n");
				goto L_EXIT;
			}
			break;

		case DISP_FLAG_PROFILING_DATA_READY:
		case DISP_FLAG_CALLCHAIN_DATA_READY:
		case DISP_FLAG_LL_DATA_READY:
		case DISP_FLAG_PQOS_CMT_READY:
			/*
			 * Show the page.
			 */
			(void) page_next_execute(B_FALSE);
			timeout_set(&timeout, DISP_DEFAULT_INTVAL);
			break;

		case DISP_FLAG_PROFILING_DATA_FAIL:
		case DISP_FLAG_CALLCHAIN_DATA_FAIL:
		case DISP_FLAG_LL_DATA_FAIL:
		case DISP_FLAG_PQOS_CMT_FAIL:
			/*
			 * Received the notification that the perf counting
			 * was failed.
			 */
			debug_print(NULL, 2,
			    "disp: profiling/callchain/LL data failed.\n");
			disp_go_home();
			break;

		case DISP_FLAG_SCROLLUP:
			/*
			 * User hits the "UP" key.
			 */
			key_scroll(SCROLL_UP);
			if (status == ETIMEDOUT) {
				timeout_set(&timeout, DISP_DEFAULT_INTVAL);
			}
			break;

		case DISP_FLAG_SCROLLDOWN:
			/*
			 * User hits the "DOWN" key.
			 */
			key_scroll(SCROLL_DOWN);
			if (status == ETIMEDOUT) {
				timeout_set(&timeout, DISP_DEFAULT_INTVAL);
			}
			break;

		case DISP_FLAG_SCROLLENTER:
			/*
			 * User selects a scroll item and hit the "ENTER".
			 */
			scroll_enter();
			if (status == ETIMEDOUT) {
				timeout_set(&timeout, DISP_DEFAULT_INTVAL);
			}
			break;

		default:
			break;
		}
	}

L_EXIT:
	if (pagelist_inited) {
		page_list_fini();
	}

	/*
	 * Let the perf thread exit first.
	 */
	perf_fini();

	debug_print(NULL, 2, "disp thread is exiting\n");
	return (NULL);
}