Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


working instruction emulation
[palacios.git] / palacios / include / palacios / vmm_rbtree.h
1 /*
2   Red Black Trees
3   (C) 1999  Andrea Arcangeli <andrea@suse.de>
4   
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
18
19   linux/include/linux/rbtree.h
20
21   To use rbtrees you'll have to implement your own insert and search cores.
22   This will avoid us to use callbacks and to drop drammatically performances.
23   I know it's not the cleaner way,  but in C (not in C++) to get
24   performances and genericity...
25
26   Some example of insert and search follows here. The search is a plain
27   normal search over an ordered tree. The insert instead must be implemented
28   int two steps: as first thing the code must insert the element in
29   order as a red leaf in the tree, then the support library function
30   rb_insert_color() must be called. Such function will do the
31   not trivial work to rebalance the rbtree if necessary.
32
33 -----------------------------------------------------------------------
34 static inline struct page * rb_search_page_cache(struct inode * inode,
35                                                  unsigned long offset)
36 {
37         struct rb_node * n = inode->i_rb_page_cache.rb_node;
38         struct page * page;
39
40         while (n)
41         {
42                 page = rb_entry(n, struct page, rb_page_cache);
43
44                 if (offset < page->offset)
45                         n = n->rb_left;
46                 else if (offset > page->offset)
47                         n = n->rb_right;
48                 else
49                         return page;
50         }
51         return NULL;
52 }
53
54 static inline struct page * __rb_insert_page_cache(struct inode * inode,
55                                                    unsigned long offset,
56                                                    struct rb_node * node)
57 {
58         struct rb_node ** p = &inode->i_rb_page_cache.rb_node;
59         struct rb_node * parent = NULL;
60         struct page * page;
61
62         while (*p)
63         {
64                 parent = *p;
65                 page = rb_entry(parent, struct page, rb_page_cache);
66
67                 if (offset < page->offset)
68                         p = &(*p)->rb_left;
69                 else if (offset > page->offset)
70                         p = &(*p)->rb_right;
71                 else
72                         return page;
73         }
74
75         rb_link_node(node, parent, p);
76
77         return NULL;
78 }
79
80 static inline struct page * rb_insert_page_cache(struct inode * inode,
81                                                  unsigned long offset,
82                                                  struct rb_node * node)
83 {
84         struct page * ret;
85         if ((ret = __rb_insert_page_cache(inode, offset, node)))
86                 goto out;
87         rb_insert_color(node, &inode->i_rb_page_cache);
88  out:
89         return ret;
90 }
91 -----------------------------------------------------------------------
92 */
93
94 #ifndef _VMM_RBTREE_H
95 #define _VMM_RBTREE_H
96
97 #ifdef __V3VEE__
98
99
100 #define container_of(ptr, type, member) ({                      \
101         const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
102         (type *)( (char *)__mptr - offsetof(type,member) );})
103
104
105
106 struct rb_node
107 {
108         unsigned long  rb_parent_color;
109 #define RB_RED          0
110 #define RB_BLACK        1
111         struct rb_node *rb_right;
112         struct rb_node *rb_left;
113 } __attribute__((aligned(sizeof(long))));
114     /* The alignment might seem pointless, but allegedly CRIS needs it */
115
116 struct rb_root
117 {
118         struct rb_node *rb_node;
119 };
120
121
122 #define rb_parent(r)   ((struct rb_node *)((r)->rb_parent_color & ~3))
123 #define rb_color(r)   ((r)->rb_parent_color & 1)
124 #define rb_is_red(r)   (!rb_color(r))
125 #define rb_is_black(r) rb_color(r)
126 #define rb_set_red(r)  do { (r)->rb_parent_color &= ~1; } while (0)
127 #define rb_set_black(r)  do { (r)->rb_parent_color |= 1; } while (0)
128
129 static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
130 {
131         rb->rb_parent_color = (rb->rb_parent_color & 3) | (unsigned long)p;
132 }
133 static inline void rb_set_color(struct rb_node *rb, int color)
134 {
135         rb->rb_parent_color = (rb->rb_parent_color & ~1) | color;
136 }
137
138 #define RB_ROOT (struct rb_root) { NULL, }
139 #define rb_entry(ptr, type, member) container_of(ptr, type, member)
140
141 #define RB_EMPTY_ROOT(root)     ((root)->rb_node == NULL)
142 #define RB_EMPTY_NODE(node)     (rb_parent(node) != node)
143 #define RB_CLEAR_NODE(node)     (rb_set_parent(node, node))
144
145 extern void v3_rb_insert_color(struct rb_node *, struct rb_root *);
146 extern void v3_rb_erase(struct rb_node *, struct rb_root *);
147
148 /* Find logical next and previous nodes in a tree */
149 extern struct rb_node *v3_rb_next(struct rb_node *);
150 extern struct rb_node *v3_rb_prev(struct rb_node *);
151 extern struct rb_node *v3_rb_first(struct rb_root *);
152 extern struct rb_node *v3_rb_last(struct rb_root *);
153
154 /* Fast replacement of a single node without remove/rebalance/add/rebalance */
155 extern void v3_rb_replace_node(struct rb_node *victim, struct rb_node *new, 
156                             struct rb_root *root);
157
158 static inline void rb_link_node(struct rb_node * node, struct rb_node * parent,
159                                 struct rb_node ** rb_link)
160 {
161         node->rb_parent_color = (unsigned long )parent;
162         node->rb_left = node->rb_right = NULL;
163
164         *rb_link = node;
165 }
166
167
168 #endif
169
170 #endif  /* _LINUX_RBTREE_H */