From 3c232d3456bca5d7ac9b67a0e77806e1e2aad4ad Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Sat, 11 Apr 2015 03:11:33 +0200 Subject: [PATCH gnumach 8/9] xxx use a rbtree for reverse lookups --- ipc/ipc_entry.h | 3 +++ ipc/ipc_space.c | 3 +-- ipc/ipc_space.h | 66 ++++++++++++++++++++++++++++++++++++--------------------- 3 files changed, 46 insertions(+), 26 deletions(-) diff --git a/ipc/ipc_entry.h b/ipc/ipc_entry.h index ee3c2d4..a292638 100644 --- a/ipc/ipc_entry.h +++ b/ipc/ipc_entry.h @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -71,6 +72,8 @@ typedef struct ipc_entry { /*XXX ipc_port_request_index_t request;*/ unsigned int request; } index; + struct rbtree_node tree_node; /* entries in the reverse_map + tree (send rights only) */ } *ipc_entry_t; #define IE_NULL ((ipc_entry_t) 0) diff --git a/ipc/ipc_space.c b/ipc/ipc_space.c index ea3cb3b..7d3f6cb 100644 --- a/ipc/ipc_space.c +++ b/ipc/ipc_space.c @@ -115,7 +115,7 @@ ipc_space_create( space->is_active = TRUE; rdxtree_init(&space->is_map); - rdxtree_init(&space->is_reverse_map); + rbtree_init(&space->is_reverse_map); /* The zeroth entry is reserved. */ rdxtree_insert(&space->is_map, 0, &zero_entry); space->is_size = 1; @@ -204,7 +204,6 @@ ipc_space_destroy( ie_free(entry); } rdxtree_remove_all(&space->is_map); - rdxtree_remove_all(&space->is_reverse_map); /* * Because the space is now dead, diff --git a/ipc/ipc_space.h b/ipc/ipc_space.h index 404f708..1ed3afd 100644 --- a/ipc/ipc_space.h +++ b/ipc/ipc_space.h @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -75,7 +76,7 @@ struct ipc_space { boolean_t is_active; /* is the space alive? */ struct rdxtree is_map; /* a map of entries */ size_t is_size; /* number of entries */ - struct rdxtree is_reverse_map; /* maps objects to entries */ + struct rbtree is_reverse_map; /* maps objects to entries */ ipc_entry_t is_free_list; /* a linked list of free entries */ size_t is_free_list_size; /* number of free entries */ #define IS_FREE_LIST_SIZE_LIMIT 64 /* maximum number of entries @@ -259,13 +260,26 @@ ipc_entry_dealloc( /* Reverse lookups. */ -/* Cast a pointer to a suitable key. */ -#define KEY(X) \ - ({ \ - assert((((unsigned long) (X)) & 0x07) == 0); \ - ((unsigned long long) \ - (((unsigned long) (X) - VM_MIN_KERNEL_ADDRESS) >> 3)); \ - }) +/* Red-black tree lookup/insert comparison functions. */ +static inline int +ipc_reverse_cmp_lookup(ipc_object_t obj, struct rbtree_node *node) +{ + struct ipc_entry *n = + structof(node, struct ipc_entry, tree_node); + if ((vm_offset_t) obj < (vm_offset_t) n->ie_object) + return -1; + if ((vm_offset_t) obj > (vm_offset_t) n->ie_object) + return 1; + return 0; +} + +static inline int +ipc_reverse_cmp_insert(struct rbtree_node *node_n, struct rbtree_node *node_m) +{ + struct ipc_entry *n = + structof(node_n, struct ipc_entry, tree_node); + return ipc_reverse_cmp_lookup(n->ie_object, node_m); +} /* Insert (OBJ, ENTRY) pair into the reverse mapping. SPACE must be write-locked. */ @@ -276,8 +290,9 @@ ipc_reverse_insert(ipc_space_t space, { assert(space != IS_NULL); assert(obj != IO_NULL); - return (kern_return_t) rdxtree_insert(&space->is_reverse_map, - KEY(obj), entry); + rbtree_insert(&space->is_reverse_map, &entry->tree_node, + ipc_reverse_cmp_insert); + return KERN_SUCCESS; } /* Remove OBJ from the reverse mapping. SPACE must be @@ -288,18 +303,16 @@ ipc_reverse_remove(ipc_space_t space, { assert(space != IS_NULL); assert(obj != IO_NULL); - return rdxtree_remove(&space->is_reverse_map, KEY(obj)); -} + struct rbtree_node *tree_node; -/* Remove all entries from the reverse mapping. SPACE must be - write-locked. */ -static inline void -ipc_reverse_remove_all(ipc_space_t space) -{ - assert(space != IS_NULL); - rdxtree_remove_all(&space->is_reverse_map); - assert(space->is_reverse_map.height == 0); - assert(space->is_reverse_map.root == NULL); + tree_node = rbtree_lookup(&space->is_reverse_map, obj, + ipc_reverse_cmp_lookup); + if (tree_node == NULL) + return NULL; + + rbtree_remove(&space->is_reverse_map, tree_node); + + return structof(tree_node, struct ipc_entry, tree_node); } /* Return ENTRY related to OBJ, or NULL if no such entry is found in @@ -311,9 +324,14 @@ ipc_reverse_lookup(ipc_space_t space, { assert(space != IS_NULL); assert(obj != IO_NULL); - return rdxtree_lookup(&space->is_reverse_map, KEY(obj)); -} + struct rbtree_node *tree_node; -#undef KEY + tree_node = rbtree_lookup(&space->is_reverse_map, obj, + ipc_reverse_cmp_lookup); + if (tree_node == NULL) + return NULL; + + return structof(tree_node, struct ipc_entry, tree_node); +} #endif /* _IPC_IPC_SPACE_H_ */ -- 2.1.4