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.


06ee0c4cb1c2699b3770f9342431e29cb4524d66
[palacios.git] / palacios / src / palacios / vmm_multitree.c
1 /* 
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
11  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Jack Lange <jarusl@cs.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20
21 #include <palacios/vmm_multitree.h>
22 #include <palacios/vmm_string.h>
23
24 #include <palacios/vmm_rbtree.h>
25
26 static inline 
27 struct v3_mtree * __insert_mtree_node(struct v3_mtree * root, struct v3_mtree * node) {
28     struct rb_node ** p = &(root->child.rb_node);
29     struct rb_node * parent = NULL;
30     struct v3_mtree * tmp_node;
31
32     while (*p) {
33         int ret = 0;
34         parent = *p;
35         tmp_node = rb_entry(parent, struct v3_mtree, tree_node);
36
37         ret = strcmp(node->name, tmp_node->name);
38
39         if (ret < 0) {
40             p = &(*p)->rb_left;
41         } else if (ret > 0) {
42             p = &(*p)->rb_right;
43         } else {
44             return tmp_node;
45         }
46     }
47
48     rb_link_node(&(node->tree_node), parent, p);
49   
50     return NULL;
51 }
52
53
54
55 struct v3_mtree * v3_mtree_create_node(struct v3_mtree * root, char * name) {
56     struct v3_mtree * node = (struct v3_mtree *)V3_Malloc(sizeof(struct v3_mtree));
57     struct v3_mtree * ret = NULL;
58
59
60     PrintDebug(VM_NONE, VCORE_NONE, "Creating Node %s\n", name);
61
62
63     if (!node) {
64         PrintError(VM_NONE, VCORE_NONE, "Cannot allocate multitree node\n");
65         return NULL;
66     }
67
68     memset(node, 0, sizeof(struct v3_mtree));
69     strncpy(node->name, name, V3_MTREE_NAME_LEN);
70
71     if ((ret = __insert_mtree_node(root, node))) {
72         PrintError(VM_NONE, VCORE_NONE, "Insertion failure\n");
73         V3_Free(node);
74         return NULL;
75     }
76
77     PrintDebug(VM_NONE, VCORE_NONE, "Node (%s)=%p, root=%p, root->child=%p\n", node->name, node, root, root->child.rb_node);
78
79     v3_rb_insert_color(&(node->tree_node), &(root->child));
80
81     PrintDebug(VM_NONE, VCORE_NONE, "balanced\n");
82
83     return node;
84 }
85
86
87 struct v3_mtree * v3_mtree_create_subtree(struct v3_mtree * root, char * name) {
88     struct v3_mtree * node = NULL;
89
90     PrintDebug(VM_NONE, VCORE_NONE, "Creating Subtree %s\n", name);
91     node = v3_mtree_create_node(root, name);
92
93     if (node == NULL) {
94         return NULL;
95     }
96
97     node->subtree = 1;
98
99     return node;
100 }
101
102
103 struct v3_mtree * v3_mtree_create_value(struct v3_mtree * root, char * name, 
104                                         uint64_t size, void * value) {
105     struct v3_mtree * node  = NULL;
106
107     PrintDebug(VM_NONE, VCORE_NONE, "Creating value %s\n", name);    
108     node = v3_mtree_create_node(root, name);
109
110     if (node == NULL) {
111         return NULL;
112     }
113
114     node->size = size;
115     node->value = value;
116
117     return node;
118 }
119
120
121
122 struct v3_mtree * v3_mtree_find_node(struct v3_mtree * root, char * name) {
123     struct rb_node * n = root->child.rb_node;
124     struct v3_mtree * tmp_node = NULL;
125
126     if (root->subtree == 0) {
127         PrintError(VM_NONE, VCORE_NONE, "Searching for node on a non-root mtree (search=%s), root=%s\n", name, root->name);
128         return NULL;
129     }
130    
131     while (n) {
132         int ret = 0;
133         tmp_node = rb_entry(n, struct v3_mtree, tree_node);
134         ret = strcmp(tmp_node->name, name);
135
136         if (ret < 0) {
137             n = n->rb_left;
138         } else if (ret > 0) {
139             n = n->rb_right;
140         } else {
141             return tmp_node;
142         }       
143     }
144
145     return NULL;
146 }
147
148
149 struct v3_mtree * v3_mtree_find_subtree(struct v3_mtree * root, char * name) {
150     struct v3_mtree * node = v3_mtree_find_node(root, name);
151     
152     if (node->subtree == 0) {
153         return NULL;
154     }
155
156     return node;
157 }
158
159
160 struct v3_mtree * v3_mtree_find_value(struct v3_mtree * root, char * name) {
161     struct v3_mtree * node= v3_mtree_find_node(root, name);
162     
163     if (node->subtree == 1) {
164         return NULL;
165     }
166
167     return node;
168 }
169
170
171 struct v3_mtree * v3_mtree_first_child(struct v3_mtree * root) {
172     struct rb_node * node = v3_rb_first(&(root->child));
173
174     if (node == NULL) {
175         return NULL;
176     }
177
178     return rb_entry(node, struct v3_mtree, tree_node);
179 }
180
181
182 struct v3_mtree * v3_mtree_next_node(struct v3_mtree * node) {
183     struct rb_node * next_node = v3_rb_next(&(node->tree_node));
184
185     if (next_node == NULL) {
186         return NULL;
187     }
188     return rb_entry(next_node, struct v3_mtree, tree_node);
189 }