summaryrefslogtreecommitdiff
path: root/debian/patches/0008-xxx-drop-code.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/0008-xxx-drop-code.patch')
-rw-r--r--debian/patches/0008-xxx-drop-code.patch2322
1 files changed, 2322 insertions, 0 deletions
diff --git a/debian/patches/0008-xxx-drop-code.patch b/debian/patches/0008-xxx-drop-code.patch
new file mode 100644
index 0000000..93a6a31
--- /dev/null
+++ b/debian/patches/0008-xxx-drop-code.patch
@@ -0,0 +1,2322 @@
+From 79ee408f351cf4fce4334876ba4b53fcb21a1671 Mon Sep 17 00:00:00 2001
+From: Justus Winter <4winter@informatik.uni-hamburg.de>
+Date: Sat, 16 May 2015 14:22:52 +0200
+Subject: [PATCH gnumach 08/10] xxx drop code
+
+---
+ Makefrag.am | 4 -
+ ipc/ipc_entry.c | 349 +--------------------
+ ipc/ipc_entry.h | 38 +--
+ ipc/ipc_hash.c | 475 ----------------------------
+ ipc/ipc_hash.h | 96 ------
+ ipc/ipc_init.c | 5 -
+ ipc/ipc_object.c | 1 -
+ ipc/ipc_right.c | 39 +--
+ ipc/ipc_splay.c | 920 -------------------------------------------------------
+ ipc/ipc_splay.h | 114 -------
+ 10 files changed, 21 insertions(+), 2020 deletions(-)
+ delete mode 100644 ipc/ipc_hash.c
+ delete mode 100644 ipc/ipc_hash.h
+ delete mode 100644 ipc/ipc_splay.c
+ delete mode 100644 ipc/ipc_splay.h
+
+diff --git a/Makefrag.am b/Makefrag.am
+index 2eb835e..023a4d1 100644
+--- a/Makefrag.am
++++ b/Makefrag.am
+@@ -80,8 +80,6 @@ endif
+ libkernel_a_SOURCES += \
+ ipc/ipc_entry.c \
+ ipc/ipc_entry.h \
+- ipc/ipc_hash.c \
+- ipc/ipc_hash.h \
+ ipc/ipc_init.c \
+ ipc/ipc_init.h \
+ ipc/ipc_kmsg.c \
+@@ -105,8 +103,6 @@ libkernel_a_SOURCES += \
+ ipc/ipc_right.h \
+ ipc/ipc_space.c \
+ ipc/ipc_space.h \
+- ipc/ipc_splay.c \
+- ipc/ipc_splay.h \
+ ipc/ipc_table.c \
+ ipc/ipc_table.h \
+ ipc/ipc_target.c \
+diff --git a/ipc/ipc_entry.c b/ipc/ipc_entry.c
+index dfef3cf..2d6e665 100644
+--- a/ipc/ipc_entry.c
++++ b/ipc/ipc_entry.c
+@@ -46,49 +46,11 @@
+ #include <ipc/ipc_types.h>
+ #include <ipc/ipc_entry.h>
+ #include <ipc/ipc_space.h>
+-#include <ipc/ipc_splay.h>
+-#include <ipc/ipc_hash.h>
+ #include <ipc/ipc_table.h>
+ #include <ipc/ipc_object.h>
+
+ struct kmem_cache ipc_entry_cache;
+
+-struct kmem_cache ipc_tree_entry_cache;
+-
+-/*
+- * Routine: ipc_entry_tree_collision
+- * Purpose:
+- * Checks if "name" collides with an allocated name
+- * in the space's tree. That is, returns TRUE
+- * if the splay tree contains a name with the same
+- * index as "name".
+- * Conditions:
+- * The space is locked (read or write) and active.
+- */
+-
+-boolean_t
+-ipc_entry_tree_collision(
+- ipc_space_t space,
+- mach_port_t name)
+-{
+- assert(!"reached");
+- mach_port_index_t index;
+- mach_port_t lower, upper;
+-
+- assert(space->is_active);
+-
+- /*
+- * Check if we collide with the next smaller name
+- * or the next larger name.
+- */
+-
+- ipc_splay_tree_bounds(&space->is_tree, name, &lower, &upper);
+-
+- index = MACH_PORT_INDEX(name);
+- return (((lower != ~0) && (MACH_PORT_INDEX(lower) == index)) ||
+- ((upper != 0) && (MACH_PORT_INDEX(upper) == index)));
+-}
+-
+ /*
+ * Routine: ipc_entry_lookup
+ * Purpose:
+@@ -259,9 +221,6 @@ ipc_entry_alloc_name(
+ ipc_entry_t *entryp)
+ {
+ kern_return_t kr;
+- mach_port_index_t index = MACH_PORT_INDEX(name);
+- mach_port_gen_t gen = MACH_PORT_GEN(name);
+-
+ ipc_entry_t entry, e, *prevp;
+ void **slot;
+ assert(MACH_PORT_VALID(name));
+@@ -323,7 +282,7 @@ ipc_entry_alloc_name(
+ *prevp = entry->ie_next_free;
+ space->is_free_list_size -= 1;
+
+- entry->ie_bits = gen;
++ entry->ie_bits = 0;
+ assert(entry->ie_object == IO_NULL);
+ assert(entry->ie_name == name);
+ entry->ie_request = 0;
+@@ -365,312 +324,6 @@ ipc_entry_dealloc(
+ space->is_size -= 1;
+ }
+
+-/*
+- * Routine: ipc_entry_grow_table
+- * Purpose:
+- * Grows the table in a space.
+- * Conditions:
+- * The space must be write-locked and active before.
+- * If successful, it is also returned locked.
+- * Allocates memory.
+- * Returns:
+- * KERN_SUCCESS Grew the table.
+- * KERN_SUCCESS Somebody else grew the table.
+- * KERN_SUCCESS The space died.
+- * KERN_NO_SPACE Table has maximum size already.
+- * KERN_RESOURCE_SHORTAGE Couldn't allocate a new table.
+- */
+-
+-kern_return_t
+-ipc_entry_grow_table(ipc_space_t space)
+-{
+- assert(!"reached");
+- ipc_entry_num_t osize, size, nsize;
+-
+- do {
+- ipc_entry_t otable, table;
+- ipc_table_size_t oits, its, nits;
+- mach_port_index_t i, free_index;
+-
+- assert(space->is_active);
+-
+- if (space->is_growing) {
+- /*
+- * Somebody else is growing the table.
+- * We just wait for them to finish.
+- */
+-
+- assert_wait((event_t) space, FALSE);
+- is_write_unlock(space);
+- thread_block((void (*)()) 0);
+- is_write_lock(space);
+- return KERN_SUCCESS;
+- }
+-
+- otable = space->is_table;
+- its = space->is_table_next;
+- size = its->its_size;
+- oits = its - 1;
+- osize = oits->its_size;
+- nits = its + 1;
+- nsize = nits->its_size;
+-
+- if (osize == size) {
+- is_write_unlock(space);
+- printf_once("no more room for ipc_entry_grow_table in space %p\n", space);
+- return KERN_NO_SPACE;
+- }
+-
+- assert((osize < size) && (size <= nsize));
+-
+- /*
+- * OK, we'll attempt to grow the table.
+- * The realloc requires that the old table
+- * remain in existence.
+- */
+-
+- space->is_growing = TRUE;
+- is_write_unlock(space);
+- if (it_entries_reallocable(oits))
+- table = it_entries_realloc(oits, otable, its);
+- else
+- table = it_entries_alloc(its);
+- is_write_lock(space);
+- space->is_growing = FALSE;
+-
+- /*
+- * We need to do a wakeup on the space,
+- * to rouse waiting threads. We defer
+- * this until the space is unlocked,
+- * because we don't want them to spin.
+- */
+-
+- if (table == IE_NULL) {
+- is_write_unlock(space);
+- thread_wakeup((event_t) space);
+- return KERN_RESOURCE_SHORTAGE;
+- }
+-
+- if (!space->is_active) {
+- /*
+- * The space died while it was unlocked.
+- */
+-
+- is_write_unlock(space);
+- thread_wakeup((event_t) space);
+- it_entries_free(its, table);
+- ipc_reverse_remove_all(space);
+- is_write_lock(space);
+- return KERN_SUCCESS;
+- }
+-
+- assert(space->is_table == otable);
+- assert(space->is_table_next == its);
+- assert(space->is_table_size == osize);
+-
+- space->is_table = table;
+- space->is_table_size = size;
+- space->is_table_next = nits;
+-
+- /*
+- * If we did a realloc, it remapped the data.
+- * Otherwise we copy by hand first. Then we have
+- * to clear the index fields in the old part and
+- * zero the new part.
+- */
+-
+- if (!it_entries_reallocable(oits))
+- memcpy(table, otable,
+- osize * sizeof(struct ipc_entry));
+-
+- (void) memset((void *) (table + osize), 0,
+- (size - osize) * sizeof(struct ipc_entry));
+-
+- /*
+- * Put old entries into the reverse hash table.
+- */
+-
+- ipc_reverse_remove_all(space);
+- for (i = 0; i < osize; i++) {
+- ipc_entry_t entry = &table[i];
+-
+- if (IE_BITS_TYPE(entry->ie_bits) ==
+- MACH_PORT_TYPE_SEND)
+- ipc_hash_local_insert(space, entry->ie_object,
+- i, entry);
+- }
+-
+- /*
+- * If there are entries in the splay tree,
+- * then we have work to do:
+- * 1) transfer entries to the table
+- * 2) update is_tree_small
+- */
+-
+- if (space->is_tree_total > 0) {
+- mach_port_index_t index;
+- boolean_t delete;
+- struct ipc_splay_tree ignore;
+- struct ipc_splay_tree move;
+- struct ipc_splay_tree small;
+- ipc_entry_num_t nosmall;
+- ipc_tree_entry_t tentry;
+-
+- /*
+- * The splay tree divides into four regions,
+- * based on the index of the entries:
+- * 1) 0 <= index < osize
+- * 2) osize <= index < size
+- * 3) size <= index < nsize
+- * 4) nsize <= index
+- *
+- * Entries in the first part are ignored.
+- * Entries in the second part, that don't
+- * collide, are moved into the table.
+- * Entries in the third part, that don't
+- * collide, are counted for is_tree_small.
+- * Entries in the fourth part are ignored.
+- */
+-
+- ipc_splay_tree_split(&space->is_tree,
+- MACH_PORT_MAKE(nsize, 0),
+- &small);
+- ipc_splay_tree_split(&small,
+- MACH_PORT_MAKE(size, 0),
+- &move);
+- ipc_splay_tree_split(&move,
+- MACH_PORT_MAKE(osize, 0),
+- &ignore);
+-
+- /* move entries into the table */
+-
+- for (tentry = ipc_splay_traverse_start(&move);
+- tentry != ITE_NULL;
+- tentry = ipc_splay_traverse_next(&move, delete)) {
+- mach_port_t name;
+- mach_port_gen_t gen;
+- mach_port_type_t type;
+- ipc_entry_bits_t bits;
+- ipc_object_t obj;
+- ipc_entry_t entry;
+-
+- name = tentry->ite_name;
+- gen = MACH_PORT_GEN(name);
+- index = MACH_PORT_INDEX(name);
+-
+- assert(tentry->ite_space == space);
+- assert((osize <= index) && (index < size));
+-
+- entry = &table[index];
+-
+- /* collision with previously moved entry? */
+-
+- bits = entry->ie_bits;
+- if (bits != 0) {
+- assert(IE_BITS_TYPE(bits));
+- assert(IE_BITS_GEN(bits) != gen);
+-
+- entry->ie_bits =
+- bits | IE_BITS_COLLISION;
+- delete = FALSE;
+- continue;
+- }
+-
+- bits = tentry->ite_bits;
+- type = IE_BITS_TYPE(bits);
+- assert(type != MACH_PORT_TYPE_NONE);
+-
+- entry->ie_bits = bits | gen;
+- entry->ie_object = obj = tentry->ite_object;
+- entry->ie_request = tentry->ite_request;
+-
+- if (type == MACH_PORT_TYPE_SEND) {
+- ipc_hash_global_delete(space, obj,
+- name, tentry);
+- ipc_hash_local_insert(space, obj,
+- index, entry);
+- }
+-
+- space->is_tree_total--;
+- delete = TRUE;
+- }
+- ipc_splay_traverse_finish(&move);
+-
+- /* count entries for is_tree_small */
+-
+- nosmall = 0; index = 0;
+- for (tentry = ipc_splay_traverse_start(&small);
+- tentry != ITE_NULL;
+- tentry = ipc_splay_traverse_next(&small, FALSE)) {
+- mach_port_index_t nindex;
+-
+- nindex = MACH_PORT_INDEX(tentry->ite_name);
+-
+- if (nindex != index) {
+- nosmall++;
+- index = nindex;
+- }
+- }
+- ipc_splay_traverse_finish(&small);
+-
+- assert(nosmall <= (nsize - size));
+- assert(nosmall <= space->is_tree_total);
+- space->is_tree_small = nosmall;
+-
+- /* put the splay tree back together */
+-
+- ipc_splay_tree_join(&space->is_tree, &small);
+- ipc_splay_tree_join(&space->is_tree, &move);
+- ipc_splay_tree_join(&space->is_tree, &ignore);
+- }
+-
+- /*
+- * Add entries in the new part which still aren't used
+- * to the free list. Add them in reverse order,
+- * and set the generation number to -1, so that
+- * early allocations produce "natural" names.
+- */
+-
+- free_index = table[0].ie_next;
+- for (i = size-1; i >= osize; --i) {
+- ipc_entry_t entry = &table[i];
+-
+- if (entry->ie_bits == 0) {
+- entry->ie_bits = IE_BITS_GEN_MASK;
+- entry->ie_next = free_index;
+- free_index = i;
+- }
+- }
+- table[0].ie_next = free_index;
+-
+- /*
+- * Now we need to free the old table.
+- * If the space dies or grows while unlocked,
+- * then we can quit here.
+- */
+-
+- is_write_unlock(space);
+- thread_wakeup((event_t) space);
+- it_entries_free(oits, otable);
+- is_write_lock(space);
+- if (!space->is_active || (space->is_table_next != nits))
+- return KERN_SUCCESS;
+-
+- /*
+- * We might have moved enough entries from
+- * the splay tree into the table that
+- * the table can be profitably grown again.
+- *
+- * Note that if size == nsize, then
+- * space->is_tree_small == 0.
+- */
+- } while ((space->is_tree_small > 0) &&
+- (((nsize - size) * sizeof(struct ipc_entry)) <
+- (space->is_tree_small * sizeof(struct ipc_tree_entry))));
+-
+- return KERN_SUCCESS;
+-}
+-
+
+ #if MACH_KDB
+ #include <ddb/db_output.h>
+diff --git a/ipc/ipc_entry.h b/ipc/ipc_entry.h
+index 09e1223..451dc53 100644
+--- a/ipc/ipc_entry.h
++++ b/ipc/ipc_entry.h
+@@ -63,26 +63,19 @@ typedef unsigned int ipc_entry_bits_t;
+ typedef ipc_table_elems_t ipc_entry_num_t; /* number of entries */
+
+ typedef struct ipc_entry {
++ mach_port_t ie_name;
+ ipc_entry_bits_t ie_bits;
+ struct ipc_object *ie_object;
+ union {
+ struct ipc_entry *next_free;
+- mach_port_index_t next;
+ /*XXX ipc_port_request_index_t request;*/
+ unsigned int request;
+ } index;
+- union {
+- mach_port_index_t table;
+- struct ipc_tree_entry *tree;
+- } hash;
+ } *ipc_entry_t;
+
+ #define IE_NULL ((ipc_entry_t) 0)
+
+ #define ie_request index.request
+-#define ie_next index.next
+-#define ie_index hash.table
+-#define ie_name hash.table
+ #define ie_next_free index.next_free
+
+ #define IE_BITS_UREFS_MASK 0x0000ffff /* 16 bits of user-reference */
+@@ -93,12 +86,10 @@ typedef struct ipc_entry {
+
+ #define IE_BITS_MAREQUEST 0x00200000 /* 1 bit for msg-accepted */
+
+-#define IE_BITS_COMPAT 0x00400000 /* 1 bit for compatibility */
+-
+-#define IE_BITS_COLLISION 0x00800000 /* 1 bit for collisions */
+-#define IE_BITS_RIGHT_MASK 0x007fffff /* relevant to the right */
++#define IE_BITS_RIGHT_MASK 0x003fffff /* relevant to the right */
+
+ #if PORT_GENERATIONS
++#error "not supported"
+ #define IE_BITS_GEN_MASK 0xff000000U /* 8 bits for generation */
+ #define IE_BITS_GEN(bits) ((bits) & IE_BITS_GEN_MASK)
+ #define IE_BITS_GEN_ONE 0x01000000 /* low bit of generation */
+@@ -109,26 +100,6 @@ typedef struct ipc_entry {
+ #endif
+
+
+-typedef struct ipc_tree_entry {
+- struct ipc_entry ite_entry;
+- mach_port_t ite_name;
+- struct ipc_space *ite_space;
+- struct ipc_tree_entry *ite_lchild;
+- struct ipc_tree_entry *ite_rchild;
+-} *ipc_tree_entry_t;
+-
+-#define ITE_NULL ((ipc_tree_entry_t) 0)
+-
+-#define ite_bits ite_entry.ie_bits
+-#define ite_object ite_entry.ie_object
+-#define ite_request ite_entry.ie_request
+-#define ite_next ite_entry.hash.tree
+-
+-extern struct kmem_cache ipc_tree_entry_cache;
+-
+-#define ite_alloc() ((ipc_tree_entry_t) kmem_cache_alloc(&ipc_tree_entry_cache))
+-#define ite_free(ite) kmem_cache_free(&ipc_tree_entry_cache, (vm_offset_t) (ite))
+-
+ extern struct kmem_cache ipc_entry_cache;
+ #define ie_alloc() ((ipc_entry_t) kmem_cache_alloc(&ipc_entry_cache))
+ #define ie_free(e) kmem_cache_free(&ipc_entry_cache, (vm_offset_t) (e))
+@@ -148,9 +119,6 @@ ipc_entry_alloc_name(ipc_space_t space, mach_port_t name, ipc_entry_t *entryp);
+ extern void
+ ipc_entry_dealloc(ipc_space_t space, mach_port_t name, ipc_entry_t entry);
+
+-extern kern_return_t
+-ipc_entry_grow_table(ipc_space_t space);
+-
+ ipc_entry_t
+ db_ipc_object_by_name(
+ task_t task,
+diff --git a/ipc/ipc_hash.c b/ipc/ipc_hash.c
+deleted file mode 100644
+index 682b854..0000000
+--- a/ipc/ipc_hash.c
++++ /dev/null
+@@ -1,475 +0,0 @@
+-/*
+- * Mach Operating System
+- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
+- * All Rights Reserved.
+- *
+- * Permission to use, copy, modify and distribute this software and its
+- * documentation is hereby granted, provided that both the copyright
+- * notice and this permission notice appear in all copies of the
+- * software, derivative works or modified versions, and any portions
+- * thereof, and that both notices appear in supporting documentation.
+- *
+- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+- *
+- * Carnegie Mellon requests users of this software to return to
+- *
+- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+- * School of Computer Science
+- * Carnegie Mellon University
+- * Pittsburgh PA 15213-3890
+- *
+- * any improvements or extensions that they make and grant Carnegie Mellon
+- * the rights to redistribute these changes.
+- */
+-/*
+- * File: ipc/ipc_hash.c
+- * Author: Rich Draves
+- * Date: 1989
+- *
+- * Entry hash table operations.
+- */
+-
+-#include <kern/printf.h>
+-#include <mach/boolean.h>
+-#include <mach/port.h>
+-#include <kern/lock.h>
+-#include <kern/kalloc.h>
+-#include <ipc/port.h>
+-#include <ipc/ipc_space.h>
+-#include <ipc/ipc_object.h>
+-#include <ipc/ipc_entry.h>
+-#include <ipc/ipc_hash.h>
+-#include <ipc/ipc_init.h>
+-#include <ipc/ipc_types.h>
+-
+-#if MACH_IPC_DEBUG
+-#include <mach/kern_return.h>
+-#include <mach_debug/hash_info.h>
+-#include <vm/vm_map.h>
+-#include <vm/vm_kern.h>
+-#include <vm/vm_user.h>
+-#endif
+-
+-
+-
+-/*
+- * Routine: ipc_hash_lookup
+- * Purpose:
+- * Converts (space, obj) -> (name, entry).
+- * Returns TRUE if an entry was found.
+- * Conditions:
+- * The space must be locked (read or write) throughout.
+- */
+-
+-boolean_t
+-ipc_hash_lookup(
+- ipc_space_t space,
+- ipc_object_t obj,
+- mach_port_t *namep,
+- ipc_entry_t *entryp)
+-{
+- return ipc_hash_local_lookup(space, obj, namep, entryp);
+-}
+-
+-/*
+- * Routine: ipc_hash_insert
+- * Purpose:
+- * Inserts an entry into the appropriate reverse hash table,
+- * so that ipc_hash_lookup will find it.
+- * Conditions:
+- * The space must be write-locked.
+- */
+-
+-void
+-ipc_hash_insert(
+- ipc_space_t space,
+- ipc_object_t obj,
+- mach_port_t name,
+- ipc_entry_t entry)
+-{
+- mach_port_index_t index;
+-
+- index = MACH_PORT_INDEX(name);
+- ipc_hash_local_insert(space, obj, index, entry);
+-}
+-
+-/*
+- * Routine: ipc_hash_delete
+- * Purpose:
+- * Deletes an entry from the appropriate reverse hash table.
+- * Conditions:
+- * The space must be write-locked.
+- */
+-
+-void
+-ipc_hash_delete(
+- ipc_space_t space,
+- ipc_object_t obj,
+- mach_port_t name,
+- ipc_entry_t entry)
+-{
+- mach_port_index_t index;
+-
+- index = MACH_PORT_INDEX(name);
+- ipc_hash_local_delete(space, obj, index, entry);
+-}
+-
+-/*
+- * The global reverse hash table holds splay tree entries.
+- * It is a simple open-chaining hash table with singly-linked buckets.
+- * Each bucket is locked separately, with an exclusive lock.
+- * Within each bucket, move-to-front is used.
+- */
+-
+-ipc_hash_index_t ipc_hash_global_size;
+-ipc_hash_index_t ipc_hash_global_mask;
+-
+-#define IH_GLOBAL_HASH(space, obj) \
+- (((((ipc_hash_index_t) ((vm_offset_t)space)) >> 4) + \
+- (((ipc_hash_index_t) ((vm_offset_t)obj)) >> 6)) & \
+- ipc_hash_global_mask)
+-
+-typedef struct ipc_hash_global_bucket {
+- decl_simple_lock_data(, ihgb_lock_data)
+- ipc_tree_entry_t ihgb_head;
+-} *ipc_hash_global_bucket_t;
+-
+-#define IHGB_NULL ((ipc_hash_global_bucket_t) 0)
+-
+-#define ihgb_lock_init(ihgb) simple_lock_init(&(ihgb)->ihgb_lock_data)
+-#define ihgb_lock(ihgb) simple_lock(&(ihgb)->ihgb_lock_data)
+-#define ihgb_unlock(ihgb) simple_unlock(&(ihgb)->ihgb_lock_data)
+-
+-ipc_hash_global_bucket_t ipc_hash_global_table;
+-
+-/*
+- * Routine: ipc_hash_global_lookup
+- * Purpose:
+- * Converts (space, obj) -> (name, entry).
+- * Looks in the global table, for splay tree entries.
+- * Returns TRUE if an entry was found.
+- * Conditions:
+- * The space must be locked (read or write) throughout.
+- */
+-
+-boolean_t
+-ipc_hash_global_lookup(
+- ipc_space_t space,
+- ipc_object_t obj,
+- mach_port_t *namep,
+- ipc_tree_entry_t *entryp)
+-{
+- assert(!"reached");
+- ipc_hash_global_bucket_t bucket;
+- ipc_tree_entry_t this, *last;
+-
+- assert(space != IS_NULL);
+- assert(obj != IO_NULL);
+-
+- bucket = &ipc_hash_global_table[IH_GLOBAL_HASH(space, obj)];
+- ihgb_lock(bucket);
+-
+- if ((this = bucket->ihgb_head) != ITE_NULL) {
+- if ((this->ite_object == obj) &&
+- (this->ite_space == space)) {
+- /* found it at front; no need to move */
+-
+- *namep = this->ite_name;
+- *entryp = this;
+- } else for (last = &this->ite_next;
+- (this = *last) != ITE_NULL;
+- last = &this->ite_next) {
+- if ((this->ite_object == obj) &&
+- (this->ite_space == space)) {
+- /* found it; move to front */
+-
+- *last = this->ite_next;
+- this->ite_next = bucket->ihgb_head;
+- bucket->ihgb_head = this;
+-
+- *namep = this->ite_name;
+- *entryp = this;
+- break;
+- }
+- }
+- }
+-
+- ihgb_unlock(bucket);
+- return this != ITE_NULL;
+-}
+-
+-/*
+- * Routine: ipc_hash_global_insert
+- * Purpose:
+- * Inserts an entry into the global reverse hash table.
+- * Conditions:
+- * The space must be write-locked.
+- */
+-
+-void
+-ipc_hash_global_insert(
+- ipc_space_t space,
+- ipc_object_t obj,
+- mach_port_t name,
+- ipc_tree_entry_t entry)
+-{
+- assert(!"reached");
+- ipc_hash_global_bucket_t bucket;
+-
+-
+- assert(entry->ite_name == name);
+- assert(space != IS_NULL);
+- assert(entry->ite_space == space);
+- assert(obj != IO_NULL);
+- assert(entry->ite_object == obj);
+-
+- space->is_tree_hash++;
+- assert(space->is_tree_hash <= space->is_tree_total);
+-
+- bucket = &ipc_hash_global_table[IH_GLOBAL_HASH(space, obj)];
+- ihgb_lock(bucket);
+-
+- /* insert at front of bucket */
+-
+- entry->ite_next = bucket->ihgb_head;
+- bucket->ihgb_head = entry;
+-
+- ihgb_unlock(bucket);
+-}
+-
+-/*
+- * Routine: ipc_hash_global_delete
+- * Purpose:
+- * Deletes an entry from the global reverse hash table.
+- * Conditions:
+- * The space must be write-locked.
+- */
+-
+-void
+-ipc_hash_global_delete(
+- ipc_space_t space,
+- ipc_object_t obj,
+- mach_port_t name,
+- ipc_tree_entry_t entry)
+-{
+- assert(!"reached");
+- ipc_hash_global_bucket_t bucket;
+- ipc_tree_entry_t this, *last;
+-
+- assert(entry->ite_name == name);
+- assert(space != IS_NULL);
+- assert(entry->ite_space == space);
+- assert(obj != IO_NULL);
+- assert(entry->ite_object == obj);
+-
+- assert(space->is_tree_hash > 0);
+- space->is_tree_hash--;
+-
+- bucket = &ipc_hash_global_table[IH_GLOBAL_HASH(space, obj)];
+- ihgb_lock(bucket);
+-
+- for (last = &bucket->ihgb_head;
+- (this = *last) != ITE_NULL;
+- last = &this->ite_next) {
+- if (this == entry) {
+- /* found it; remove from bucket */
+-
+- *last = this->ite_next;
+- break;
+- }
+- }
+- assert(this != ITE_NULL);
+-
+- ihgb_unlock(bucket);
+-}
+-
+-/*
+- * Each space has a local reverse mapping from objects to entries
+- * from the space's table. This used to be a hash table.
+- */
+-
+-#define IPC_LOCAL_HASH_INVARIANT(S, O, N, E) \
+- MACRO_BEGIN \
+- assert(IE_BITS_TYPE((E)->ie_bits) == MACH_PORT_TYPE_SEND || \
+- IE_BITS_TYPE((E)->ie_bits) == MACH_PORT_TYPE_SEND_RECEIVE || \
+- IE_BITS_TYPE((E)->ie_bits) == MACH_PORT_TYPE_NONE); \
+- assert((E)->ie_object == (O)); \
+- assert((E)->ie_index == (N)); \
+- MACRO_END
+-
+-/*
+- * Routine: ipc_hash_local_lookup
+- * Purpose:
+- * Converts (space, obj) -> (name, entry).
+- * Looks in the space's local table, for table entries.
+- * Returns TRUE if an entry was found.
+- * Conditions:
+- * The space must be locked (read or write) throughout.
+- */
+-
+-boolean_t
+-ipc_hash_local_lookup(
+- ipc_space_t space,
+- ipc_object_t obj,
+- mach_port_t *namep,
+- ipc_entry_t *entryp)
+-{
+- assert(space != IS_NULL);
+- assert(obj != IO_NULL);
+-
+- *entryp = ipc_reverse_lookup(space, obj);
+- if (*entryp != IE_NULL) {
+- *namep = (*entryp)->ie_index;
+- IPC_LOCAL_HASH_INVARIANT(space, obj, *namep, *entryp);
+- return TRUE;
+- }
+- return FALSE;
+-}
+-
+-/*
+- * Routine: ipc_hash_local_insert
+- * Purpose:
+- * Inserts an entry into the space's reverse hash table.
+- * Conditions:
+- * The space must be write-locked.
+- */
+-
+-void
+-ipc_hash_local_insert(
+- ipc_space_t space,
+- ipc_object_t obj,
+- mach_port_index_t index,
+- ipc_entry_t entry)
+-{
+- kern_return_t kr;
+- assert(index != 0);
+- assert(space != IS_NULL);
+- assert(obj != IO_NULL);
+-
+- entry->ie_index = index;
+- IPC_LOCAL_HASH_INVARIANT(space, obj, index, entry);
+- kr = ipc_reverse_insert(space, obj, entry);
+- assert(kr == 0);
+-}
+-
+-/*
+- * Routine: ipc_hash_local_delete
+- * Purpose:
+- * Deletes an entry from the space's reverse hash table.
+- * Conditions:
+- * The space must be write-locked.
+- */
+-
+-void
+-ipc_hash_local_delete(
+- ipc_space_t space,
+- ipc_object_t obj,
+- mach_port_index_t index,
+- ipc_entry_t entry)
+-{
+- ipc_entry_t removed;
+- assert(index != MACH_PORT_NULL);
+- assert(space != IS_NULL);
+- assert(obj != IO_NULL);
+-
+- IPC_LOCAL_HASH_INVARIANT(space, obj, index, entry);
+- removed = ipc_reverse_remove(space, obj);
+- assert(removed == entry);
+-}
+-
+-/*
+- * Routine: ipc_hash_init
+- * Purpose:
+- * Initialize the reverse hash table implementation.
+- */
+-
+-void
+-ipc_hash_init(void)
+-{
+- ipc_hash_index_t i;
+-
+- /* initialize ipc_hash_global_size */
+-
+- ipc_hash_global_size = IPC_HASH_GLOBAL_SIZE;
+-
+- /* make sure it is a power of two */
+-
+- ipc_hash_global_mask = ipc_hash_global_size - 1;
+- if ((ipc_hash_global_size & ipc_hash_global_mask) != 0) {
+- natural_t bit;
+-
+- /* round up to closest power of two */
+-
+- for (bit = 1;; bit <<= 1) {
+- ipc_hash_global_mask |= bit;
+- ipc_hash_global_size = ipc_hash_global_mask + 1;
+-
+- if ((ipc_hash_global_size & ipc_hash_global_mask) == 0)
+- break;
+- }
+- }
+-
+- /* allocate ipc_hash_global_table */
+-
+- ipc_hash_global_table = (ipc_hash_global_bucket_t)
+- kalloc((vm_size_t) (ipc_hash_global_size *
+- sizeof(struct ipc_hash_global_bucket)));
+- assert(ipc_hash_global_table != IHGB_NULL);
+-
+- /* and initialize it */
+-
+- for (i = 0; i < ipc_hash_global_size; i++) {
+- ipc_hash_global_bucket_t bucket;
+-
+- bucket = &ipc_hash_global_table[i];
+- ihgb_lock_init(bucket);
+- bucket->ihgb_head = ITE_NULL;
+- }
+-}
+-
+-#if MACH_IPC_DEBUG
+-
+-/*
+- * Routine: ipc_hash_info
+- * Purpose:
+- * Return information about the global reverse hash table.
+- * Fills the buffer with as much information as possible
+- * and returns the desired size of the buffer.
+- * Conditions:
+- * Nothing locked. The caller should provide
+- * possibly-pageable memory.
+- */
+-
+-
+-ipc_hash_index_t
+-ipc_hash_info(
+- hash_info_bucket_t *info,
+- mach_msg_type_number_t count)
+-{
+- ipc_hash_index_t i;
+-
+- if (ipc_hash_global_size < count)
+- count = ipc_hash_global_size;
+-
+- for (i = 0; i < count; i++) {
+- ipc_hash_global_bucket_t bucket = &ipc_hash_global_table[i];
+- unsigned int bucket_count = 0;
+- ipc_tree_entry_t entry;
+-
+- ihgb_lock(bucket);
+- for (entry = bucket->ihgb_head;
+- entry != ITE_NULL;
+- entry = entry->ite_next)
+- bucket_count++;
+- ihgb_unlock(bucket);
+-
+- /* don't touch pageable memory while holding locks */
+- info[i].hib_count = bucket_count;
+- }
+-
+- return ipc_hash_global_size;
+-}
+-
+-#endif /* MACH_IPC_DEBUG */
+diff --git a/ipc/ipc_hash.h b/ipc/ipc_hash.h
+deleted file mode 100644
+index 929ba77..0000000
+--- a/ipc/ipc_hash.h
++++ /dev/null
+@@ -1,96 +0,0 @@
+-/*
+- * Mach Operating System
+- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
+- * All Rights Reserved.
+- *
+- * Permission to use, copy, modify and distribute this software and its
+- * documentation is hereby granted, provided that both the copyright
+- * notice and this permission notice appear in all copies of the
+- * software, derivative works or modified versions, and any portions
+- * thereof, and that both notices appear in supporting documentation.
+- *
+- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+- *
+- * Carnegie Mellon requests users of this software to return to
+- *
+- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+- * School of Computer Science
+- * Carnegie Mellon University
+- * Pittsburgh PA 15213-3890
+- *
+- * any improvements or extensions that they make and grant Carnegie Mellon
+- * the rights to redistribute these changes.
+- */
+-/*
+- * File: ipc/ipc_hash.h
+- * Author: Rich Draves
+- * Date: 1989
+- *
+- * Declarations of entry hash table operations.
+- */
+-
+-#ifndef _IPC_IPC_HASH_H_
+-#define _IPC_IPC_HASH_H_
+-
+-#include <mach/boolean.h>
+-#include <mach/kern_return.h>
+-
+-typedef natural_t ipc_hash_index_t;
+-
+-extern void
+-ipc_hash_init(void);
+-
+-#if MACH_IPC_DEBUG
+-
+-extern ipc_hash_index_t
+-ipc_hash_info(hash_info_bucket_t *, mach_msg_type_number_t);
+-
+-#endif /* MACH_IPC_DEBUG */
+-
+-extern boolean_t
+-ipc_hash_lookup(ipc_space_t space, ipc_object_t obj,
+- mach_port_t *namep, ipc_entry_t *entryp);
+-
+-extern void
+-ipc_hash_insert(ipc_space_t space, ipc_object_t obj,
+- mach_port_t name, ipc_entry_t entry);
+-
+-extern void
+-ipc_hash_delete(ipc_space_t space, ipc_object_t obj,
+- mach_port_t name, ipc_entry_t entry);
+-
+-/*
+- * For use by functions that know what they're doing:
+- * the global primitives, for splay tree entries,
+- * and the local primitives, for table entries.
+- */
+-
+-#define IPC_HASH_GLOBAL_SIZE 256
+-
+-extern boolean_t
+-ipc_hash_global_lookup(ipc_space_t space, ipc_object_t obj,
+- mach_port_t *namep, ipc_tree_entry_t *entryp);
+-
+-extern void
+-ipc_hash_global_insert(ipc_space_t space, ipc_object_t obj,
+- mach_port_t name, ipc_tree_entry_t entry);
+-
+-extern void
+-ipc_hash_global_delete(ipc_space_t space, ipc_object_t obj,
+- mach_port_t name, ipc_tree_entry_t entry);
+-
+-extern boolean_t
+-ipc_hash_local_lookup(ipc_space_t space, ipc_object_t obj,
+- mach_port_t *namep, ipc_entry_t *entryp);
+-
+-extern void
+-ipc_hash_local_insert(ipc_space_t space, ipc_object_t obj,
+- mach_port_index_t index, ipc_entry_t entry);
+-
+-extern void
+-ipc_hash_local_delete(ipc_space_t space, ipc_object_t obj,
+- mach_port_index_t index, ipc_entry_t entry);
+-
+-#endif /* _IPC_IPC_HASH_H_ */
+diff --git a/ipc/ipc_init.c b/ipc/ipc_init.c
+index 096e0fb..2c58a6e 100644
+--- a/ipc/ipc_init.c
++++ b/ipc/ipc_init.c
+@@ -47,7 +47,6 @@
+ #include <ipc/ipc_marequest.h>
+ #include <ipc/ipc_notify.h>
+ #include <ipc/ipc_kmsg.h>
+-#include <ipc/ipc_hash.h>
+ #include <ipc/ipc_init.h>
+
+
+@@ -76,9 +75,6 @@ ipc_bootstrap(void)
+ kmem_cache_init(&ipc_space_cache, "ipc_space",
+ sizeof(struct ipc_space), 0, NULL, NULL, NULL, 0);
+
+- kmem_cache_init(&ipc_tree_entry_cache, "ipc_tree_entry",
+- sizeof(struct ipc_tree_entry), 0, NULL, NULL, NULL, 0);
+-
+ kmem_cache_init(&ipc_entry_cache, "ipc_entry",
+ sizeof(struct ipc_entry), 0, NULL, NULL, NULL, 0);
+
+@@ -100,7 +96,6 @@ ipc_bootstrap(void)
+
+ ipc_table_init();
+ ipc_notify_init();
+- ipc_hash_init();
+ ipc_marequest_init();
+ }
+
+diff --git a/ipc/ipc_object.c b/ipc/ipc_object.c
+index ec40062..2d84cf5 100644
+--- a/ipc/ipc_object.c
++++ b/ipc/ipc_object.c
+@@ -41,7 +41,6 @@
+ #include <ipc/ipc_space.h>
+ #include <ipc/ipc_entry.h>
+ #include <ipc/ipc_object.h>
+-#include <ipc/ipc_hash.h>
+ #include <ipc/ipc_right.h>
+ #include <ipc/ipc_notify.h>
+ #include <ipc/ipc_pset.h>
+diff --git a/ipc/ipc_right.c b/ipc/ipc_right.c
+index 503eb1f..217cef5 100644
+--- a/ipc/ipc_right.c
++++ b/ipc/ipc_right.c
+@@ -43,7 +43,6 @@
+ #include <ipc/ipc_entry.h>
+ #include <ipc/ipc_space.h>
+ #include <ipc/ipc_object.h>
+-#include <ipc/ipc_hash.h>
+ #include <ipc/ipc_port.h>
+ #include <ipc/ipc_pset.h>
+ #include <ipc/ipc_marequest.h>
+@@ -142,7 +141,8 @@ ipc_right_reverse(
+ return TRUE;
+ }
+
+- if (ipc_hash_lookup(space, (ipc_object_t) port, namep, entryp)) {
++ if ((*entryp = ipc_reverse_lookup(space, (ipc_object_t) port))) {
++ *namep = (*entryp)->ie_name;
+ assert((entry = *entryp) != IE_NULL);
+ assert(IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_SEND);
+ assert(port == (ipc_port_t) entry->ie_object);
+@@ -392,7 +392,7 @@ ipc_right_check(
+ ipc_marequest_cancel(space, name);
+ }
+
+- ipc_hash_delete(space, (ipc_object_t) port, name, entry);
++ ipc_reverse_remove(space, (ipc_object_t) port);
+ } else {
+ assert(IE_BITS_TYPE(bits) == MACH_PORT_TYPE_SEND_ONCE);
+ assert(IE_BITS_UREFS(bits) == 1);
+@@ -609,8 +609,7 @@ ipc_right_destroy(
+ }
+
+ if (type == MACH_PORT_TYPE_SEND)
+- ipc_hash_delete(space, (ipc_object_t) port,
+- name, entry);
++ ipc_reverse_remove(space, (ipc_object_t) port);
+
+ ip_lock(port);
+
+@@ -789,8 +788,7 @@ ipc_right_dealloc(
+ dnrequest = ipc_right_dncancel_macro(space, port,
+ name, entry);
+
+- ipc_hash_delete(space, (ipc_object_t) port,
+- name, entry);
++ ipc_reverse_remove(space, (ipc_object_t) port);
+
+ if (bits & IE_BITS_MAREQUEST)
+ ipc_marequest_cancel(space, name);
+@@ -1134,8 +1132,7 @@ ipc_right_delta(
+ dnrequest = ipc_right_dncancel_macro(
+ space, port, name, entry);
+
+- ipc_hash_delete(space, (ipc_object_t) port,
+- name, entry);
++ ipc_reverse_remove(space, (ipc_object_t) port);
+
+ if (bits & IE_BITS_MAREQUEST)
+ ipc_marequest_cancel(space, name);
+@@ -1410,8 +1407,8 @@ ipc_right_copyin(
+ assert(IE_BITS_UREFS(bits) > 0);
+ assert(port->ip_srights > 0);
+
+- ipc_hash_insert(space, (ipc_object_t) port,
+- name, entry);
++ entry->ie_name = name;
++ ipc_reverse_insert(space, (ipc_object_t) port, entry);
+
+ ip_reference(port);
+ } else {
+@@ -1534,8 +1531,7 @@ ipc_right_copyin(
+ dnrequest = ipc_right_dncancel_macro(
+ space, port, name, entry);
+
+- ipc_hash_delete(space, (ipc_object_t) port,
+- name, entry);
++ ipc_reverse_remove(space, (ipc_object_t) port);
+
+ if (bits & IE_BITS_MAREQUEST)
+ ipc_marequest_cancel(space, name);
+@@ -1796,8 +1792,7 @@ ipc_right_copyin_two(
+ dnrequest = ipc_right_dncancel_macro(space, port,
+ name, entry);
+
+- ipc_hash_delete(space, (ipc_object_t) port,
+- name, entry);
++ ipc_reverse_remove(space, (ipc_object_t) port);
+
+ if (bits & IE_BITS_MAREQUEST)
+ ipc_marequest_cancel(space, name);
+@@ -1921,8 +1916,8 @@ ipc_right_copyout(
+
+ /* entry is locked holding ref, so can use port */
+
+- ipc_hash_insert(space, (ipc_object_t) port,
+- name, entry);
++ entry->ie_name = name;
++ ipc_reverse_insert(space, (ipc_object_t) port, entry);
+ }
+
+ entry->ie_bits = (bits | MACH_PORT_TYPE_SEND) + 1;
+@@ -1956,8 +1951,7 @@ ipc_right_copyout(
+
+ /* entry is locked holding ref, so can use port */
+
+- ipc_hash_delete(space, (ipc_object_t) port,
+- name, entry);
++ ipc_reverse_remove(space, (ipc_object_t) port);
+ } else {
+ assert(IE_BITS_TYPE(bits) == MACH_PORT_TYPE_NONE);
+ assert(IE_BITS_UREFS(bits) == 0);
+@@ -2083,7 +2077,7 @@ ipc_right_rename(
+ ipc_marequest_rename(space, oname, nname);
+ }
+
+- /* initialize nentry before letting ipc_hash_insert see it */
++ /* initialize nentry before letting ipc_reverse_insert see it */
+
+ assert((nentry->ie_bits & IE_BITS_RIGHT_MASK) == 0);
+ nentry->ie_bits |= bits & IE_BITS_RIGHT_MASK;
+@@ -2097,8 +2091,9 @@ ipc_right_rename(
+ port = (ipc_port_t) object;
+ assert(port != IP_NULL);
+
+- ipc_hash_delete(space, (ipc_object_t) port, oname, oentry);
+- ipc_hash_insert(space, (ipc_object_t) port, nname, nentry);
++ ipc_reverse_remove(space, (ipc_object_t) port);
++ nentry->ie_name = nname;
++ ipc_reverse_insert(space, (ipc_object_t) port, nentry);
+ break;
+ }
+
+diff --git a/ipc/ipc_splay.c b/ipc/ipc_splay.c
+deleted file mode 100644
+index 6fb5bcb..0000000
+--- a/ipc/ipc_splay.c
++++ /dev/null
+@@ -1,920 +0,0 @@
+-/*
+- * Mach Operating System
+- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
+- * All Rights Reserved.
+- *
+- * Permission to use, copy, modify and distribute this software and its
+- * documentation is hereby granted, provided that both the copyright
+- * notice and this permission notice appear in all copies of the
+- * software, derivative works or modified versions, and any portions
+- * thereof, and that both notices appear in supporting documentation.
+- *
+- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+- *
+- * Carnegie Mellon requests users of this software to return to
+- *
+- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+- * School of Computer Science
+- * Carnegie Mellon University
+- * Pittsburgh PA 15213-3890
+- *
+- * any improvements or extensions that they make and grant Carnegie Mellon
+- * the rights to redistribute these changes.
+- */
+-/*
+- */
+-/*
+- * File: ipc/ipc_splay.c
+- * Author: Rich Draves
+- * Date: 1989
+- *
+- * Primitive splay tree operations.
+- */
+-
+-#include <mach/port.h>
+-#include <kern/assert.h>
+-#include <kern/macro_help.h>
+-#include <ipc/ipc_entry.h>
+-#include <ipc/ipc_splay.h>
+-
+-/*
+- * Splay trees are self-adjusting binary search trees.
+- * They have the following attractive properties:
+- * 1) Space efficient; only two pointers per entry.
+- * 2) Robust performance; amortized O(log n) per operation.
+- * 3) Recursion not needed.
+- * This makes them a good fall-back data structure for those
+- * entries that don't fit into the lookup table.
+- *
+- * The paper by Sleator and Tarjan, JACM v. 32, no. 3, pp. 652-686,
+- * describes the splaying operation. ipc_splay_prim_lookup
+- * and ipc_splay_prim_assemble implement the top-down splay
+- * described on p. 669.
+- *
+- * The tree is stored in an unassembled form. If ist_root is null,
+- * then the tree has no entries. Otherwise, ist_name records
+- * the value used for the last lookup. ist_root points to the
+- * middle tree obtained from the top-down splay. ist_ltree and
+- * ist_rtree point to left and right subtrees, whose entries
+- * are all smaller (larger) than those in the middle tree.
+- * ist_ltreep and ist_rtreep are pointers to fields in the
+- * left and right subtrees. ist_ltreep points to the rchild field
+- * of the largest entry in ltree, and ist_rtreep points to the
+- * lchild field of the smallest entry in rtree. The pointed-to
+- * fields aren't initialized. If the left (right) subtree is null,
+- * then ist_ltreep (ist_rtreep) points to the ist_ltree (ist_rtree)
+- * field in the splay structure itself.
+- *
+- * The primary advantage of the unassembled form is that repeated
+- * unsuccessful lookups are efficient. In particular, an unsuccessful
+- * lookup followed by an insert only requires one splaying operation.
+- *
+- * The traversal algorithm works via pointer inversion.
+- * When descending down the tree, child pointers are reversed
+- * to point back to the parent entry. When ascending,
+- * the pointers are restored to their original value.
+- *
+- * The biggest potential problem with the splay tree implementation
+- * is that the operations, even lookup, require an exclusive lock.
+- * If IPC spaces are protected with exclusive locks, then
+- * the splay tree doesn't require its own lock, and ist_lock/ist_unlock
+- * needn't do anything. If IPC spaces are protected with read/write
+- * locks then ist_lock/ist_unlock should provide exclusive access.
+- *
+- * If it becomes important to let lookups run in parallel,
+- * or if the restructuring makes lookups too expensive, then
+- * there is hope. Use a read/write lock on the splay tree.
+- * Keep track of the number of entries in the tree. When doing
+- * a lookup, first try a non-restructuring lookup with a read lock held,
+- * with a bound (based on log of size of the tree) on the number of
+- * entries to traverse. If the lookup runs up against the bound,
+- * then take a write lock and do a reorganizing lookup.
+- * This way, if lookups only access roughly balanced parts
+- * of the tree, then lookups run in parallel and do no restructuring.
+- *
+- * The traversal algorithm currently requires an exclusive lock.
+- * If that is a problem, the tree could be changed from an lchild/rchild
+- * representation to a leftmost child/right sibling representation.
+- * In conjunction with non-restructing lookups, this would let
+- * lookups and traversals all run in parallel. But this representation
+- * is more complicated and would slow down the operations.
+- */
+-
+-/*
+- * Boundary values to hand to ipc_splay_prim_lookup:
+- */
+-
+-#define MACH_PORT_SMALLEST ((mach_port_t) 0)
+-#define MACH_PORT_LARGEST ((mach_port_t) ~0)
+-
+-/*
+- * Routine: ipc_splay_prim_lookup
+- * Purpose:
+- * Searches for the node labeled name in the splay tree.
+- * Returns three nodes (treep, ltreep, rtreep) and
+- * two pointers to nodes (ltreepp, rtreepp).
+- *
+- * ipc_splay_prim_lookup splits the supplied tree into
+- * three subtrees, left, middle, and right, returned
+- * in ltreep, treep, and rtreep.
+- *
+- * If name is present in the tree, then it is at
+- * the root of the middle tree. Otherwise, the root
+- * of the middle tree is the last node traversed.
+- *
+- * ipc_splay_prim_lookup returns a pointer into
+- * the left subtree, to the rchild field of its
+- * largest node, in ltreepp. It returns a pointer
+- * into the right subtree, to the lchild field of its
+- * smallest node, in rtreepp.
+- */
+-
+-static void
+-ipc_splay_prim_lookup(
+- mach_port_t name,
+- ipc_tree_entry_t tree,
+- ipc_tree_entry_t *treep,
+- ipc_tree_entry_t *ltreep,
+- ipc_tree_entry_t **ltreepp,
+- ipc_tree_entry_t *rtreep,
+- ipc_tree_entry_t **rtreepp)
+-{
+- mach_port_t tname; /* temp name */
+- ipc_tree_entry_t lchild, rchild; /* temp child pointers */
+-
+- assert(tree != ITE_NULL);
+-
+-#define link_left \
+-MACRO_BEGIN \
+- *ltreep = tree; \
+- ltreep = &tree->ite_rchild; \
+- tree = *ltreep; \
+-MACRO_END
+-
+-#define link_right \
+-MACRO_BEGIN \
+- *rtreep = tree; \
+- rtreep = &tree->ite_lchild; \
+- tree = *rtreep; \
+-MACRO_END
+-
+-#define rotate_left \
+-MACRO_BEGIN \
+- ipc_tree_entry_t temp = tree; \
+- \
+- tree = temp->ite_rchild; \
+- temp->ite_rchild = tree->ite_lchild; \
+- tree->ite_lchild = temp; \
+-MACRO_END
+-
+-#define rotate_right \
+-MACRO_BEGIN \
+- ipc_tree_entry_t temp = tree; \
+- \
+- tree = temp->ite_lchild; \
+- temp->ite_lchild = tree->ite_rchild; \
+- tree->ite_rchild = temp; \
+-MACRO_END
+-
+- while (name != (tname = tree->ite_name)) {
+- if (name < tname) {
+- /* descend to left */
+-
+- lchild = tree->ite_lchild;
+- if (lchild == ITE_NULL)
+- break;
+- tname = lchild->ite_name;
+-
+- if ((name < tname) &&
+- (lchild->ite_lchild != ITE_NULL))
+- rotate_right;
+- link_right;
+- if ((name > tname) &&
+- (lchild->ite_rchild != ITE_NULL))
+- link_left;
+- } else {
+- /* descend to right */
+-
+- rchild = tree->ite_rchild;
+- if (rchild == ITE_NULL)
+- break;
+- tname = rchild->ite_name;
+-
+- if ((name > tname) &&
+- (rchild->ite_rchild != ITE_NULL))
+- rotate_left;
+- link_left;
+- if ((name < tname) &&
+- (rchild->ite_lchild != ITE_NULL))
+- link_right;
+- }
+-
+- assert(tree != ITE_NULL);
+- }
+-
+- *treep = tree;
+- *ltreepp = ltreep;
+- *rtreepp = rtreep;
+-
+-#undef link_left
+-#undef link_right
+-#undef rotate_left
+-#undef rotate_right
+-}
+-
+-/*
+- * Routine: ipc_splay_prim_assemble
+- * Purpose:
+- * Assembles the results of ipc_splay_prim_lookup
+- * into a splay tree with the found node at the root.
+- *
+- * ltree and rtree are by-reference so storing
+- * through ltreep and rtreep can change them.
+- */
+-
+-static void
+-ipc_splay_prim_assemble(
+- ipc_tree_entry_t tree,
+- ipc_tree_entry_t *ltree,
+- ipc_tree_entry_t *ltreep,
+- ipc_tree_entry_t *rtree,
+- ipc_tree_entry_t *rtreep)
+-{
+- assert(tree != ITE_NULL);
+-
+- *ltreep = tree->ite_lchild;
+- *rtreep = tree->ite_rchild;
+-
+- tree->ite_lchild = *ltree;
+- tree->ite_rchild = *rtree;
+-}
+-
+-/*
+- * Routine: ipc_splay_tree_init
+- * Purpose:
+- * Initialize a raw splay tree for use.
+- */
+-
+-void
+-ipc_splay_tree_init(
+- ipc_splay_tree_t splay)
+-{
+- splay->ist_root = ITE_NULL;
+-}
+-
+-/*
+- * Routine: ipc_splay_tree_pick
+- * Purpose:
+- * Picks and returns a random entry in a splay tree.
+- * Returns FALSE if the splay tree is empty.
+- */
+-
+-boolean_t
+-ipc_splay_tree_pick(
+- ipc_splay_tree_t splay,
+- mach_port_t *namep,
+- ipc_tree_entry_t *entryp)
+-{
+- ipc_tree_entry_t root;
+-
+- ist_lock(splay);
+-
+- root = splay->ist_root;
+- if (root != ITE_NULL) {
+- *namep = root->ite_name;
+- *entryp = root;
+- }
+-
+- ist_unlock(splay);
+-
+- return root != ITE_NULL;
+-}
+-
+-/*
+- * Routine: ipc_splay_tree_lookup
+- * Purpose:
+- * Finds an entry in a splay tree.
+- * Returns ITE_NULL if not found.
+- */
+-
+-ipc_tree_entry_t
+-ipc_splay_tree_lookup(
+- ipc_splay_tree_t splay,
+- mach_port_t name)
+-{
+- ipc_tree_entry_t root;
+-
+- ist_lock(splay);
+-
+- root = splay->ist_root;
+- if (root != ITE_NULL) {
+- if (splay->ist_name != name) {
+- ipc_splay_prim_assemble(root,
+- &splay->ist_ltree, splay->ist_ltreep,
+- &splay->ist_rtree, splay->ist_rtreep);
+- ipc_splay_prim_lookup(name, root, &root,
+- &splay->ist_ltree, &splay->ist_ltreep,
+- &splay->ist_rtree, &splay->ist_rtreep);
+- splay->ist_name = name;
+- splay->ist_root = root;
+- }
+-
+- if (name != root->ite_name)
+- root = ITE_NULL;
+- }
+-
+- ist_unlock(splay);
+-
+- return root;
+-}
+-
+-/*
+- * Routine: ipc_splay_tree_insert
+- * Purpose:
+- * Inserts a new entry into a splay tree.
+- * The caller supplies a new entry.
+- * The name can't already be present in the tree.
+- */
+-
+-void
+-ipc_splay_tree_insert(
+- ipc_splay_tree_t splay,
+- mach_port_t name,
+- ipc_tree_entry_t entry)
+-{
+- ipc_tree_entry_t root;
+-
+- assert(entry != ITE_NULL);
+-
+- ist_lock(splay);
+-
+- root = splay->ist_root;
+- if (root == ITE_NULL) {
+- entry->ite_lchild = ITE_NULL;
+- entry->ite_rchild = ITE_NULL;
+- } else {
+- if (splay->ist_name != name) {
+- ipc_splay_prim_assemble(root,
+- &splay->ist_ltree, splay->ist_ltreep,
+- &splay->ist_rtree, splay->ist_rtreep);
+- ipc_splay_prim_lookup(name, root, &root,
+- &splay->ist_ltree, &splay->ist_ltreep,
+- &splay->ist_rtree, &splay->ist_rtreep);
+- }
+-
+- assert(root->ite_name != name);
+-
+- if (name < root->ite_name) {
+- assert(root->ite_lchild == ITE_NULL);
+-
+- *splay->ist_ltreep = ITE_NULL;
+- *splay->ist_rtreep = root;
+- } else {
+- assert(root->ite_rchild == ITE_NULL);
+-
+- *splay->ist_ltreep = root;
+- *splay->ist_rtreep = ITE_NULL;
+- }
+-
+- entry->ite_lchild = splay->ist_ltree;
+- entry->ite_rchild = splay->ist_rtree;
+- }
+-
+- entry->ite_name = name;
+- splay->ist_root = entry;
+- splay->ist_name = name;
+- splay->ist_ltreep = &splay->ist_ltree;
+- splay->ist_rtreep = &splay->ist_rtree;
+-
+- ist_unlock(splay);
+-}
+-
+-/*
+- * Routine: ipc_splay_tree_delete
+- * Purpose:
+- * Deletes an entry from a splay tree.
+- * The name must be present in the tree.
+- * Frees the entry.
+- *
+- * The "entry" argument isn't currently used.
+- * Other implementations might want it, though.
+- */
+-
+-void
+-ipc_splay_tree_delete(
+- ipc_splay_tree_t splay,
+- mach_port_t name,
+- ipc_tree_entry_t entry)
+-{
+- ipc_tree_entry_t root, saved;
+-
+- ist_lock(splay);
+-
+- root = splay->ist_root;
+- assert(root != ITE_NULL);
+-
+- if (splay->ist_name != name) {
+- ipc_splay_prim_assemble(root,
+- &splay->ist_ltree, splay->ist_ltreep,
+- &splay->ist_rtree, splay->ist_rtreep);
+- ipc_splay_prim_lookup(name, root, &root,
+- &splay->ist_ltree, &splay->ist_ltreep,
+- &splay->ist_rtree, &splay->ist_rtreep);
+- }
+-
+- assert(root->ite_name == name);
+- assert(root == entry);
+-
+- *splay->ist_ltreep = root->ite_lchild;
+- *splay->ist_rtreep = root->ite_rchild;
+- ite_free(root);
+-
+- root = splay->ist_ltree;
+- saved = splay->ist_rtree;
+-
+- if (root == ITE_NULL)
+- root = saved;
+- else if (saved != ITE_NULL) {
+- /*
+- * Find the largest node in the left subtree, and splay it
+- * to the root. Then add the saved right subtree.
+- */
+-
+- ipc_splay_prim_lookup(MACH_PORT_LARGEST, root, &root,
+- &splay->ist_ltree, &splay->ist_ltreep,
+- &splay->ist_rtree, &splay->ist_rtreep);
+- ipc_splay_prim_assemble(root,
+- &splay->ist_ltree, splay->ist_ltreep,
+- &splay->ist_rtree, splay->ist_rtreep);
+-
+- assert(root->ite_rchild == ITE_NULL);
+- root->ite_rchild = saved;
+- }
+-
+- splay->ist_root = root;
+- if (root != ITE_NULL) {
+- splay->ist_name = root->ite_name;
+- splay->ist_ltreep = &splay->ist_ltree;
+- splay->ist_rtreep = &splay->ist_rtree;
+- }
+-
+- ist_unlock(splay);
+-}
+-
+-/*
+- * Routine: ipc_splay_tree_split
+- * Purpose:
+- * Split a splay tree. Puts all entries smaller than "name"
+- * into a new tree, "small".
+- *
+- * Doesn't do locking on "small", because nobody else
+- * should be fiddling with the uninitialized tree.
+- */
+-
+-void
+-ipc_splay_tree_split(
+- ipc_splay_tree_t splay,
+- mach_port_t name,
+- ipc_splay_tree_t small)
+-{
+- ipc_tree_entry_t root;
+-
+- ipc_splay_tree_init(small);
+-
+- ist_lock(splay);
+-
+- root = splay->ist_root;
+- if (root != ITE_NULL) {
+- /* lookup name, to get it (or last traversed) to the top */
+-
+- if (splay->ist_name != name) {
+- ipc_splay_prim_assemble(root,
+- &splay->ist_ltree, splay->ist_ltreep,
+- &splay->ist_rtree, splay->ist_rtreep);
+- ipc_splay_prim_lookup(name, root, &root,
+- &splay->ist_ltree, &splay->ist_ltreep,
+- &splay->ist_rtree, &splay->ist_rtreep);
+- }
+-
+- if (root->ite_name < name) {
+- /* root goes into small */
+-
+- *splay->ist_ltreep = root->ite_lchild;
+- *splay->ist_rtreep = ITE_NULL;
+- root->ite_lchild = splay->ist_ltree;
+- assert(root->ite_rchild == ITE_NULL);
+-
+- small->ist_root = root;
+- small->ist_name = root->ite_name;
+- small->ist_ltreep = &small->ist_ltree;
+- small->ist_rtreep = &small->ist_rtree;
+-
+- /* rtree goes into splay */
+-
+- root = splay->ist_rtree;
+- splay->ist_root = root;
+- if (root != ITE_NULL) {
+- splay->ist_name = root->ite_name;
+- splay->ist_ltreep = &splay->ist_ltree;
+- splay->ist_rtreep = &splay->ist_rtree;
+- }
+- } else {
+- /* root stays in splay */
+-
+- *splay->ist_ltreep = root->ite_lchild;
+- root->ite_lchild = ITE_NULL;
+-
+- splay->ist_root = root;
+- splay->ist_name = name;
+- splay->ist_ltreep = &splay->ist_ltree;
+-
+- /* ltree goes into small */
+-
+- root = splay->ist_ltree;
+- small->ist_root = root;
+- if (root != ITE_NULL) {
+- small->ist_name = root->ite_name;
+- small->ist_ltreep = &small->ist_ltree;
+- small->ist_rtreep = &small->ist_rtree;
+- }
+- }
+- }
+-
+- ist_unlock(splay);
+-}
+-
+-/*
+- * Routine: ipc_splay_tree_join
+- * Purpose:
+- * Joins two splay trees. Merges the entries in "small",
+- * which must all be smaller than the entries in "splay",
+- * into "splay".
+- */
+-
+-void
+-ipc_splay_tree_join(
+- ipc_splay_tree_t splay,
+- ipc_splay_tree_t small)
+-{
+- ipc_tree_entry_t sroot;
+-
+- /* pull entries out of small */
+-
+- ist_lock(small);
+-
+- sroot = small->ist_root;
+- if (sroot != ITE_NULL) {
+- ipc_splay_prim_assemble(sroot,
+- &small->ist_ltree, small->ist_ltreep,
+- &small->ist_rtree, small->ist_rtreep);
+- small->ist_root = ITE_NULL;
+- }
+-
+- ist_unlock(small);
+-
+- /* put entries, if any, into splay */
+-
+- if (sroot != ITE_NULL) {
+- ipc_tree_entry_t root;
+-
+- ist_lock(splay);
+-
+- root = splay->ist_root;
+- if (root == ITE_NULL) {
+- root = sroot;
+- } else {
+- /* get smallest entry in splay tree to top */
+-
+- if (splay->ist_name != MACH_PORT_SMALLEST) {
+- ipc_splay_prim_assemble(root,
+- &splay->ist_ltree, splay->ist_ltreep,
+- &splay->ist_rtree, splay->ist_rtreep);
+- ipc_splay_prim_lookup(MACH_PORT_SMALLEST,
+- root, &root,
+- &splay->ist_ltree, &splay->ist_ltreep,
+- &splay->ist_rtree, &splay->ist_rtreep);
+- }
+-
+- ipc_splay_prim_assemble(root,
+- &splay->ist_ltree, splay->ist_ltreep,
+- &splay->ist_rtree, splay->ist_rtreep);
+-
+- assert(root->ite_lchild == ITE_NULL);
+- assert(sroot->ite_name < root->ite_name);
+- root->ite_lchild = sroot;
+- }
+-
+- splay->ist_root = root;
+- splay->ist_name = root->ite_name;
+- splay->ist_ltreep = &splay->ist_ltree;
+- splay->ist_rtreep = &splay->ist_rtree;
+-
+- ist_unlock(splay);
+- }
+-}
+-
+-/*
+- * Routine: ipc_splay_tree_bounds
+- * Purpose:
+- * Given a name, returns the largest value present
+- * in the tree that is smaller than or equal to the name,
+- * or ~0 if no such value exists. Similarly, returns
+- * the smallest value present that is greater than or
+- * equal to the name, or 0 if no such value exists.
+- *
+- * Hence, if
+- * lower = upper, then lower = name = upper
+- * and name is present in the tree
+- * lower = ~0 and upper = 0,
+- * then the tree is empty
+- * lower = ~0 and upper > 0, then name < upper
+- * and upper is smallest value in tree
+- * lower < ~0 and upper = 0, then lower < name
+- * and lower is largest value in tree
+- * lower < ~0 and upper > 0, then lower < name < upper
+- * and they are tight bounds on name
+- *
+- * (Note MACH_PORT_SMALLEST = 0 and MACH_PORT_LARGEST = ~0.)
+- */
+-
+-void
+-ipc_splay_tree_bounds(
+- ipc_splay_tree_t splay,
+- mach_port_t name,
+- mach_port_t *lowerp,
+- mach_port_t *upperp)
+-{
+- ipc_tree_entry_t root;
+-
+- ist_lock(splay);
+-
+- root = splay->ist_root;
+- if (root == ITE_NULL) {
+- *lowerp = MACH_PORT_LARGEST;
+- *upperp = MACH_PORT_SMALLEST;
+- } else {
+- mach_port_t rname;
+-
+- if (splay->ist_name != name) {
+- ipc_splay_prim_assemble(root,
+- &splay->ist_ltree, splay->ist_ltreep,
+- &splay->ist_rtree, splay->ist_rtreep);
+- ipc_splay_prim_lookup(name, root, &root,
+- &splay->ist_ltree, &splay->ist_ltreep,
+- &splay->ist_rtree, &splay->ist_rtreep);
+- splay->ist_name = name;
+- splay->ist_root = root;
+- }
+-
+- rname = root->ite_name;
+-
+- /*
+- * OK, it's a hack. We convert the ltreep and rtreep
+- * pointers back into real entry pointers,
+- * so we can pick the names out of the entries.
+- */
+-
+- if (rname <= name)
+- *lowerp = rname;
+- else if (splay->ist_ltreep == &splay->ist_ltree)
+- *lowerp = MACH_PORT_LARGEST;
+- else {
+- ipc_tree_entry_t entry;
+-
+- entry = (ipc_tree_entry_t)
+- ((char *)splay->ist_ltreep -
+- ((char *)&root->ite_rchild -
+- (char *)root));
+- *lowerp = entry->ite_name;
+- }
+-
+- if (rname >= name)
+- *upperp = rname;
+- else if (splay->ist_rtreep == &splay->ist_rtree)
+- *upperp = MACH_PORT_SMALLEST;
+- else {
+- ipc_tree_entry_t entry;
+-
+- entry = (ipc_tree_entry_t)
+- ((char *)splay->ist_rtreep -
+- ((char *)&root->ite_lchild -
+- (char *)root));
+- *upperp = entry->ite_name;
+- }
+- }
+-
+- ist_unlock(splay);
+-}
+-
+-/*
+- * Routine: ipc_splay_traverse_start
+- * Routine: ipc_splay_traverse_next
+- * Routine: ipc_splay_traverse_finish
+- * Purpose:
+- * Perform a symmetric order traversal of a splay tree.
+- * Usage:
+- * for (entry = ipc_splay_traverse_start(splay);
+- * entry != ITE_NULL;
+- * entry = ipc_splay_traverse_next(splay, delete)) {
+- * do something with entry
+- * }
+- * ipc_splay_traverse_finish(splay);
+- *
+- * If "delete" is TRUE, then the current entry
+- * is removed from the tree and deallocated.
+- *
+- * During the traversal, the splay tree is locked.
+- */
+-
+-ipc_tree_entry_t
+-ipc_splay_traverse_start(
+- ipc_splay_tree_t splay)
+-{
+- ipc_tree_entry_t current, parent;
+-
+- ist_lock(splay);
+-
+- current = splay->ist_root;
+- if (current != ITE_NULL) {
+- ipc_splay_prim_assemble(current,
+- &splay->ist_ltree, splay->ist_ltreep,
+- &splay->ist_rtree, splay->ist_rtreep);
+-
+- parent = ITE_NULL;
+-
+- while (current->ite_lchild != ITE_NULL) {
+- ipc_tree_entry_t next;
+-
+- next = current->ite_lchild;
+- current->ite_lchild = parent;
+- parent = current;
+- current = next;
+- }
+-
+- splay->ist_ltree = current;
+- splay->ist_rtree = parent;
+- }
+-
+- return current;
+-}
+-
+-ipc_tree_entry_t
+-ipc_splay_traverse_next(
+- ipc_splay_tree_t splay,
+- boolean_t delete)
+-{
+- ipc_tree_entry_t current, parent;
+-
+- /* pick up where traverse_entry left off */
+-
+- current = splay->ist_ltree;
+- parent = splay->ist_rtree;
+- assert(current != ITE_NULL);
+-
+- if (!delete)
+- goto traverse_right;
+-
+- /* we must delete current and patch the tree */
+-
+- if (current->ite_lchild == ITE_NULL) {
+- if (current->ite_rchild == ITE_NULL) {
+- /* like traverse_back, but with deletion */
+-
+- if (parent == ITE_NULL) {
+- ite_free(current);
+-
+- splay->ist_root = ITE_NULL;
+- return ITE_NULL;
+- }
+-
+- if (current->ite_name < parent->ite_name) {
+- ite_free(current);
+-
+- current = parent;
+- parent = current->ite_lchild;
+- current->ite_lchild = ITE_NULL;
+- goto traverse_entry;
+- } else {
+- ite_free(current);
+-
+- current = parent;
+- parent = current->ite_rchild;
+- current->ite_rchild = ITE_NULL;
+- goto traverse_back;
+- }
+- } else {
+- ipc_tree_entry_t prev;
+-
+- prev = current;
+- current = current->ite_rchild;
+- ite_free(prev);
+- goto traverse_left;
+- }
+- } else {
+- if (current->ite_rchild == ITE_NULL) {
+- ipc_tree_entry_t prev;
+-
+- prev = current;
+- current = current->ite_lchild;
+- ite_free(prev);
+- goto traverse_back;
+- } else {
+- ipc_tree_entry_t prev;
+- ipc_tree_entry_t ltree, rtree;
+- ipc_tree_entry_t *ltreep, *rtreep;
+-
+- /* replace current with largest of left children */
+-
+- prev = current;
+- ipc_splay_prim_lookup(MACH_PORT_LARGEST,
+- current->ite_lchild, &current,
+- &ltree, &ltreep, &rtree, &rtreep);
+- ipc_splay_prim_assemble(current,
+- &ltree, ltreep, &rtree, rtreep);
+-
+- assert(current->ite_rchild == ITE_NULL);
+- current->ite_rchild = prev->ite_rchild;
+- ite_free(prev);
+- goto traverse_right;
+- }
+- }
+- /*NOTREACHED*/
+-
+- /*
+- * A state machine: for each entry, we
+- * 1) traverse left subtree
+- * 2) traverse the entry
+- * 3) traverse right subtree
+- * 4) traverse back to parent
+- */
+-
+- traverse_left:
+- if (current->ite_lchild != ITE_NULL) {
+- ipc_tree_entry_t next;
+-
+- next = current->ite_lchild;
+- current->ite_lchild = parent;
+- parent = current;
+- current = next;
+- goto traverse_left;
+- }
+-
+- traverse_entry:
+- splay->ist_ltree = current;
+- splay->ist_rtree = parent;
+- return current;
+-
+- traverse_right:
+- if (current->ite_rchild != ITE_NULL) {
+- ipc_tree_entry_t next;
+-
+- next = current->ite_rchild;
+- current->ite_rchild = parent;
+- parent = current;
+- current = next;
+- goto traverse_left;
+- }
+-
+- traverse_back:
+- if (parent == ITE_NULL) {
+- splay->ist_root = current;
+- return ITE_NULL;
+- }
+-
+- if (current->ite_name < parent->ite_name) {
+- ipc_tree_entry_t prev;
+-
+- prev = current;
+- current = parent;
+- parent = current->ite_lchild;
+- current->ite_lchild = prev;
+- goto traverse_entry;
+- } else {
+- ipc_tree_entry_t prev;
+-
+- prev = current;
+- current = parent;
+- parent = current->ite_rchild;
+- current->ite_rchild = prev;
+- goto traverse_back;
+- }
+-}
+-
+-void
+-ipc_splay_traverse_finish(
+- ipc_splay_tree_t splay)
+-{
+- ipc_tree_entry_t root;
+-
+- root = splay->ist_root;
+- if (root != ITE_NULL) {
+- splay->ist_name = root->ite_name;
+- splay->ist_ltreep = &splay->ist_ltree;
+- splay->ist_rtreep = &splay->ist_rtree;
+- }
+-
+- ist_unlock(splay);
+-}
+-
+diff --git a/ipc/ipc_splay.h b/ipc/ipc_splay.h
+deleted file mode 100644
+index d3316ef..0000000
+--- a/ipc/ipc_splay.h
++++ /dev/null
+@@ -1,114 +0,0 @@
+-/*
+- * Mach Operating System
+- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
+- * All Rights Reserved.
+- *
+- * Permission to use, copy, modify and distribute this software and its
+- * documentation is hereby granted, provided that both the copyright
+- * notice and this permission notice appear in all copies of the
+- * software, derivative works or modified versions, and any portions
+- * thereof, and that both notices appear in supporting documentation.
+- *
+- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+- *
+- * Carnegie Mellon requests users of this software to return to
+- *
+- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+- * School of Computer Science
+- * Carnegie Mellon University
+- * Pittsburgh PA 15213-3890
+- *
+- * any improvements or extensions that they make and grant Carnegie Mellon
+- * the rights to redistribute these changes.
+- */
+-/*
+- */
+-/*
+- * File: ipc/ipc_splay.h
+- * Author: Rich Draves
+- * Date: 1989
+- *
+- * Declarations of primitive splay tree operations.
+- */
+-
+-#ifndef _IPC_IPC_SPLAY_H_
+-#define _IPC_IPC_SPLAY_H_
+-
+-#include <mach/port.h>
+-#include <kern/assert.h>
+-#include <kern/macro_help.h>
+-#include <ipc/ipc_entry.h>
+-
+-typedef struct ipc_splay_tree {
+- mach_port_t ist_name; /* name used in last lookup */
+- ipc_tree_entry_t ist_root; /* root of middle tree */
+- ipc_tree_entry_t ist_ltree; /* root of left tree */
+- ipc_tree_entry_t *ist_ltreep; /* pointer into left tree */
+- ipc_tree_entry_t ist_rtree; /* root of right tree */
+- ipc_tree_entry_t *ist_rtreep; /* pointer into right tree */
+-} *ipc_splay_tree_t;
+-
+-#define ist_lock(splay) /* no locking */
+-#define ist_unlock(splay) /* no locking */
+-
+-/* Initialize a raw splay tree */
+-extern void ipc_splay_tree_init(
+- ipc_splay_tree_t splay);
+-
+-/* Pick a random entry in a splay tree */
+-extern boolean_t ipc_splay_tree_pick(
+- ipc_splay_tree_t splay,
+- mach_port_t *namep,
+- ipc_tree_entry_t *entryp);
+-
+-/* Find an entry in a splay tree */
+-extern ipc_tree_entry_t ipc_splay_tree_lookup(
+- ipc_splay_tree_t splay,
+- mach_port_t name);
+-
+-/* Insert a new entry into a splay tree */
+-extern void ipc_splay_tree_insert(
+- ipc_splay_tree_t splay,
+- mach_port_t name,
+- ipc_tree_entry_t entry);
+-
+-/* Delete an entry from a splay tree */
+-extern void ipc_splay_tree_delete(
+- ipc_splay_tree_t splay,
+- mach_port_t name,
+- ipc_tree_entry_t entry);
+-
+-/* Split a splay tree */
+-extern void ipc_splay_tree_split(
+- ipc_splay_tree_t splay,
+- mach_port_t name,
+- ipc_splay_tree_t entry);
+-
+-/* Join two splay trees */
+-extern void ipc_splay_tree_join(
+- ipc_splay_tree_t splay,
+- ipc_splay_tree_t small);
+-
+-/* Do a bounded splay tree lookup */
+-extern void ipc_splay_tree_bounds(
+- ipc_splay_tree_t splay,
+- mach_port_t name,
+- mach_port_t *lowerp,
+- mach_port_t *upperp);
+-
+-/* Initialize a symmetric order traversal of a splay tree */
+-extern ipc_tree_entry_t ipc_splay_traverse_start(
+- ipc_splay_tree_t splay);
+-
+-/* Return the next entry in a symmetric order traversal of a splay tree */
+-extern ipc_tree_entry_t ipc_splay_traverse_next(
+- ipc_splay_tree_t splay,
+- boolean_t delete);
+-
+-/* Terminate a symmetric order traversal of a splay tree */
+-extern void ipc_splay_traverse_finish(
+- ipc_splay_tree_t splay);
+-
+-#endif /* _IPC_IPC_SPLAY_H_ */
+--
+2.1.4
+