diff options
Diffstat (limited to 'debian/patches/0008-update-radix-tree-code.patch')
-rw-r--r-- | debian/patches/0008-update-radix-tree-code.patch | 379 |
1 files changed, 379 insertions, 0 deletions
diff --git a/debian/patches/0008-update-radix-tree-code.patch b/debian/patches/0008-update-radix-tree-code.patch new file mode 100644 index 0000000..678fc3b --- /dev/null +++ b/debian/patches/0008-update-radix-tree-code.patch @@ -0,0 +1,379 @@ +From a8584bd986fc87c2641a36b5ee93fc55fb753b28 Mon Sep 17 00:00:00 2001 +From: Justus Winter <4winter@informatik.uni-hamburg.de> +Date: Thu, 14 May 2015 11:21:44 +0200 +Subject: [PATCH gnumach 8/8] update radix tree code + +--- + kern/rdxtree.c | 163 +++++++++++++++++++++++++++++++------------------------ + kern/rdxtree.h | 26 +++++---- + kern/rdxtree_i.h | 21 +++---- + 3 files changed, 119 insertions(+), 91 deletions(-) + +diff --git a/kern/rdxtree.c b/kern/rdxtree.c +index 44784f3..78868b1 100644 +--- a/kern/rdxtree.c ++++ b/kern/rdxtree.c +@@ -21,12 +21,15 @@ + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * ++ * Upstream site with license notes : ++ * http://git.sceen.net/rbraun/librbraun.git/ + */ + + #include <kern/assert.h> + #include <kern/slab.h> + #include <mach/kern_return.h> +-#include <sys/types.h> + #include <stddef.h> + #include <string.h> + +@@ -34,9 +37,9 @@ + #include "rdxtree.h" + #include "rdxtree_i.h" + ++/* XXX */ + #define CHAR_BIT 8U + #define ERR_SUCCESS KERN_SUCCESS +-//XXX + #define ERR_BUSY KERN_INVALID_ARGUMENT + #define ERR_NOMEM KERN_RESOURCE_SHORTAGE + +@@ -121,7 +124,7 @@ void + rdxtree_cache_init(void) + { + kmem_cache_init(&rdxtree_node_cache, "rdxtree_node", +- sizeof(struct rdxtree_node), 0, NULL, NULL, NULL, 0); ++ sizeof(struct rdxtree_node), 0, NULL, NULL, NULL, 0); + } + + #ifdef RDXTREE_ENABLE_NODE_CREATION_FAILURES +@@ -251,15 +254,20 @@ rdxtree_node_remove(struct rdxtree_node *node, unsigned int index) + } + + static inline void * +-rdxtree_node_find(struct rdxtree_node *node, unsigned int index, int get_slot) ++rdxtree_node_find(struct rdxtree_node *node, unsigned int *indexp) + { ++ unsigned int index; + void *ptr; + ++ index = *indexp; ++ + while (index < ARRAY_SIZE(node->entries)) { +- ptr = rdxtree_entry_addr(node->entries[index]); ++ ptr = rdxtree_entry_addr(llsync_read_ptr(node->entries[index])); + +- if (ptr != NULL) +- return get_slot ? (void *)&node->entries[index] : ptr; ++ if (ptr != NULL) { ++ *indexp = index; ++ return ptr; ++ } + + index++; + } +@@ -695,115 +703,128 @@ rdxtree_replace_slot(void **slot, void *ptr) + return old; + } + +-static struct rdxtree_node * +-rdxtree_walk(struct rdxtree *tree, struct rdxtree_node *node) ++static void * ++rdxtree_walk_next(struct rdxtree *tree, struct rdxtree_iter *iter) + { +- struct rdxtree_node *prev, *child; +- unsigned int height, index; ++ struct rdxtree_node *root, *node, *prev; ++ unsigned int height, shift, index, orig_index; ++ rdxtree_key_t key; ++ void *entry; + +- if (node == NULL) { +- height = tree->height; +- node = rdxtree_entry_addr(tree->root); ++ entry = llsync_read_ptr(tree->root); + +- while (height > 1) { +- node = rdxtree_node_find(node, 0, 0); +- height--; +- } ++ if (entry == NULL) ++ return NULL; + +- return node; ++ if (!rdxtree_entry_is_node(entry)) { ++ if (iter->key != (rdxtree_key_t)-1) ++ return NULL; ++ else { ++ iter->key = 0; ++ return rdxtree_entry_addr(entry); ++ } + } + +- height = 0; ++ key = iter->key + 1; + +- for (;;) { +- prev = node->parent; ++ if ((key == 0) && (iter->node != NULL)) ++ return NULL; + +- if (prev == NULL) +- return NULL; ++ root = rdxtree_entry_addr(entry); + +- index = node->index; +- child = rdxtree_node_find(prev, index + 1, 0); ++restart: ++ node = root; ++ height = root->height + 1; + +- if (child != NULL) +- break; ++ if (key > rdxtree_max_key(height)) ++ return NULL; + +- height++; +- node = prev; +- } ++ shift = (height - 1) * RDXTREE_RADIX; + +- node = child; ++ do { ++ prev = node; ++ index = (key >> shift) & RDXTREE_RADIX_MASK; ++ orig_index = index; ++ node = rdxtree_node_find(node, &index); ++ ++ if (node == NULL) { ++ shift += RDXTREE_RADIX; ++ key = ((key >> shift) + 1) << shift; + +- while (height > 0) { +- node = rdxtree_node_find(node, 0, 0); ++ if (key == 0) ++ return NULL; ++ ++ goto restart; ++ } ++ ++ if (orig_index != index) ++ key = ((key >> shift) + (index - orig_index)) << shift; ++ ++ shift -= RDXTREE_RADIX; + height--; +- } ++ } while (height > 0); + ++ iter->node = prev; ++ iter->key = key; + return node; + } + + void * +-rdxtree_iter_next(struct rdxtree *tree, struct rdxtree_iter *iter) ++rdxtree_walk(struct rdxtree *tree, struct rdxtree_iter *iter) + { +- unsigned int index; +- +- if (tree->height == 0) { +- if (iter->slot != NULL) +- return NULL; ++ unsigned int index, orig_index; ++ void *ptr; + +- iter->slot = &tree->root; +- return *iter->slot; +- } ++ if (iter->node == NULL) ++ return rdxtree_walk_next(tree, iter); + +- if (iter->node != NULL) { +- index = iter->slot - ((struct rdxtree_node *)iter->node)->entries; +- iter->slot = rdxtree_node_find(iter->node, index + 1, 1); +- } ++ index = (iter->key + 1) & RDXTREE_RADIX_MASK; + +- if (iter->slot == NULL) { +- iter->node = rdxtree_walk(tree, iter->node); ++ if (index != 0) { ++ orig_index = index; ++ ptr = rdxtree_node_find(iter->node, &index); + +- if (iter->node != NULL) +- iter->slot = rdxtree_node_find(iter->node, 0, 1); ++ if (ptr != NULL) { ++ iter->key += (index - orig_index) + 1; ++ return ptr; ++ } + } + +- if (iter->slot == NULL) +- return NULL; +- +- return *iter->slot; ++ return rdxtree_walk_next(tree, iter); + } + + void + rdxtree_remove_all(struct rdxtree *tree) + { +- struct rdxtree_node *node, *parent, *next; +- unsigned int height, index; ++ struct rdxtree_node *node, *parent; ++ struct rdxtree_iter iter; + +- height = tree->height; +- +- if (height == 0) { ++ if (tree->height == 0) { + if (tree->root != NULL) + llsync_assign_ptr(tree->root, NULL); + + return; + } + +- node = rdxtree_walk(tree, NULL); ++ for (;;) { ++ rdxtree_iter_init(&iter); ++ rdxtree_walk_next(tree, &iter); + +- do { +- next = rdxtree_walk(tree, node); ++ if (iter.node == NULL) ++ break; + ++ node = iter.node; + parent = node->parent; + +- if (parent != NULL) { +- index = node->index; +- rdxtree_node_remove(parent, index); +- rdxtree_remove_bm_set(parent, index); ++ if (parent == NULL) ++ rdxtree_init(tree); ++ else { ++ rdxtree_node_remove(parent, node->index); ++ rdxtree_remove_bm_set(parent, node->index); + rdxtree_cleanup(tree, parent); + node->parent = NULL; + } + + rdxtree_node_schedule_destruction(node); +- +- node = next; +- } while (node != NULL); ++ } + } +diff --git a/kern/rdxtree.h b/kern/rdxtree.h +index f2f38a0..b272f8a 100644 +--- a/kern/rdxtree.h ++++ b/kern/rdxtree.h +@@ -27,6 +27,9 @@ + * + * In addition to the standard insertion operation, this implementation + * can allocate keys for the caller at insertion time. ++ * ++ * Upstream site with license notes : ++ * http://git.sceen.net/rbraun/librbraun.git/ + */ + + #ifndef _RDXTREE_H +@@ -49,12 +52,6 @@ typedef uint64_t rdxtree_key_t; + #endif /* RDXTREE_KEY_32 */ + + /* +- * Initialize the node cache. +- */ +-void +-rdxtree_cache_init(void); +- +-/* + * Radix tree. + */ + struct rdxtree; +@@ -181,10 +178,19 @@ void * rdxtree_replace_slot(void **slot, void *ptr); + /* + * Forge a loop to process all pointers of a tree. + */ +-#define rdxtree_for_each(tree, iter, ptr) \ +-for (rdxtree_iter_init(iter), ptr = rdxtree_iter_next(tree, iter); \ +- ptr != NULL; \ +- ptr = rdxtree_iter_next(tree, iter)) ++#define rdxtree_for_each(tree, iter, ptr) \ ++for (rdxtree_iter_init(iter), ptr = rdxtree_walk(tree, iter); \ ++ ptr != NULL; \ ++ ptr = rdxtree_walk(tree, iter)) ++ ++/* ++ * Return the key of the current pointer from an iterator. ++ */ ++static inline rdxtree_key_t ++rdxtree_iter_key(const struct rdxtree_iter *iter) ++{ ++ return iter->key; ++} + + /* + * Remove all pointers from a tree. +diff --git a/kern/rdxtree_i.h b/kern/rdxtree_i.h +index 9c9f962..1bd1f64 100644 +--- a/kern/rdxtree_i.h ++++ b/kern/rdxtree_i.h +@@ -13,6 +13,10 @@ + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. ++ * ++ * ++ * Upstream site with license notes : ++ * http://git.sceen.net/rbraun/librbraun.git/ + */ + + #ifndef _RDXTREE_I_H +@@ -28,10 +32,14 @@ struct rdxtree { + + /* + * Radix tree iterator. ++ * ++ * The node member refers to the node containing the current pointer, if any. ++ * The key member refers to the current pointer, and is valid if and only if ++ * rdxtree_walk() has been called at least once on the iterator. + */ + struct rdxtree_iter { + void *node; +- void **slot; ++ rdxtree_key_t key; + }; + + /* +@@ -41,7 +49,7 @@ static inline void + rdxtree_iter_init(struct rdxtree_iter *iter) + { + iter->node = NULL; +- iter->slot = NULL; ++ iter->key = (rdxtree_key_t)-1; + } + + int rdxtree_insert_common(struct rdxtree *tree, rdxtree_key_t key, +@@ -53,13 +61,6 @@ int rdxtree_insert_alloc_common(struct rdxtree *tree, void *ptr, + void * rdxtree_lookup_common(const struct rdxtree *tree, rdxtree_key_t key, + int get_slot); + +-/* +- * Walk over pointers in a tree. +- * +- * Move the iterator to the next pointer in the given tree. +- * +- * The next pointer is returned if there is one, NULL otherwise. +- */ +-void * rdxtree_iter_next(struct rdxtree *tree, struct rdxtree_iter *iter); ++void * rdxtree_walk(struct rdxtree *tree, struct rdxtree_iter *iter); + + #endif /* _RDXTREE_I_H */ +-- +2.1.4 + |