hc
2024-05-10 23fa18eaa71266feff7ba8d83022d9e1cc83c65a
kernel/tools/include/linux/rbtree.h
....@@ -1,20 +1,8 @@
1
+/* SPDX-License-Identifier: GPL-2.0-or-later */
12 /*
23 Red Black Trees
34 (C) 1999 Andrea Arcangeli <andrea@suse.de>
45
5
- This program is free software; you can redistribute it and/or modify
6
- it under the terms of the GNU General Public License as published by
7
- the Free Software Foundation; either version 2 of the License, or
8
- (at your option) any later version.
9
-
10
- This program is distributed in the hope that it will be useful,
11
- but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- GNU General Public License for more details.
14
-
15
- You should have received a copy of the GNU General Public License
16
- along with this program; if not, write to the Free Software
17
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
186
197 linux/include/linux/rbtree.h
208
....@@ -23,7 +11,7 @@
2311 I know it's not the cleaner way, but in C (not in C++) to get
2412 performances and genericity...
2513
26
- See Documentation/rbtree.txt for documentation and samples.
14
+ See Documentation/core-api/rbtree.rst for documentation and samples.
2715 */
2816
2917 #ifndef __TOOLS_LINUX_PERF_RBTREE_H
....@@ -43,13 +31,12 @@
4331 struct rb_node *rb_node;
4432 };
4533
46
-
4734 #define rb_parent(r) ((struct rb_node *)((r)->__rb_parent_color & ~3))
4835
4936 #define RB_ROOT (struct rb_root) { NULL, }
5037 #define rb_entry(ptr, type, member) container_of(ptr, type, member)
5138
52
-#define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL)
39
+#define RB_EMPTY_ROOT(root) (READ_ONCE((root)->rb_node) == NULL)
5340
5441 /* 'empty' nodes are nodes that are known not to be inserted in an rbtree */
5542 #define RB_EMPTY_NODE(node) \
....@@ -90,15 +77,79 @@
9077 ____ptr ? rb_entry(____ptr, type, member) : NULL; \
9178 })
9279
93
-
94
-/*
95
- * Handy for checking that we are not deleting an entry that is
96
- * already in a list, found in block/{blk-throttle,cfq-iosched}.c,
97
- * probably should be moved to lib/rbtree.c...
80
+/**
81
+ * rbtree_postorder_for_each_entry_safe - iterate in post-order over rb_root of
82
+ * given type allowing the backing memory of @pos to be invalidated
83
+ *
84
+ * @pos: the 'type *' to use as a loop cursor.
85
+ * @n: another 'type *' to use as temporary storage
86
+ * @root: 'rb_root *' of the rbtree.
87
+ * @field: the name of the rb_node field within 'type'.
88
+ *
89
+ * rbtree_postorder_for_each_entry_safe() provides a similar guarantee as
90
+ * list_for_each_entry_safe() and allows the iteration to continue independent
91
+ * of changes to @pos by the body of the loop.
92
+ *
93
+ * Note, however, that it cannot handle other modifications that re-order the
94
+ * rbtree it is iterating over. This includes calling rb_erase() on @pos, as
95
+ * rb_erase() may rebalance the tree, causing us to miss some nodes.
9896 */
97
+#define rbtree_postorder_for_each_entry_safe(pos, n, root, field) \
98
+ for (pos = rb_entry_safe(rb_first_postorder(root), typeof(*pos), field); \
99
+ pos && ({ n = rb_entry_safe(rb_next_postorder(&pos->field), \
100
+ typeof(*pos), field); 1; }); \
101
+ pos = n)
102
+
99103 static inline void rb_erase_init(struct rb_node *n, struct rb_root *root)
100104 {
101105 rb_erase(n, root);
102106 RB_CLEAR_NODE(n);
103107 }
108
+
109
+/*
110
+ * Leftmost-cached rbtrees.
111
+ *
112
+ * We do not cache the rightmost node based on footprint
113
+ * size vs number of potential users that could benefit
114
+ * from O(1) rb_last(). Just not worth it, users that want
115
+ * this feature can always implement the logic explicitly.
116
+ * Furthermore, users that want to cache both pointers may
117
+ * find it a bit asymmetric, but that's ok.
118
+ */
119
+struct rb_root_cached {
120
+ struct rb_root rb_root;
121
+ struct rb_node *rb_leftmost;
122
+};
123
+
124
+#define RB_ROOT_CACHED (struct rb_root_cached) { {NULL, }, NULL }
125
+
126
+/* Same as rb_first(), but O(1) */
127
+#define rb_first_cached(root) (root)->rb_leftmost
128
+
129
+static inline void rb_insert_color_cached(struct rb_node *node,
130
+ struct rb_root_cached *root,
131
+ bool leftmost)
132
+{
133
+ if (leftmost)
134
+ root->rb_leftmost = node;
135
+ rb_insert_color(node, &root->rb_root);
136
+}
137
+
138
+static inline void rb_erase_cached(struct rb_node *node,
139
+ struct rb_root_cached *root)
140
+{
141
+ if (root->rb_leftmost == node)
142
+ root->rb_leftmost = rb_next(node);
143
+ rb_erase(node, &root->rb_root);
144
+}
145
+
146
+static inline void rb_replace_node_cached(struct rb_node *victim,
147
+ struct rb_node *new,
148
+ struct rb_root_cached *root)
149
+{
150
+ if (root->rb_leftmost == victim)
151
+ root->rb_leftmost = new;
152
+ rb_replace_node(victim, new, &root->rb_root);
153
+}
154
+
104155 #endif /* __TOOLS_LINUX_PERF_RBTREE_H */