Skip to content
Snippets Groups Projects
builtin-top.c 26.6 KiB
Newer Older
 * builtin-top.c
 *
 * Builtin top command: Display a continuously updated profile of
 * any workload, CPU or specific PID.
 *
 * Copyright (C) 2008, Red Hat Inc, Ingo Molnar <mingo@redhat.com>
 *		 2011, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
 *
 * Improvements and fixes by:
 *
 *   Arjan van de Ven <arjan@linux.intel.com>
 *   Yanmin Zhang <yanmin.zhang@intel.com>
 *   Wu Fengguang <fengguang.wu@intel.com>
 *   Mike Galbraith <efault@gmx.de>
 *   Paul Mackerras <paulus@samba.org>
 *
 * Released under the GPL v2. (and only v2, not any later version)
#include "perf.h"
#include "util/cache.h"
#include "util/color.h"
#include "util/evlist.h"
#include "util/evsel.h"
#include "util/session.h"
#include "util/symbol.h"
#include "util/thread_map.h"
#include "util/util.h"
#include <linux/rbtree.h>
#include "util/parse-options.h"
#include "util/parse-events.h"
#include "util/cpumap.h"
#include "util/xyarray.h"
#include "util/debug.h"

#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <time.h>
#include <sched.h>

#include <sys/syscall.h>
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <sys/prctl.h>
#include <sys/wait.h>
#include <sys/uio.h>
#include <sys/mman.h>

#include <linux/unistd.h>
#include <linux/types.h>

static struct perf_top top = {
	.count_filter		= 5,
	.delay_secs		= 2,
	.target_pid		= -1,
	.target_tid		= -1,
	.freq			= 1000, /* 1 KHz */
};
static bool			use_tui, use_stdio;

static int			default_interval		=      0;
static bool			kptr_restrict_warned;
static bool			vmlinux_warned;
static int			realtime_prio			=      0;
static unsigned int		mmap_pages			=    128;
static struct winsize		winsize;
static const char		*sym_filter			=   NULL;
static int			sym_pcnt_filter			=      5;
void get_term_dimensions(struct winsize *ws)
	char *s = getenv("LINES");

	if (s != NULL) {
		ws->ws_row = atoi(s);
		s = getenv("COLUMNS");
		if (s != NULL) {
			ws->ws_col = atoi(s);
			if (ws->ws_row && ws->ws_col)
				return;
		}
#ifdef TIOCGWINSZ
	if (ioctl(1, TIOCGWINSZ, ws) == 0 &&
	    ws->ws_row && ws->ws_col)
		return;
	ws->ws_row = 25;
	ws->ws_col = 80;
static void update_print_entries(struct winsize *ws)
	if (top.print_entries > 9)
		top.print_entries -= 9;
}

static void sig_winch_handler(int sig __used)
{
	get_term_dimensions(&winsize);
	update_print_entries(&winsize);
static int parse_source(struct hist_entry *he)
	sym = he->ms.sym;
	map = he->ms.map;

	/*
	 * We can't annotate with just /proc/kallsyms
	 */
	if (map->dso->symtab_type == SYMTAB__KALLSYMS) {
		pr_err("Can't annotate %s: No vmlinux file was found in the "
		       "path\n", sym->name);
		sleep(1);
	notes = symbol__annotation(sym);
	if (notes->src != NULL) {
		pthread_mutex_lock(&notes->lock);
	pthread_mutex_lock(&notes->lock);
	if (symbol__alloc_hist(sym, top.evlist->nr_entries) < 0) {
		pthread_mutex_unlock(&notes->lock);
		pr_err("Not enough memory for annotating '%s' symbol!\n",
		       sym->name);
	err = symbol__annotate(sym, map, 0);
	pthread_mutex_unlock(&notes->lock);
static void __zero_source_counters(struct hist_entry *he)
	struct symbol *sym = he->ms.sym;
	symbol__annotate_zero_histograms(sym);
static void record_precise_ip(struct hist_entry *he, int counter, u64 ip)
	struct annotation *notes;
	struct symbol *sym;

	if (he == NULL || he->ms.sym == NULL ||
	    (he != top.sym_filter_entry && use_browser != 1))
	notes = symbol__annotation(sym);
Loading
Loading full blame...