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 "builtin.h"
#include "util/annotate.h"
#include "util/color.h"
#include "util/session.h"
#include "util/symbol.h"
#include "util/thread.h"
#include "util/thread_map.h"
#include "util/top.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/sort.h"
#include "util/debug.h"
#include <assert.h>
#include <fcntl.h>

Mike Galbraith
committed
#include <termios.h>
#include <unistd.h>
#include <inttypes.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 */
};

Ian Munsie
committed
static bool system_wide = false;
static bool use_tui, use_stdio;
static int default_interval = 0;
static bool kptr_restrict_warned;
static bool vmlinux_warned;

Ian Munsie
committed
static bool inherit = false;
static int realtime_prio = 0;

Ian Munsie
committed
static bool group = false;
static unsigned int mmap_pages = 128;

Ian Munsie
committed
static bool dump_symtab = false;
static struct winsize winsize;
static const char *sym_filter = NULL;
static int sym_pcnt_filter = 5;

Mike Galbraith
committed
/*
* Source functions
*/
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)
top.print_entries = ws->ws_row;
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)

Mike Galbraith
committed
{
struct symbol *sym;
struct annotation *notes;
struct map *map;
int err = -1;

Mike Galbraith
committed
if (!he || !he->ms.sym)
return -1;
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);
return -1;
}
notes = symbol__annotation(sym);
if (notes->src != NULL) {
pthread_mutex_lock(¬es->lock);

Mike Galbraith
committed
goto out_assign;
}
pthread_mutex_lock(¬es->lock);

Mike Galbraith
committed
if (symbol__alloc_hist(sym, top.evlist->nr_entries) < 0) {
pthread_mutex_unlock(¬es->lock);
pr_err("Not enough memory for annotating '%s' symbol!\n",
sym->name);

Mike Galbraith
committed
}
err = symbol__annotate(sym, map, 0);
if (err == 0) {

Mike Galbraith
committed
out_assign:
top.sym_filter_entry = he;
}
pthread_mutex_unlock(¬es->lock);
return err;

Mike Galbraith
committed
}
static void __zero_source_counters(struct hist_entry *he)

Mike Galbraith
committed
{
struct symbol *sym = he->ms.sym;
symbol__annotate_zero_histograms(sym);

Mike Galbraith
committed
}
static void record_precise_ip(struct hist_entry *he, int counter, u64 ip)

Mike Galbraith
committed
{
struct annotation *notes;
struct symbol *sym;
if (he == NULL || he->ms.sym == NULL ||
(he != top.sym_filter_entry && use_browser != 1))

Mike Galbraith
committed
return;
sym = he->ms.sym;
notes = symbol__annotation(sym);
Loading
Loading full blame...