linux/tools/perf/util/callchain.h
<<
>>
Prefs
   1#ifndef __PERF_CALLCHAIN_H
   2#define __PERF_CALLCHAIN_H
   3
   4#include "../perf.h"
   5#include <linux/list.h>
   6#include <linux/rbtree.h>
   7#include "event.h"
   8#include "symbol.h"
   9
  10enum chain_mode {
  11        CHAIN_NONE,
  12        CHAIN_FLAT,
  13        CHAIN_GRAPH_ABS,
  14        CHAIN_GRAPH_REL
  15};
  16
  17struct callchain_node {
  18        struct callchain_node   *parent;
  19        struct list_head        siblings;
  20        struct list_head        children;
  21        struct list_head        val;
  22        struct rb_node          rb_node; /* to sort nodes in an rbtree */
  23        struct rb_root          rb_root; /* sorted tree of children */
  24        unsigned int            val_nr;
  25        u64                     hit;
  26        u64                     children_hit;
  27};
  28
  29struct callchain_root {
  30        u64                     max_depth;
  31        struct callchain_node   node;
  32};
  33
  34struct callchain_param;
  35
  36typedef void (*sort_chain_func_t)(struct rb_root *, struct callchain_root *,
  37                                 u64, struct callchain_param *);
  38
  39struct callchain_param {
  40        enum chain_mode         mode;
  41        u32                     print_limit;
  42        double                  min_percent;
  43        sort_chain_func_t       sort;
  44};
  45
  46struct callchain_list {
  47        u64                     ip;
  48        struct map_symbol       ms;
  49        struct list_head        list;
  50};
  51
  52/*
  53 * A callchain cursor is a single linked list that
  54 * let one feed a callchain progressively.
  55 * It keeps persitent allocated entries to minimize
  56 * allocations.
  57 */
  58struct callchain_cursor_node {
  59        u64                             ip;
  60        struct map                      *map;
  61        struct symbol                   *sym;
  62        struct callchain_cursor_node    *next;
  63};
  64
  65struct callchain_cursor {
  66        u64                             nr;
  67        struct callchain_cursor_node    *first;
  68        struct callchain_cursor_node    **last;
  69        u64                             pos;
  70        struct callchain_cursor_node    *curr;
  71};
  72
  73static inline void callchain_init(struct callchain_root *root)
  74{
  75        INIT_LIST_HEAD(&root->node.siblings);
  76        INIT_LIST_HEAD(&root->node.children);
  77        INIT_LIST_HEAD(&root->node.val);
  78
  79        root->node.parent = NULL;
  80        root->node.hit = 0;
  81        root->node.children_hit = 0;
  82        root->max_depth = 0;
  83}
  84
  85static inline u64 callchain_cumul_hits(struct callchain_node *node)
  86{
  87        return node->hit + node->children_hit;
  88}
  89
  90int callchain_register_param(struct callchain_param *param);
  91int callchain_append(struct callchain_root *root,
  92                     struct callchain_cursor *cursor,
  93                     u64 period);
  94
  95int callchain_merge(struct callchain_cursor *cursor,
  96                    struct callchain_root *dst, struct callchain_root *src);
  97
  98bool ip_callchain__valid(struct ip_callchain *chain,
  99                         const union perf_event *event);
 100/*
 101 * Initialize a cursor before adding entries inside, but keep
 102 * the previously allocated entries as a cache.
 103 */
 104static inline void callchain_cursor_reset(struct callchain_cursor *cursor)
 105{
 106        cursor->nr = 0;
 107        cursor->last = &cursor->first;
 108}
 109
 110int callchain_cursor_append(struct callchain_cursor *cursor, u64 ip,
 111                            struct map *map, struct symbol *sym);
 112
 113/* Close a cursor writing session. Initialize for the reader */
 114static inline void callchain_cursor_commit(struct callchain_cursor *cursor)
 115{
 116        cursor->curr = cursor->first;
 117        cursor->pos = 0;
 118}
 119
 120/* Cursor reading iteration helpers */
 121static inline struct callchain_cursor_node *
 122callchain_cursor_current(struct callchain_cursor *cursor)
 123{
 124        if (cursor->pos == cursor->nr)
 125                return NULL;
 126
 127        return cursor->curr;
 128}
 129
 130static inline void callchain_cursor_advance(struct callchain_cursor *cursor)
 131{
 132        cursor->curr = cursor->curr->next;
 133        cursor->pos++;
 134}
 135#endif  /* __PERF_CALLCHAIN_H */
 136