aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util')
-rw-r--r--tools/perf/util/rblist.c107
-rw-r--r--tools/perf/util/rblist.h47
2 files changed, 154 insertions, 0 deletions
diff --git a/tools/perf/util/rblist.c b/tools/perf/util/rblist.c
new file mode 100644
index 000000000000..0171fb611004
--- /dev/null
+++ b/tools/perf/util/rblist.c
@@ -0,0 +1,107 @@
1/*
2 * Based on strlist.c by:
3 * (c) 2009 Arnaldo Carvalho de Melo <acme@redhat.com>
4 *
5 * Licensed under the GPLv2.
6 */
7
8#include <errno.h>
9#include <stdio.h>
10#include <stdlib.h>
11
12#include "rblist.h"
13
14int rblist__add_node(struct rblist *rblist, const void *new_entry)
15{
16 struct rb_node **p = &rblist->entries.rb_node;
17 struct rb_node *parent = NULL, *new_node;
18
19 while (*p != NULL) {
20 int rc;
21
22 parent = *p;
23
24 rc = rblist->node_cmp(parent, new_entry);
25 if (rc > 0)
26 p = &(*p)->rb_left;
27 else if (rc < 0)
28 p = &(*p)->rb_right;
29 else
30 return -EEXIST;
31 }
32
33 new_node = rblist->node_new(rblist, new_entry);
34 if (new_node == NULL)
35 return -ENOMEM;
36
37 rb_link_node(new_node, parent, p);
38 rb_insert_color(new_node, &rblist->entries);
39 ++rblist->nr_entries;
40
41 return 0;
42}
43
44void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node)
45{
46 rb_erase(rb_node, &rblist->entries);
47 rblist->node_delete(rblist, rb_node);
48}
49
50struct rb_node *rblist__find(struct rblist *rblist, const void *entry)
51{
52 struct rb_node **p = &rblist->entries.rb_node;
53 struct rb_node *parent = NULL;
54
55 while (*p != NULL) {
56 int rc;
57
58 parent = *p;
59
60 rc = rblist->node_cmp(parent, entry);
61 if (rc > 0)
62 p = &(*p)->rb_left;
63 else if (rc < 0)
64 p = &(*p)->rb_right;
65 else
66 return parent;
67 }
68
69 return NULL;
70}
71
72void rblist__init(struct rblist *rblist)
73{
74 if (rblist != NULL) {
75 rblist->entries = RB_ROOT;
76 rblist->nr_entries = 0;
77 }
78
79 return;
80}
81
82void rblist__delete(struct rblist *rblist)
83{
84 if (rblist != NULL) {
85 struct rb_node *pos, *next = rb_first(&rblist->entries);
86
87 while (next) {
88 pos = next;
89 next = rb_next(pos);
90 rb_erase(pos, &rblist->entries);
91 rblist->node_delete(rblist, pos);
92 }
93 free(rblist);
94 }
95}
96
97struct rb_node *rblist__entry(const struct rblist *rblist, unsigned int idx)
98{
99 struct rb_node *node;
100
101 for (node = rb_first(&rblist->entries); node; node = rb_next(node)) {
102 if (!idx--)
103 return node;
104 }
105
106 return NULL;
107}
diff --git a/tools/perf/util/rblist.h b/tools/perf/util/rblist.h
new file mode 100644
index 000000000000..6d0cae5ae83d
--- /dev/null
+++ b/tools/perf/util/rblist.h
@@ -0,0 +1,47 @@
1#ifndef __PERF_RBLIST_H
2#define __PERF_RBLIST_H
3
4#include <linux/rbtree.h>
5#include <stdbool.h>
6
7/*
8 * create node structs of the form:
9 * struct my_node {
10 * struct rb_node rb_node;
11 * ... my data ...
12 * };
13 *
14 * create list structs of the form:
15 * struct mylist {
16 * struct rblist rblist;
17 * ... my data ...
18 * };
19 */
20
21struct rblist {
22 struct rb_root entries;
23 unsigned int nr_entries;
24
25 int (*node_cmp)(struct rb_node *rbn, const void *entry);
26 struct rb_node *(*node_new)(struct rblist *rlist, const void *new_entry);
27 void (*node_delete)(struct rblist *rblist, struct rb_node *rb_node);
28};
29
30void rblist__init(struct rblist *rblist);
31void rblist__delete(struct rblist *rblist);
32int rblist__add_node(struct rblist *rblist, const void *new_entry);
33void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node);
34struct rb_node *rblist__find(struct rblist *rblist, const void *entry);
35struct rb_node *rblist__entry(const struct rblist *rblist, unsigned int idx);
36
37static inline bool rblist__empty(const struct rblist *rblist)
38{
39 return rblist->nr_entries == 0;
40}
41
42static inline unsigned int rblist__nr_entries(const struct rblist *rblist)
43{
44 return rblist->nr_entries;
45}
46
47#endif /* __PERF_RBLIST_H */