Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tools: Copy rbtree_augmented.h from the kernel

To complete the transitioning to not to share the same files with the
kernel, also moving it from tools/perf/include/linux/ to
tools/include/linux to make the whoke rbtree kit to other tools/ living
codebases.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-5bxyehixafckqm6ez25alnfo@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

+246 -3
+245
tools/include/linux/rbtree_augmented.h
··· 1 + /* 2 + Red Black Trees 3 + (C) 1999 Andrea Arcangeli <andrea@suse.de> 4 + (C) 2002 David Woodhouse <dwmw2@infradead.org> 5 + (C) 2012 Michel Lespinasse <walken@google.com> 6 + 7 + This program is free software; you can redistribute it and/or modify 8 + it under the terms of the GNU General Public License as published by 9 + the Free Software Foundation; either version 2 of the License, or 10 + (at your option) any later version. 11 + 12 + This program is distributed in the hope that it will be useful, 13 + but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + GNU General Public License for more details. 16 + 17 + You should have received a copy of the GNU General Public License 18 + along with this program; if not, write to the Free Software 19 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 + 21 + tools/linux/include/linux/rbtree_augmented.h 22 + 23 + Copied from: 24 + linux/include/linux/rbtree_augmented.h 25 + */ 26 + 27 + #ifndef _TOOLS_LINUX_RBTREE_AUGMENTED_H 28 + #define _TOOLS_LINUX_RBTREE_AUGMENTED_H 29 + 30 + #include <linux/compiler.h> 31 + #include <linux/rbtree.h> 32 + 33 + /* 34 + * Please note - only struct rb_augment_callbacks and the prototypes for 35 + * rb_insert_augmented() and rb_erase_augmented() are intended to be public. 36 + * The rest are implementation details you are not expected to depend on. 37 + * 38 + * See Documentation/rbtree.txt for documentation and samples. 39 + */ 40 + 41 + struct rb_augment_callbacks { 42 + void (*propagate)(struct rb_node *node, struct rb_node *stop); 43 + void (*copy)(struct rb_node *old, struct rb_node *new); 44 + void (*rotate)(struct rb_node *old, struct rb_node *new); 45 + }; 46 + 47 + extern void __rb_insert_augmented(struct rb_node *node, struct rb_root *root, 48 + void (*augment_rotate)(struct rb_node *old, struct rb_node *new)); 49 + /* 50 + * Fixup the rbtree and update the augmented information when rebalancing. 51 + * 52 + * On insertion, the user must update the augmented information on the path 53 + * leading to the inserted node, then call rb_link_node() as usual and 54 + * rb_augment_inserted() instead of the usual rb_insert_color() call. 55 + * If rb_augment_inserted() rebalances the rbtree, it will callback into 56 + * a user provided function to update the augmented information on the 57 + * affected subtrees. 58 + */ 59 + static inline void 60 + rb_insert_augmented(struct rb_node *node, struct rb_root *root, 61 + const struct rb_augment_callbacks *augment) 62 + { 63 + __rb_insert_augmented(node, root, augment->rotate); 64 + } 65 + 66 + #define RB_DECLARE_CALLBACKS(rbstatic, rbname, rbstruct, rbfield, \ 67 + rbtype, rbaugmented, rbcompute) \ 68 + static inline void \ 69 + rbname ## _propagate(struct rb_node *rb, struct rb_node *stop) \ 70 + { \ 71 + while (rb != stop) { \ 72 + rbstruct *node = rb_entry(rb, rbstruct, rbfield); \ 73 + rbtype augmented = rbcompute(node); \ 74 + if (node->rbaugmented == augmented) \ 75 + break; \ 76 + node->rbaugmented = augmented; \ 77 + rb = rb_parent(&node->rbfield); \ 78 + } \ 79 + } \ 80 + static inline void \ 81 + rbname ## _copy(struct rb_node *rb_old, struct rb_node *rb_new) \ 82 + { \ 83 + rbstruct *old = rb_entry(rb_old, rbstruct, rbfield); \ 84 + rbstruct *new = rb_entry(rb_new, rbstruct, rbfield); \ 85 + new->rbaugmented = old->rbaugmented; \ 86 + } \ 87 + static void \ 88 + rbname ## _rotate(struct rb_node *rb_old, struct rb_node *rb_new) \ 89 + { \ 90 + rbstruct *old = rb_entry(rb_old, rbstruct, rbfield); \ 91 + rbstruct *new = rb_entry(rb_new, rbstruct, rbfield); \ 92 + new->rbaugmented = old->rbaugmented; \ 93 + old->rbaugmented = rbcompute(old); \ 94 + } \ 95 + rbstatic const struct rb_augment_callbacks rbname = { \ 96 + rbname ## _propagate, rbname ## _copy, rbname ## _rotate \ 97 + }; 98 + 99 + 100 + #define RB_RED 0 101 + #define RB_BLACK 1 102 + 103 + #define __rb_parent(pc) ((struct rb_node *)(pc & ~3)) 104 + 105 + #define __rb_color(pc) ((pc) & 1) 106 + #define __rb_is_black(pc) __rb_color(pc) 107 + #define __rb_is_red(pc) (!__rb_color(pc)) 108 + #define rb_color(rb) __rb_color((rb)->__rb_parent_color) 109 + #define rb_is_red(rb) __rb_is_red((rb)->__rb_parent_color) 110 + #define rb_is_black(rb) __rb_is_black((rb)->__rb_parent_color) 111 + 112 + static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p) 113 + { 114 + rb->__rb_parent_color = rb_color(rb) | (unsigned long)p; 115 + } 116 + 117 + static inline void rb_set_parent_color(struct rb_node *rb, 118 + struct rb_node *p, int color) 119 + { 120 + rb->__rb_parent_color = (unsigned long)p | color; 121 + } 122 + 123 + static inline void 124 + __rb_change_child(struct rb_node *old, struct rb_node *new, 125 + struct rb_node *parent, struct rb_root *root) 126 + { 127 + if (parent) { 128 + if (parent->rb_left == old) 129 + parent->rb_left = new; 130 + else 131 + parent->rb_right = new; 132 + } else 133 + root->rb_node = new; 134 + } 135 + 136 + extern void __rb_erase_color(struct rb_node *parent, struct rb_root *root, 137 + void (*augment_rotate)(struct rb_node *old, struct rb_node *new)); 138 + 139 + static __always_inline struct rb_node * 140 + __rb_erase_augmented(struct rb_node *node, struct rb_root *root, 141 + const struct rb_augment_callbacks *augment) 142 + { 143 + struct rb_node *child = node->rb_right, *tmp = node->rb_left; 144 + struct rb_node *parent, *rebalance; 145 + unsigned long pc; 146 + 147 + if (!tmp) { 148 + /* 149 + * Case 1: node to erase has no more than 1 child (easy!) 150 + * 151 + * Note that if there is one child it must be red due to 5) 152 + * and node must be black due to 4). We adjust colors locally 153 + * so as to bypass __rb_erase_color() later on. 154 + */ 155 + pc = node->__rb_parent_color; 156 + parent = __rb_parent(pc); 157 + __rb_change_child(node, child, parent, root); 158 + if (child) { 159 + child->__rb_parent_color = pc; 160 + rebalance = NULL; 161 + } else 162 + rebalance = __rb_is_black(pc) ? parent : NULL; 163 + tmp = parent; 164 + } else if (!child) { 165 + /* Still case 1, but this time the child is node->rb_left */ 166 + tmp->__rb_parent_color = pc = node->__rb_parent_color; 167 + parent = __rb_parent(pc); 168 + __rb_change_child(node, tmp, parent, root); 169 + rebalance = NULL; 170 + tmp = parent; 171 + } else { 172 + struct rb_node *successor = child, *child2; 173 + tmp = child->rb_left; 174 + if (!tmp) { 175 + /* 176 + * Case 2: node's successor is its right child 177 + * 178 + * (n) (s) 179 + * / \ / \ 180 + * (x) (s) -> (x) (c) 181 + * \ 182 + * (c) 183 + */ 184 + parent = successor; 185 + child2 = successor->rb_right; 186 + augment->copy(node, successor); 187 + } else { 188 + /* 189 + * Case 3: node's successor is leftmost under 190 + * node's right child subtree 191 + * 192 + * (n) (s) 193 + * / \ / \ 194 + * (x) (y) -> (x) (y) 195 + * / / 196 + * (p) (p) 197 + * / / 198 + * (s) (c) 199 + * \ 200 + * (c) 201 + */ 202 + do { 203 + parent = successor; 204 + successor = tmp; 205 + tmp = tmp->rb_left; 206 + } while (tmp); 207 + parent->rb_left = child2 = successor->rb_right; 208 + successor->rb_right = child; 209 + rb_set_parent(child, successor); 210 + augment->copy(node, successor); 211 + augment->propagate(parent, successor); 212 + } 213 + 214 + successor->rb_left = tmp = node->rb_left; 215 + rb_set_parent(tmp, successor); 216 + 217 + pc = node->__rb_parent_color; 218 + tmp = __rb_parent(pc); 219 + __rb_change_child(node, successor, tmp, root); 220 + if (child2) { 221 + successor->__rb_parent_color = pc; 222 + rb_set_parent_color(child2, parent, RB_BLACK); 223 + rebalance = NULL; 224 + } else { 225 + unsigned long pc2 = successor->__rb_parent_color; 226 + successor->__rb_parent_color = pc; 227 + rebalance = __rb_is_black(pc2) ? parent : NULL; 228 + } 229 + tmp = successor; 230 + } 231 + 232 + augment->propagate(tmp, NULL); 233 + return rebalance; 234 + } 235 + 236 + static __always_inline void 237 + rb_erase_augmented(struct rb_node *node, struct rb_root *root, 238 + const struct rb_augment_callbacks *augment) 239 + { 240 + struct rb_node *rebalance = __rb_erase_augmented(node, root, augment); 241 + if (rebalance) 242 + __rb_erase_color(rebalance, root, augment->rotate); 243 + } 244 + 245 + #endif /* _TOOLS_LINUX_RBTREE_AUGMENTED_H */
+1 -1
tools/perf/MANIFEST
··· 46 46 tools/include/linux/log2.h 47 47 tools/include/linux/poison.h 48 48 tools/include/linux/rbtree.h 49 + tools/include/linux/rbtree_augmented.h 49 50 tools/include/linux/types.h 50 51 include/asm-generic/bitops/arch_hweight.h 51 52 include/asm-generic/bitops/const_hweight.h ··· 66 65 arch/*/lib/memset*.S 67 66 include/linux/poison.h 68 67 include/linux/hw_breakpoint.h 69 - include/linux/rbtree_augmented.h 70 68 include/uapi/linux/perf_event.h 71 69 include/uapi/linux/const.h 72 70 include/uapi/linux/swab.h
-2
tools/perf/util/include/linux/rbtree_augmented.h
··· 1 - #include <stdbool.h> 2 - #include "../../../../include/linux/rbtree_augmented.h"