summaryrefslogtreecommitdiff
path: root/debian/patches/0008-xxx-use-a-rbtree-for-reverse-lookups.patch
blob: 13ed0436f5c38ca61a40dae60d4cde42c00466ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
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 <mach/mach_types.h>
 #include <mach/port.h>
 #include <mach/kern_return.h>
+#include <kern/rbtree.h>
 #include <kern/slab.h>
 #include <ipc/port.h>
 #include <ipc/ipc_table.h>
@@ -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 <machine/vm_param.h>
 #include <kern/macro_help.h>
 #include <kern/lock.h>
+#include <kern/rbtree.h>
 #include <kern/rdxtree.h>
 #include <kern/slab.h>
 #include <ipc/ipc_entry.h>
@@ -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