/*
* 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>
*
* 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 "perf.h"
#include "util/symbol.h"
#include "util/color.h"
#include "util/util.h"
#include <linux/rbtree.h>
#include "util/parse-options.h"
#include "util/parse-events.h"
#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <sched.h>
#include <pthread.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 int fd[MAX_NR_CPUS][MAX_COUNTERS];
static int system_wide = 0;
static int default_interval = 100000;
static int count_filter = 5;
static int print_entries = 15;
static int target_pid = -1;
static int inherit = 0;
static int profile_cpu = -1;
static int nr_cpus = 0;
static unsigned int realtime_prio = 0;
static int group = 0;
static unsigned int page_size;
static unsigned int mmap_pages = 16;
static int freq = 0;
static int verbose = 0;
static char *vmlinux = NULL;
static int delay_secs = 2;
static int zero;
static int dump_symtab;
/*
* Source
*/
struct source_line {
u64 eip;
unsigned long count[MAX_COUNTERS];
char *line;
struct source_line *next;
};
static char *sym_filter = NULL;
struct sym_entry *sym_filter_entry = NULL;
static int sym_pcnt_filter = 5;
static int sym_counter = 0;
/*
* Symbols
*/
static u64 min_ip;
static u64 max_ip = -1ll;
struct sym_entry {
struct rb_node rb_node;
struct list_head node;
unsigned long count[MAX_COUNTERS];
unsigned long snap_count;
double weight;
int skip;
struct source_line *source;
struct source_line *lines;
struct source_line **lines_tail;
pthread_mutex_t source_lock;
};
/*
* Source functions
*/
static void parse_source(struct sym_entry *syme)
{
struct symbol *sym;
struct module *module;
struct section *section = NULL;
FILE *file;
char command[PATH_MAX*2], *path = vmlinux;
u64 start, end, len;
if (!syme)
return;
if (syme->lines) {
pthread_mutex_lock(&syme->source_lock);
goto out_assign;
}
sym = (struct symbol *)(syme + 1);
module = sym->module