summaryrefslogtreecommitdiff
path: root/debian/patches/0008-update-radix-tree-code.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/0008-update-radix-tree-code.patch')
-rw-r--r--debian/patches/0008-update-radix-tree-code.patch379
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
+