#ifndef _LIBPMCSTAT_H_
#define _LIBPMCSTAT_H_
#include <sys/_cpuset.h>
#include <sys/queue.h>
#include <stdio.h>
#include <gelf.h>
#define PMCSTAT_ALLOCATE 1
#define NSOCKPAIRFD 2
#define PARENTSOCKET 0
#define CHILDSOCKET 1
#define PMCSTAT_OPEN_FOR_READ 0
#define PMCSTAT_OPEN_FOR_WRITE 1
#define READPIPEFD 0
#define WRITEPIPEFD 1
#define NPIPEFD 2
#define PMCSTAT_NHASH 256
#define PMCSTAT_HASH_MASK 0xFF
#define DEFAULT_SAMPLE_COUNT 65536
typedef const void *pmcstat_interned_string;
struct pmc_plugins;
enum pmcstat_state {
PMCSTAT_FINISHED = 0,
PMCSTAT_EXITING = 1,
PMCSTAT_RUNNING = 2
};
struct pmcstat_ev {
STAILQ_ENTRY(pmcstat_ev) ev_next;
int ev_count;
uint32_t ev_cpu;
int ev_cumulative;
int ev_flags;
int ev_fieldskip;
int ev_fieldwidth;
enum pmc_mode ev_mode;
char *ev_name;
pmc_id_t ev_pmcid;
pmc_value_t ev_saved;
char *ev_spec;
};
struct pmcstat_target {
SLIST_ENTRY(pmcstat_target) pt_next;
pid_t pt_pid;
};
struct pmcstat_args {
int pa_flags;
#define FLAG_HAS_TARGET 0x00000001
#define FLAG_HAS_WAIT_INTERVAL 0x00000002
#define FLAG_HAS_OUTPUT_LOGFILE 0x00000004
#define FLAG_HAS_COMMANDLINE 0x00000008
#define FLAG_HAS_SAMPLING_PMCS 0x00000010
#define FLAG_HAS_COUNTING_PMCS 0x00000020
#define FLAG_HAS_PROCESS_PMCS 0x00000040
#define FLAG_HAS_SYSTEM_PMCS 0x00000080
#define FLAG_HAS_PIPE 0x00000100
#define FLAG_READ_LOGFILE 0x00000200
#define FLAG_DO_GPROF 0x00000400
#define FLAG_HAS_SAMPLESDIR 0x00000800
#define FLAG_DO_PRINT 0x00002000
#define FLAG_DO_CALLGRAPHS 0x00004000
#define FLAG_DO_ANNOTATE 0x00008000
#define FLAG_DO_TOP 0x00010000
#define FLAG_DO_ANALYSIS 0x00020000
#define FLAGS_HAS_CPUMASK 0x00040000
#define FLAG_HAS_DURATION 0x00080000
#define FLAG_DO_WIDE_GPROF_HC 0x00100000
#define FLAG_SKIP_TOP_FN_RES 0x00200000
#define FLAG_FILTER_THREAD_ID 0x00400000
#define FLAG_SHOW_OFFSET 0x00800000
int pa_required;
int pa_pplugin;
int pa_plugin;
int pa_verbosity;
FILE *pa_printfile;
int pa_logfd;
char *pa_inputpath;
char *pa_outputpath;
void *pa_logparser;
const char *pa_fsroot;
const char *pa_samplesdir;
const char *pa_mapfilename;
FILE *pa_graphfile;
int pa_graphdepth;
double pa_interval;
cpuset_t pa_cpumask;
int pa_ctdumpinstr;
int pa_topmode;
int pa_toptty;
int pa_topcolor;
int pa_mergepmc;
double pa_duration;
uint32_t pa_tid;
int pa_argc;
char **pa_argv;
STAILQ_HEAD(, pmcstat_ev) pa_events;
SLIST_HEAD(, pmcstat_target) pa_targets;
};
struct pmcstat_symbol {
pmcstat_interned_string ps_name;
uint64_t ps_start;
uint64_t ps_end;
};
enum pmcstat_image_type {
PMCSTAT_IMAGE_UNKNOWN = 0,
PMCSTAT_IMAGE_INDETERMINABLE,
PMCSTAT_IMAGE_ELF32,
PMCSTAT_IMAGE_ELF64,
PMCSTAT_IMAGE_AOUT
};
struct pmcstat_image {
LIST_ENTRY(pmcstat_image) pi_next;
pmcstat_interned_string pi_execpath;
pmcstat_interned_string pi_samplename;
pmcstat_interned_string pi_fullpath;
pmcstat_interned_string pi_name;
enum pmcstat_image_type pi_type;
uintfptr_t pi_start;
uintfptr_t pi_end;
uintfptr_t pi_entry;
uintfptr_t pi_vaddr;
int pi_isdynamic;
int pi_iskernelmodule;
pmcstat_interned_string pi_dynlinkerpath;
struct pmcstat_symbol *pi_symbols;
size_t pi_symcount;
FILE *pi_addr2line;
LIST_HEAD(,pmcstat_gmonfile) pi_gmlist;
};
extern LIST_HEAD(pmcstat_image_hash_list, pmcstat_image) pmcstat_image_hash[PMCSTAT_NHASH];
struct pmcstat_string {
LIST_ENTRY(pmcstat_string) ps_next;
int ps_len;
int ps_hash;
char *ps_string;
};
struct pmcstat_pcmap {
TAILQ_ENTRY(pmcstat_pcmap) ppm_next;
uintfptr_t ppm_lowpc;
uintfptr_t ppm_highpc;
struct pmcstat_image *ppm_image;
};
struct pmcstat_process {
LIST_ENTRY(pmcstat_process) pp_next;
pid_t pp_pid;
int pp_isactive;
uintfptr_t pp_entryaddr;
TAILQ_HEAD(,pmcstat_pcmap) pp_map;
};
extern LIST_HEAD(pmcstat_process_hash_list, pmcstat_process) pmcstat_process_hash[PMCSTAT_NHASH];
struct pmcstat_pmcrecord {
LIST_ENTRY(pmcstat_pmcrecord) pr_next;
pmc_id_t pr_pmcid;
int pr_pmcin;
pmcstat_interned_string pr_pmcname;
int pr_samples;
int pr_dubious_frames;
struct pmcstat_pmcrecord *pr_merge;
};
extern LIST_HEAD(pmcstat_pmcs, pmcstat_pmcrecord) pmcstat_pmcs;
struct pmc_plugins {
const char *pl_name;
int (*pl_configure)(char *opt);
int (*pl_init)(void);
void (*pl_shutdown)(FILE *mf);
void (*pl_process)(struct pmcstat_process *pp,
struct pmcstat_pmcrecord *pmcr, uint32_t nsamples,
uintfptr_t *cc, int usermode, uint32_t cpu);
void (*pl_initimage)(struct pmcstat_image *pi);
void (*pl_shutdownimage)(struct pmcstat_image *pi);
void (*pl_newpmc)(pmcstat_interned_string ps,
struct pmcstat_pmcrecord *pr);
void (*pl_topdisplay)(void);
int (*pl_topkeypress)(int c, void *w);
};
struct pmcstat_stats {
int ps_exec_aout;
int ps_exec_elf;
int ps_exec_errors;
int ps_exec_indeterminable;
int ps_samples_total;
int ps_samples_skipped;
int ps_samples_unknown_offset;
int ps_samples_indeterminable;
int ps_samples_unknown_function;
int ps_callchain_dubious_frames;
};
__BEGIN_DECLS
int pmcstat_symbol_compare(const void *a, const void *b);
struct pmcstat_symbol *pmcstat_symbol_search(struct pmcstat_image *image,
uintfptr_t addr);
void pmcstat_image_add_symbols(struct pmcstat_image *image, Elf *e,
Elf_Scn *scn, GElf_Shdr *sh);
const char *pmcstat_string_unintern(pmcstat_interned_string _is);
pmcstat_interned_string pmcstat_string_intern(const char *_s);
int pmcstat_string_compute_hash(const char *s);
pmcstat_interned_string pmcstat_string_lookup(const char *_s);
void pmcstat_image_get_elf_params(struct pmcstat_image *image, struct pmcstat_args *args);
struct pmcstat_image *
pmcstat_image_from_path(pmcstat_interned_string internedpath,
int iskernelmodule, struct pmcstat_args *args,
struct pmc_plugins *plugins);
int pmcstat_string_lookup_hash(pmcstat_interned_string _is);
void pmcstat_process_elf_exec(struct pmcstat_process *_pp,
struct pmcstat_image *_image, uintptr_t _baseaddr, uintptr_t _dynaddr,
struct pmcstat_args *args, struct pmc_plugins *plugins,
struct pmcstat_stats *pmcstat_stats);
void pmcstat_image_link(struct pmcstat_process *_pp,
struct pmcstat_image *_i, uintfptr_t _lpc);
void pmcstat_process_aout_exec(struct pmcstat_process *_pp,
struct pmcstat_image *_image, uintptr_t _baseaddr);
void pmcstat_process_exec(struct pmcstat_process *_pp,
pmcstat_interned_string _path, uintptr_t _baseaddr, uintptr_t _dynaddr,
struct pmcstat_args *args, struct pmc_plugins *plugins,
struct pmcstat_stats *pmcstat_stats);
void pmcstat_image_determine_type(struct pmcstat_image *_image, struct pmcstat_args *args);
void pmcstat_image_get_aout_params(struct pmcstat_image *_image, struct pmcstat_args *args);
struct pmcstat_pcmap *pmcstat_process_find_map(struct pmcstat_process *_p,
uintfptr_t _pc);
void pmcstat_initialize_logging(struct pmcstat_process **pmcstat_kernproc,
struct pmcstat_args *args, struct pmc_plugins *plugins,
int *pmcstat_npmcs, int *pmcstat_mergepmc);
void pmcstat_shutdown_logging(struct pmcstat_args *args,
struct pmc_plugins *plugins,
struct pmcstat_stats *pmcstat_stats);
struct pmcstat_process *pmcstat_process_lookup(pid_t _pid, int _allocate);
void pmcstat_clone_event_descriptor(struct pmcstat_ev *ev, const cpuset_t *cpumask, struct pmcstat_args *args);
void pmcstat_create_process(int *pmcstat_sockpair, struct pmcstat_args *args, int pmcstat_kq);
void pmcstat_start_process(int *pmcstat_sockpair);
void pmcstat_attach_pmcs(struct pmcstat_args *args);
struct pmcstat_symbol *pmcstat_symbol_search_by_name(struct pmcstat_process *pp, const char *pi_name, const char *name, uintptr_t *, uintptr_t *);
void pmcstat_string_initialize(void);
void pmcstat_string_shutdown(void);
int pmcstat_analyze_log(struct pmcstat_args *args,
struct pmc_plugins *plugins,
struct pmcstat_stats *pmcstat_stats,
struct pmcstat_process *pmcstat_kernproc,
int pmcstat_mergepmc,
int *pmcstat_npmcs,
int *ps_samples_period);
int pmcstat_open_log(const char *_p, int _mode);
int pmcstat_close_log(struct pmcstat_args *args);
__END_DECLS
#endif