]>
git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blob - tools/perf/util/call-path.c
1 // SPDX-License-Identifier: GPL-2.0-only
3 * call-path.h: Manipulate a tree data structure containing function call paths
4 * Copyright (c) 2014, Intel Corporation.
7 #include <linux/rbtree.h>
8 #include <linux/list.h>
11 #include "call-path.h"
13 static void call_path__init(struct call_path
*cp
, struct call_path
*parent
,
14 struct symbol
*sym
, u64 ip
, bool in_kernel
)
18 cp
->ip
= sym
? 0 : ip
;
20 cp
->in_kernel
= in_kernel
;
21 RB_CLEAR_NODE(&cp
->rb_node
);
22 cp
->children
= RB_ROOT
;
25 struct call_path_root
*call_path_root__new(void)
27 struct call_path_root
*cpr
;
29 cpr
= zalloc(sizeof(struct call_path_root
));
32 call_path__init(&cpr
->call_path
, NULL
, NULL
, 0, false);
33 INIT_LIST_HEAD(&cpr
->blocks
);
37 void call_path_root__free(struct call_path_root
*cpr
)
39 struct call_path_block
*pos
, *n
;
41 list_for_each_entry_safe(pos
, n
, &cpr
->blocks
, node
) {
48 static struct call_path
*call_path__new(struct call_path_root
*cpr
,
49 struct call_path
*parent
,
50 struct symbol
*sym
, u64 ip
,
53 struct call_path_block
*cpb
;
57 if (cpr
->next
< cpr
->sz
) {
58 cpb
= list_last_entry(&cpr
->blocks
, struct call_path_block
,
61 cpb
= zalloc(sizeof(struct call_path_block
));
64 list_add_tail(&cpb
->node
, &cpr
->blocks
);
65 cpr
->sz
+= CALL_PATH_BLOCK_SIZE
;
68 n
= cpr
->next
++ & CALL_PATH_BLOCK_MASK
;
71 call_path__init(cp
, parent
, sym
, ip
, in_kernel
);
76 struct call_path
*call_path__findnew(struct call_path_root
*cpr
,
77 struct call_path
*parent
,
78 struct symbol
*sym
, u64 ip
, u64 ks
)
81 struct rb_node
*node_parent
= NULL
;
83 bool in_kernel
= ip
>= ks
;
89 return call_path__new(cpr
, parent
, sym
, ip
, in_kernel
);
91 p
= &parent
->children
.rb_node
;
94 cp
= rb_entry(node_parent
, struct call_path
, rb_node
);
96 if (cp
->sym
== sym
&& cp
->ip
== ip
)
99 if (sym
< cp
->sym
|| (sym
== cp
->sym
&& ip
< cp
->ip
))
105 cp
= call_path__new(cpr
, parent
, sym
, ip
, in_kernel
);
109 rb_link_node(&cp
->rb_node
, node_parent
, p
);
110 rb_insert_color(&cp
->rb_node
, &parent
->children
);