summaryrefslogtreecommitdiff
path: root/ipc
diff options
context:
space:
mode:
Diffstat (limited to 'ipc')
-rw-r--r--ipc/ipc_entry.c795
-rw-r--r--ipc/ipc_entry.h72
-rw-r--r--ipc/ipc_hash.c620
-rw-r--r--ipc/ipc_hash.h96
-rw-r--r--ipc/ipc_init.c10
-rw-r--r--ipc/ipc_kmsg.c345
-rw-r--r--ipc/ipc_kmsg.h29
-rw-r--r--ipc/ipc_kmsg_queue.h2
-rwxr-xr-xipc/ipc_machdep.h4
-rw-r--r--ipc/ipc_marequest.c34
-rw-r--r--ipc/ipc_mqueue.c14
-rw-r--r--ipc/ipc_mqueue.h3
-rw-r--r--ipc/ipc_notify.c42
-rw-r--r--ipc/ipc_object.c58
-rw-r--r--ipc/ipc_object.h6
-rw-r--r--ipc/ipc_port.c88
-rw-r--r--ipc/ipc_port.h30
-rw-r--r--ipc/ipc_print.h39
-rw-r--r--ipc/ipc_pset.c5
-rw-r--r--ipc/ipc_pset.h3
-rw-r--r--ipc/ipc_right.c91
-rw-r--r--ipc/ipc_space.c104
-rw-r--r--ipc/ipc_space.h228
-rw-r--r--ipc/ipc_splay.c920
-rw-r--r--ipc/ipc_splay.h114
-rw-r--r--ipc/ipc_table.c70
-rw-r--r--ipc/ipc_table.h59
-rw-r--r--ipc/ipc_thread.h8
-rw-r--r--ipc/mach_debug.c339
-rw-r--r--ipc/mach_msg.c299
-rw-r--r--ipc/mach_port.c263
-rw-r--r--ipc/mach_port.h11
-rw-r--r--ipc/mach_rpc.c9
-rw-r--r--ipc/notify.defs22
-rw-r--r--ipc/port.h7
35 files changed, 1065 insertions, 3774 deletions
diff --git a/ipc/ipc_entry.c b/ipc/ipc_entry.c
index 3a062447..0414ba5f 100644
--- a/ipc/ipc_entry.c
+++ b/ipc/ipc_entry.c
@@ -46,158 +46,17 @@
#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_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)
-{
- 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:
- * Searches for an entry, given its name.
- * Conditions:
- * The space must be read or write locked throughout.
- * The space must be active.
- */
-
-ipc_entry_t
-ipc_entry_lookup(space, name)
- ipc_space_t space;
- mach_port_t name;
-{
- mach_port_index_t index;
- ipc_entry_t entry;
-
- assert(space->is_active);
-
- index = MACH_PORT_INDEX(name);
- if (index < space->is_table_size) {
- entry = &space->is_table[index];
- if (IE_BITS_GEN(entry->ie_bits) != MACH_PORT_GEN(name))
- if (entry->ie_bits & IE_BITS_COLLISION) {
- assert(space->is_tree_total > 0);
- goto tree_lookup;
- } else
- entry = IE_NULL;
- else if (IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE)
- entry = IE_NULL;
- } else if (space->is_tree_total == 0)
- entry = IE_NULL;
- else
- tree_lookup:
- entry = (ipc_entry_t)
- ipc_splay_tree_lookup(&space->is_tree, name);
-
- assert((entry == IE_NULL) || IE_BITS_TYPE(entry->ie_bits));
- return entry;
-}
-
-/*
- * Routine: ipc_entry_get
- * Purpose:
- * Tries to allocate an entry out of the space.
- * Conditions:
- * The space is write-locked and active throughout.
- * An object may be locked. Will not allocate memory.
- * Returns:
- * KERN_SUCCESS A free entry was found.
- * KERN_NO_SPACE No entry allocated.
- */
-
-kern_return_t
-ipc_entry_get(space, namep, entryp)
- ipc_space_t space;
- mach_port_t *namep;
- ipc_entry_t *entryp;
-{
- ipc_entry_t table;
- mach_port_index_t first_free;
- mach_port_t new_name;
- ipc_entry_t free_entry;
-
- assert(space->is_active);
-
- table = space->is_table;
- first_free = table->ie_next;
-
- if (first_free == 0)
- return KERN_NO_SPACE;
-
- free_entry = &table[first_free];
- table->ie_next = free_entry->ie_next;
-
- /*
- * Initialize the new entry. We need only
- * increment the generation number and clear ie_request.
- */
-
- {
- mach_port_gen_t gen;
-
- assert((free_entry->ie_bits &~ IE_BITS_GEN_MASK) == 0);
- gen = free_entry->ie_bits + IE_BITS_GEN_ONE;
- free_entry->ie_bits = gen;
- free_entry->ie_request = 0;
- new_name = MACH_PORT_MAKE(first_free, gen);
- }
-
- /*
- * The new name can't be MACH_PORT_NULL because index
- * is non-zero. It can't be MACH_PORT_DEAD because
- * the table isn't allowed to grow big enough.
- * (See comment in ipc/ipc_table.h.)
- */
-
- assert(MACH_PORT_VALID(new_name));
- assert(free_entry->ie_object == IO_NULL);
-
- *namep = new_name;
- *entryp = free_entry;
- return KERN_SUCCESS;
-}
+struct kmem_cache ipc_entry_cache;
/*
* Routine: ipc_entry_alloc
* Purpose:
* Allocate an entry out of the space.
* Conditions:
- * The space is not locked before, but it is write-locked after
- * if the call is successful. May allocate memory.
+ * The space must be write-locked. May allocate memory.
* Returns:
* KERN_SUCCESS An entry was allocated.
* KERN_INVALID_TASK The space is dead.
@@ -212,23 +71,37 @@ ipc_entry_alloc(
ipc_entry_t *entryp)
{
kern_return_t kr;
+ ipc_entry_t entry;
+ rdxtree_key_t key;
- is_write_lock(space);
+ if (!space->is_active) {
+ return KERN_INVALID_TASK;
+ }
- for (;;) {
- if (!space->is_active) {
- is_write_unlock(space);
- return KERN_INVALID_TASK;
- }
+ kr = ipc_entry_get(space, namep, entryp);
+ if (kr == KERN_SUCCESS)
+ return kr;
- kr = ipc_entry_get(space, namep, entryp);
- if (kr == KERN_SUCCESS)
- return kr;
+ entry = ie_alloc();
+ if (entry == IE_NULL) {
+ return KERN_RESOURCE_SHORTAGE;
+ }
- kr = ipc_entry_grow_table(space);
- if (kr != KERN_SUCCESS)
- return kr; /* space is unlocked */
+ kr = rdxtree_insert_alloc(&space->is_map, entry, &key);
+ if (kr) {
+ ie_free(entry);
+ return kr;
}
+ space->is_size += 1;
+
+ entry->ie_bits = 0;
+ entry->ie_object = IO_NULL;
+ entry->ie_request = 0;
+ entry->ie_name = (mach_port_t) key;
+
+ *entryp = entry;
+ *namep = (mach_port_t) key;
+ return KERN_SUCCESS;
}
/*
@@ -237,8 +110,7 @@ ipc_entry_alloc(
* Allocates/finds an entry with a specific name.
* If an existing entry is returned, its type will be nonzero.
* Conditions:
- * The space is not locked before, but it is write-locked after
- * if the call is successful. May allocate memory.
+ * The space must be write-locked. May allocate memory.
* Returns:
* KERN_SUCCESS Found existing entry with same name.
* KERN_SUCCESS Allocated a new entry.
@@ -252,601 +124,80 @@ ipc_entry_alloc_name(
mach_port_t name,
ipc_entry_t *entryp)
{
- mach_port_index_t index = MACH_PORT_INDEX(name);
- mach_port_gen_t gen = MACH_PORT_GEN(name);
- ipc_tree_entry_t tree_entry = ITE_NULL;
-
+ kern_return_t kr;
+ ipc_entry_t entry, e, *prevp;
+ void **slot;
assert(MACH_PORT_VALID(name));
+ if (!space->is_active) {
+ return KERN_INVALID_TASK;
+ }
- is_write_lock(space);
-
- for (;;) {
- ipc_entry_t entry;
- ipc_tree_entry_t tentry;
- ipc_table_size_t its;
-
- if (!space->is_active) {
- is_write_unlock(space);
- if (tree_entry) ite_free(tree_entry);
- return KERN_INVALID_TASK;
- }
-
- /*
- * If we are under the table cutoff,
- * there are three cases:
- * 1) The entry is inuse, for the same name
- * 2) The entry is inuse, for a different name
- * 3) The entry is free
- */
-
- if ((0 < index) && (index < space->is_table_size)) {
- ipc_entry_t table = space->is_table;
-
- entry = &table[index];
-
- if (IE_BITS_TYPE(entry->ie_bits)) {
- if (IE_BITS_GEN(entry->ie_bits) == gen) {
- *entryp = entry;
- if (tree_entry) ite_free(tree_entry);
- return KERN_SUCCESS;
- }
- } else {
- mach_port_index_t free_index, next_index;
-
- /*
- * Rip the entry out of the free list.
- */
-
- for (free_index = 0;
- (next_index = table[free_index].ie_next)
- != index;
- free_index = next_index)
- continue;
-
- table[free_index].ie_next =
- table[next_index].ie_next;
-
- entry->ie_bits = gen;
- assert(entry->ie_object == IO_NULL);
- entry->ie_request = 0;
-
- *entryp = entry;
- if (tree_entry) ite_free(tree_entry);
- return KERN_SUCCESS;
- }
- }
-
- /*
- * Before trying to allocate any memory,
- * check if the entry already exists in the tree.
- * This avoids spurious resource errors.
- * The splay tree makes a subsequent lookup/insert
- * of the same name cheap, so this costs little.
- */
-
- if ((space->is_tree_total > 0) &&
- ((tentry = ipc_splay_tree_lookup(&space->is_tree, name))
- != ITE_NULL)) {
- assert(tentry->ite_space == space);
- assert(IE_BITS_TYPE(tentry->ite_bits));
+ slot = rdxtree_lookup_slot(&space->is_map, (rdxtree_key_t) name);
+ if (slot != NULL)
+ entry = *(ipc_entry_t *) slot;
- *entryp = &tentry->ite_entry;
- if (tree_entry) ite_free(tree_entry);
- return KERN_SUCCESS;
+ if (slot == NULL || entry == IE_NULL) {
+ entry = ie_alloc();
+ if (entry == IE_NULL) {
+ return KERN_RESOURCE_SHORTAGE;
}
- its = space->is_table_next;
-
- /*
- * Check if the table should be grown.
- *
- * Note that if space->is_table_size == its->its_size,
- * then we won't ever try to grow the table.
- *
- * Note that we are optimistically assuming that name
- * doesn't collide with any existing names. (So if
- * it were entered into the tree, is_tree_small would
- * be incremented.) This is OK, because even in that
- * case, we don't lose memory by growing the table.
- */
+ entry->ie_bits = 0;
+ entry->ie_object = IO_NULL;
+ entry->ie_request = 0;
+ entry->ie_name = name;
- if ((space->is_table_size <= index) &&
- (index < its->its_size) &&
- (((its->its_size - space->is_table_size) *
- sizeof(struct ipc_entry)) <
- ((space->is_tree_small + 1) *
- sizeof(struct ipc_tree_entry)))) {
- kern_return_t kr;
-
- /*
- * Can save space by growing the table.
- * Because the space will be unlocked,
- * we must restart.
- */
-
- kr = ipc_entry_grow_table(space);
- assert(kr != KERN_NO_SPACE);
+ if (slot != NULL)
+ rdxtree_replace_slot(slot, entry);
+ else {
+ kr = rdxtree_insert(&space->is_map,
+ (rdxtree_key_t) name, entry);
if (kr != KERN_SUCCESS) {
- /* space is unlocked */
- if (tree_entry) ite_free(tree_entry);
+ ie_free(entry);
return kr;
}
-
- continue;
- }
-
- /*
- * If a splay-tree entry was allocated previously,
- * go ahead and insert it into the tree.
- */
-
- if (tree_entry != ITE_NULL) {
- space->is_tree_total++;
-
- if (index < space->is_table_size)
- space->is_table[index].ie_bits |=
- IE_BITS_COLLISION;
- else if ((index < its->its_size) &&
- !ipc_entry_tree_collision(space, name))
- space->is_tree_small++;
-
- ipc_splay_tree_insert(&space->is_tree,
- name, tree_entry);
-
- tree_entry->ite_bits = 0;
- tree_entry->ite_object = IO_NULL;
- tree_entry->ite_request = 0;
- tree_entry->ite_space = space;
- *entryp = &tree_entry->ite_entry;
- return KERN_SUCCESS;
}
+ space->is_size += 1;
- /*
- * Allocate a tree entry and try again.
- */
-
- is_write_unlock(space);
- tree_entry = ite_alloc();
- if (tree_entry == ITE_NULL)
- return KERN_RESOURCE_SHORTAGE;
- is_write_lock(space);
+ *entryp = entry;
+ return KERN_SUCCESS;
}
-}
-
-/*
- * Routine: ipc_entry_dealloc
- * Purpose:
- * Deallocates an entry from a space.
- * Conditions:
- * The space must be write-locked throughout.
- * The space must be active.
- */
-
-void
-ipc_entry_dealloc(
- ipc_space_t space,
- mach_port_t name,
- ipc_entry_t entry)
-{
- ipc_entry_t table;
- ipc_entry_num_t size;
- mach_port_index_t index;
- assert(space->is_active);
- assert(entry->ie_object == IO_NULL);
- assert(entry->ie_request == 0);
-
- index = MACH_PORT_INDEX(name);
- table = space->is_table;
- size = space->is_table_size;
-
- if ((index < size) && (entry == &table[index])) {
- assert(IE_BITS_GEN(entry->ie_bits) == MACH_PORT_GEN(name));
-
- if (entry->ie_bits & IE_BITS_COLLISION) {
- struct ipc_splay_tree small, collisions;
- ipc_tree_entry_t tentry;
- mach_port_t tname;
- boolean_t pick;
- ipc_entry_bits_t bits;
- ipc_object_t obj;
-
- /* must move an entry from tree to table */
-
- ipc_splay_tree_split(&space->is_tree,
- MACH_PORT_MAKE(index+1, 0),
- &collisions);
- ipc_splay_tree_split(&collisions,
- MACH_PORT_MAKE(index, 0),
- &small);
-
- pick = ipc_splay_tree_pick(&collisions,
- &tname, &tentry);
- assert(pick);
- assert(MACH_PORT_INDEX(tname) == index);
-
- bits = tentry->ite_bits;
- entry->ie_bits = bits | MACH_PORT_GEN(tname);
- entry->ie_object = obj = tentry->ite_object;
- entry->ie_request = tentry->ite_request;
- assert(tentry->ite_space == space);
-
- if (IE_BITS_TYPE(bits) == MACH_PORT_TYPE_SEND) {
- ipc_hash_global_delete(space, obj,
- tname, tentry);
- ipc_hash_local_insert(space, obj,
- index, entry);
- }
-
- ipc_splay_tree_delete(&collisions, tname, tentry);
-
- assert(space->is_tree_total > 0);
- space->is_tree_total--;
-
- /* check if collision bit should still be on */
-
- pick = ipc_splay_tree_pick(&collisions,
- &tname, &tentry);
- if (pick) {
- entry->ie_bits |= IE_BITS_COLLISION;
- ipc_splay_tree_join(&space->is_tree,
- &collisions);
- }
-
- ipc_splay_tree_join(&space->is_tree, &small);
- } else {
- entry->ie_bits &= IE_BITS_GEN_MASK;
- entry->ie_next = table->ie_next;
- table->ie_next = index;
- }
- } else {
- ipc_tree_entry_t tentry = (ipc_tree_entry_t) entry;
-
- assert(tentry->ite_space == space);
-
- ipc_splay_tree_delete(&space->is_tree, name, tentry);
-
- assert(space->is_tree_total > 0);
- space->is_tree_total--;
-
- if (index < size) {
- ipc_entry_t ientry = &table[index];
-
- assert(ientry->ie_bits & IE_BITS_COLLISION);
-
- if (!ipc_entry_tree_collision(space, name))
- ientry->ie_bits &= ~IE_BITS_COLLISION;
- } else if ((index < space->is_table_next->its_size) &&
- !ipc_entry_tree_collision(space, name)) {
- assert(space->is_tree_small > 0);
- space->is_tree_small--;
- }
+ if (IE_BITS_TYPE(entry->ie_bits)) {
+ /* Used entry. */
+ *entryp = entry;
+ return KERN_SUCCESS;
}
-}
-/*
- * 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(space)
- ipc_space_t space;
-{
- 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.
- */
+ /* Free entry. Rip the entry out of the free list. */
+ for (prevp = &space->is_free_list, e = space->is_free_list;
+ e != entry;
+ ({ prevp = &e->ie_next_free; e = e->ie_next_free; }))
+ continue;
- 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;
+ *prevp = entry->ie_next_free;
+ space->is_free_list_size -= 1;
- /*
- * 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);
- 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));
-
- for (i = 0; i < osize; i++)
- table[i].ie_index = 0;
-
- (void) memset((void *) (table + osize), 0,
- (size - osize) * sizeof(struct ipc_entry));
-
- /*
- * Put old entries into the reverse hash table.
- */
-
- 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))));
+ entry->ie_bits = 0;
+ assert(entry->ie_object == IO_NULL);
+ assert(entry->ie_name == name);
+ entry->ie_request = 0;
+ space->is_size += 1;
+ *entryp = entry;
return KERN_SUCCESS;
}
-
#if MACH_KDB
#include <ddb/db_output.h>
#include <kern/task.h>
#define printf kdbprintf
-ipc_entry_t db_ipc_object_by_name(
- task_t task,
- mach_port_t name);
-
-
ipc_entry_t
db_ipc_object_by_name(
- task_t task,
+ const task_t task,
mach_port_t name)
{
ipc_space_t space = task->itk_space;
diff --git a/ipc/ipc_entry.h b/ipc/ipc_entry.h
index 6afa4f68..b429984b 100644
--- a/ipc/ipc_entry.h
+++ b/ipc/ipc_entry.h
@@ -48,47 +48,27 @@
/*
* Spaces hold capabilities for ipc_object_t's (ports and port sets).
- * Each ipc_entry_t records a capability. Most capabilities have
- * small names, and the entries are elements of a table.
- * Capabilities can have large names, and a splay tree holds
- * those entries. The cutoff point between the table and the tree
- * is adjusted dynamically to minimize memory consumption.
- *
- * The ie_index field of entries in the table implements
- * a ordered hash table with open addressing and linear probing.
- * This hash table converts (space, object) -> name.
- * It is used independently of the other fields.
- *
- * Free (unallocated) entries in the table have null ie_object
- * fields. The ie_bits field is zero except for IE_BITS_GEN.
- * The ie_next (ie_request) field links free entries into a free list.
- *
- * The first entry in the table (index 0) is always free.
- * It is used as the head of the free list.
+ * Each ipc_entry_t records a capability.
*/
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 {
- mach_port_index_t next;
+ struct ipc_entry *next_free;
/*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_next_free index.next_free
#define IE_BITS_UREFS_MASK 0x0000ffff /* 16 bits of user-reference */
#define IE_BITS_UREFS(bits) ((bits) & IE_BITS_UREFS_MASK)
@@ -98,12 +78,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 */
@@ -114,32 +92,9 @@ 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 ipc_entry_t
-ipc_entry_lookup(ipc_space_t space, mach_port_t name);
-
-extern kern_return_t
-ipc_entry_get(ipc_space_t space, mach_port_t *namep, ipc_entry_t *entryp);
+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))
extern kern_return_t
ipc_entry_alloc(ipc_space_t space, mach_port_t *namep, ipc_entry_t *entryp);
@@ -147,10 +102,9 @@ ipc_entry_alloc(ipc_space_t space, mach_port_t *namep, ipc_entry_t *entryp);
extern kern_return_t
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,
+ mach_port_t name);
#endif /* _IPC_IPC_ENTRY_H_ */
diff --git a/ipc/ipc_hash.c b/ipc/ipc_hash.c
deleted file mode 100644
index 5eec58cb..00000000
--- a/ipc/ipc_hash.c
+++ /dev/null
@@ -1,620 +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(space, obj, namep, entryp)
- 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) ||
- ((space->is_tree_hash > 0) &&
- ipc_hash_global_lookup(space, obj, namep,
- (ipc_tree_entry_t *) 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);
- if ((index < space->is_table_size) &&
- (entry == &space->is_table[index]))
- ipc_hash_local_insert(space, obj, index, entry);
- else
- ipc_hash_global_insert(space, obj, name,
- (ipc_tree_entry_t) 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);
- if ((index < space->is_table_size) &&
- (entry == &space->is_table[index]))
- ipc_hash_local_delete(space, obj, index, entry);
- else
- ipc_hash_global_delete(space, obj, name,
- (ipc_tree_entry_t) 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)
-{
- 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)
-{
- 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)
-{
- 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 hash table, which holds
- * entries from the space's table. In fact, the hash table
- * just uses a field (ie_index) in the table itself.
- *
- * The local hash table is an open-addressing hash table,
- * which means that when a collision occurs, instead of
- * throwing the entry into a bucket, the entry is rehashed
- * to another position in the table. In this case the rehash
- * is very simple: linear probing (ie, just increment the position).
- * This simple rehash makes deletions tractable (they're still a pain),
- * but it means that collisions tend to build up into clumps.
- *
- * Because at least one entry in the table (index 0) is always unused,
- * there will always be room in the reverse hash table. If a table
- * with n slots gets completely full, the reverse hash table will
- * have one giant clump of n-1 slots and one free slot somewhere.
- * Because entries are only entered into the reverse table if they
- * are pure send rights (not receive, send-once, port-set,
- * or dead-name rights), and free entries of course aren't entered,
- * I expect the reverse hash table won't get unreasonably full.
- *
- * Ordered hash tables (Amble & Knuth, Computer Journal, v. 17, no. 2,
- * pp. 135-142.) may be desirable here. They can dramatically help
- * unsuccessful lookups. But unsuccessful lookups are almost always
- * followed by insertions, and those slow down somewhat. They
- * also can help deletions somewhat. Successful lookups aren't affected.
- * So possibly a small win; probably nothing significant.
- */
-
-#define IH_LOCAL_HASH(obj, size) \
- ((((mach_port_index_t) (vm_offset_t) (obj)) >> 6) % (size))
-
-/*
- * 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)
-{
- ipc_entry_t table;
- ipc_entry_num_t size;
- mach_port_index_t hindex, index;
-
- assert(space != IS_NULL);
- assert(obj != IO_NULL);
-
- table = space->is_table;
- size = space->is_table_size;
- hindex = IH_LOCAL_HASH(obj, size);
-
- /*
- * Ideally, table[hindex].ie_index is the name we want.
- * However, must check ie_object to verify this,
- * because collisions can happen. In case of a collision,
- * search farther along in the clump.
- */
-
- while ((index = table[hindex].ie_index) != 0) {
- ipc_entry_t entry = &table[index];
-
- if (entry->ie_object == obj) {
- *namep = MACH_PORT_MAKEB(index, entry->ie_bits);
- *entryp = entry;
- return TRUE;
- }
-
- if (++hindex == size)
- hindex = 0;
- }
-
- 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)
-{
- ipc_entry_t table;
- ipc_entry_num_t size;
- mach_port_index_t hindex;
-
- assert(index != 0);
- assert(space != IS_NULL);
- assert(obj != IO_NULL);
-
- table = space->is_table;
- size = space->is_table_size;
- hindex = IH_LOCAL_HASH(obj, size);
-
- assert(entry == &table[index]);
- assert(entry->ie_object == obj);
-
- /*
- * We want to insert at hindex, but there may be collisions.
- * If a collision occurs, search for the end of the clump
- * and insert there.
- */
-
- while (table[hindex].ie_index != 0) {
- if (++hindex == size)
- hindex = 0;
- }
-
- table[hindex].ie_index = index;
-}
-
-/*
- * 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 table;
- ipc_entry_num_t size;
- mach_port_index_t hindex, dindex;
-
- assert(index != MACH_PORT_NULL);
- assert(space != IS_NULL);
- assert(obj != IO_NULL);
-
- table = space->is_table;
- size = space->is_table_size;
- hindex = IH_LOCAL_HASH(obj, size);
-
- assert(entry == &table[index]);
- assert(entry->ie_object == obj);
-
- /*
- * First check we have the right hindex for this index.
- * In case of collision, we have to search farther
- * along in this clump.
- */
-
- while (table[hindex].ie_index != index) {
- if (table[hindex].ie_index == 0)
- {
- static int gak = 0;
- if (gak == 0)
- {
- printf("gak! entry wasn't in hash table!\n");
- gak = 1;
- }
- return;
- }
- if (++hindex == size)
- hindex = 0;
- }
-
- /*
- * Now we want to set table[hindex].ie_index = 0.
- * But if we aren't the last index in a clump,
- * this might cause problems for lookups of objects
- * farther along in the clump that are displaced
- * due to collisions. Searches for them would fail
- * at hindex instead of succeeding.
- *
- * So we must check the clump after hindex for objects
- * that are so displaced, and move one up to the new hole.
- *
- * hindex - index of new hole in the clump
- * dindex - index we are checking for a displaced object
- *
- * When we move a displaced object up into the hole,
- * it creates a new hole, and we have to repeat the process
- * until we get to the end of the clump.
- */
-
- for (dindex = hindex; index != 0; hindex = dindex) {
- for (;;) {
- mach_port_index_t tindex;
- ipc_object_t tobj;
-
- if (++dindex == size)
- dindex = 0;
- assert(dindex != hindex);
-
- /* are we at the end of the clump? */
-
- index = table[dindex].ie_index;
- if (index == 0)
- break;
-
- /* is this a displaced object? */
-
- tobj = table[index].ie_object;
- assert(tobj != IO_NULL);
- tindex = IH_LOCAL_HASH(tobj, size);
-
- if ((dindex < hindex) ?
- ((dindex < tindex) && (tindex <= hindex)) :
- ((dindex < tindex) || (tindex <= hindex)))
- break;
- }
-
- table[hindex].ie_index = index;
- }
-}
-
-/*
- * 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 929ba77d..00000000
--- 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 ca7e7912..2c58a6e4 100644
--- a/ipc/ipc_init.c
+++ b/ipc/ipc_init.c
@@ -47,14 +47,13 @@
#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>
static struct vm_map ipc_kernel_map_store;
vm_map_t ipc_kernel_map = &ipc_kernel_map_store;
-vm_size_t ipc_kernel_map_size = 8 * 1024 * 1024;
+const vm_size_t ipc_kernel_map_size = 8 * 1024 * 1024;
/*
* Routine: ipc_bootstrap
@@ -76,8 +75,8 @@ 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);
kmem_cache_init(&ipc_object_caches[IOT_PORT], "ipc_port",
sizeof(struct ipc_port), 0, NULL, NULL, NULL, 0);
@@ -97,7 +96,6 @@ ipc_bootstrap(void)
ipc_table_init();
ipc_notify_init();
- ipc_hash_init();
ipc_marequest_init();
}
@@ -108,7 +106,7 @@ ipc_bootstrap(void)
*/
void
-ipc_init()
+ipc_init(void)
{
vm_offset_t min, max;
diff --git a/ipc/ipc_kmsg.c b/ipc/ipc_kmsg.c
index c2689a48..5076809e 100644
--- a/ipc/ipc_kmsg.c
+++ b/ipc/ipc_kmsg.c
@@ -50,7 +50,6 @@
#include <vm/vm_user.h>
#include <ipc/port.h>
#include <ipc/ipc_entry.h>
-#include <ipc/ipc_hash.h>
#include <ipc/ipc_kmsg.h>
#include <ipc/ipc_thread.h>
#include <ipc/ipc_marequest.h>
@@ -66,12 +65,9 @@
#if MACH_KDB
#include <ddb/db_output.h>
+#include <ipc/ipc_print.h>
#endif
-extern int copyinmap();
-extern int copyoutmap();
-void ipc_msg_print(); /* forward */
-
#define is_misaligned(x) ( ((vm_offset_t)(x)) & (sizeof(vm_offset_t)-1) )
#define ptr_align(x) \
( ( ((vm_offset_t)(x)) + (sizeof(vm_offset_t)-1) ) & ~(sizeof(vm_offset_t)-1) )
@@ -142,9 +138,7 @@ ipc_kmsg_rmqueue(
next->ikm_prev = prev;
prev->ikm_next = next;
}
- /* XXX Temporary debug logic */
- kmsg->ikm_next = IKM_BOGUS;
- kmsg->ikm_prev = IKM_BOGUS;
+ ikm_mark_bogus (kmsg);
}
/*
@@ -221,9 +215,9 @@ ipc_kmsg_destroy(
*/
void
-ipc_kmsg_clean_body(saddr, eaddr)
- vm_offset_t saddr;
- vm_offset_t eaddr;
+ipc_kmsg_clean_body(
+ vm_offset_t saddr,
+ vm_offset_t eaddr)
{
while (saddr < eaddr) {
mach_msg_type_long_t *type;
@@ -320,8 +314,7 @@ ipc_kmsg_clean_body(saddr, eaddr)
*/
void
-ipc_kmsg_clean(kmsg)
- ipc_kmsg_t kmsg;
+ipc_kmsg_clean(ipc_kmsg_t kmsg)
{
ipc_marequest_t marequest;
ipc_object_t object;
@@ -364,11 +357,11 @@ ipc_kmsg_clean(kmsg)
*/
void
-ipc_kmsg_clean_partial(kmsg, eaddr, dolast, number)
- ipc_kmsg_t kmsg;
- vm_offset_t eaddr;
- boolean_t dolast;
- mach_msg_type_number_t number;
+ipc_kmsg_clean_partial(
+ ipc_kmsg_t kmsg,
+ vm_offset_t eaddr,
+ boolean_t dolast,
+ mach_msg_type_number_t number)
{
ipc_object_t object;
mach_msg_bits_t mbits = kmsg->ikm_header.msgh_bits;
@@ -469,8 +462,7 @@ xxx: type = (mach_msg_type_long_t *) eaddr;
*/
void
-ipc_kmsg_free(kmsg)
- ipc_kmsg_t kmsg;
+ipc_kmsg_free(ipc_kmsg_t kmsg)
{
vm_size_t size = kmsg->ikm_size;
@@ -503,10 +495,10 @@ ipc_kmsg_free(kmsg)
*/
mach_msg_return_t
-ipc_kmsg_get(msg, size, kmsgp)
- mach_msg_header_t *msg;
- mach_msg_size_t size;
- ipc_kmsg_t *kmsgp;
+ipc_kmsg_get(
+ mach_msg_header_t *msg,
+ mach_msg_size_t size,
+ ipc_kmsg_t *kmsgp)
{
ipc_kmsg_t kmsg;
@@ -555,10 +547,10 @@ ipc_kmsg_get(msg, size, kmsgp)
*/
extern mach_msg_return_t
-ipc_kmsg_get_from_kernel(msg, size, kmsgp)
- mach_msg_header_t *msg;
- mach_msg_size_t size;
- ipc_kmsg_t *kmsgp;
+ipc_kmsg_get_from_kernel(
+ mach_msg_header_t *msg,
+ mach_msg_size_t size,
+ ipc_kmsg_t *kmsgp)
{
ipc_kmsg_t kmsg;
@@ -592,10 +584,10 @@ ipc_kmsg_get_from_kernel(msg, size, kmsgp)
*/
mach_msg_return_t
-ipc_kmsg_put(msg, kmsg, size)
- mach_msg_header_t *msg;
- ipc_kmsg_t kmsg;
- mach_msg_size_t size;
+ipc_kmsg_put(
+ mach_msg_header_t *msg,
+ ipc_kmsg_t kmsg,
+ mach_msg_size_t size)
{
mach_msg_return_t mr;
@@ -677,10 +669,10 @@ ipc_kmsg_put_to_kernel(
*/
mach_msg_return_t
-ipc_kmsg_copyin_header(msg, space, notify)
- mach_msg_header_t *msg;
- ipc_space_t space;
- mach_port_t notify;
+ipc_kmsg_copyin_header(
+ mach_msg_header_t *msg,
+ ipc_space_t space,
+ mach_port_t notify)
{
mach_msg_bits_t mbits = msg->msgh_bits &~ MACH_MSGH_BITS_CIRCULAR;
mach_port_t dest_name = msg->msgh_remote_port;
@@ -705,24 +697,14 @@ ipc_kmsg_copyin_header(msg, space, notify)
if (!space->is_active)
goto abort_async;
- /* optimized ipc_entry_lookup */
-
- {
- mach_port_index_t index = MACH_PORT_INDEX(dest_name);
- mach_port_gen_t gen = MACH_PORT_GEN(dest_name);
-
- if (index >= space->is_table_size)
+ entry = ipc_entry_lookup (space, dest_name);
+ if (entry == IE_NULL)
goto abort_async;
-
- entry = &space->is_table[index];
bits = entry->ie_bits;
- /* check generation number and type bit */
-
- if ((bits & (IE_BITS_GEN_MASK|MACH_PORT_TYPE_SEND)) !=
- (gen | MACH_PORT_TYPE_SEND))
+ /* check type bits */
+ if (IE_BITS_TYPE (bits) != MACH_PORT_TYPE_SEND)
goto abort_async;
- }
/* optimized ipc_right_copyin */
@@ -757,8 +739,6 @@ ipc_kmsg_copyin_header(msg, space, notify)
case MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND,
MACH_MSG_TYPE_MAKE_SEND_ONCE): {
- ipc_entry_num_t size;
- ipc_entry_t table;
ipc_entry_t entry;
ipc_entry_bits_t bits;
ipc_port_t dest_port, reply_port;
@@ -769,51 +749,28 @@ ipc_kmsg_copyin_header(msg, space, notify)
if (!space->is_active)
goto abort_request;
- size = space->is_table_size;
- table = space->is_table;
-
- /* optimized ipc_entry_lookup of dest_name */
-
- {
- mach_port_index_t index = MACH_PORT_INDEX(dest_name);
- mach_port_gen_t gen = MACH_PORT_GEN(dest_name);
-
- if (index >= size)
+ entry = ipc_entry_lookup (space, dest_name);
+ if (entry == IE_NULL)
goto abort_request;
-
- entry = &table[index];
bits = entry->ie_bits;
- /* check generation number and type bit */
-
- if ((bits & (IE_BITS_GEN_MASK|MACH_PORT_TYPE_SEND)) !=
- (gen | MACH_PORT_TYPE_SEND))
+ /* check type bits */
+ if (IE_BITS_TYPE (bits) != MACH_PORT_TYPE_SEND)
goto abort_request;
- }
assert(IE_BITS_UREFS(bits) > 0);
dest_port = (ipc_port_t) entry->ie_object;
assert(dest_port != IP_NULL);
- /* optimized ipc_entry_lookup of reply_name */
-
- {
- mach_port_index_t index = MACH_PORT_INDEX(reply_name);
- mach_port_gen_t gen = MACH_PORT_GEN(reply_name);
-
- if (index >= size)
+ entry = ipc_entry_lookup (space, reply_name);
+ if (entry == IE_NULL)
goto abort_request;
-
- entry = &table[index];
bits = entry->ie_bits;
- /* check generation number and type bit */
-
- if ((bits & (IE_BITS_GEN_MASK|MACH_PORT_TYPE_RECEIVE)) !=
- (gen | MACH_PORT_TYPE_RECEIVE))
+ /* check type bits */
+ if (IE_BITS_TYPE (bits) != MACH_PORT_TYPE_RECEIVE)
goto abort_request;
- }
reply_port = (ipc_port_t) entry->ie_object;
assert(reply_port != IP_NULL);
@@ -860,9 +817,6 @@ ipc_kmsg_copyin_header(msg, space, notify)
}
case MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE, 0): {
- mach_port_index_t index;
- mach_port_gen_t gen;
- ipc_entry_t table;
ipc_entry_t entry;
ipc_entry_bits_t bits;
ipc_port_t dest_port;
@@ -876,24 +830,13 @@ ipc_kmsg_copyin_header(msg, space, notify)
if (!space->is_active)
goto abort_reply;
- /* optimized ipc_entry_lookup */
-
- table = space->is_table;
-
- index = MACH_PORT_INDEX(dest_name);
- gen = MACH_PORT_GEN(dest_name);
-
- if (index >= space->is_table_size)
+ entry = ipc_entry_lookup (space, dest_name);
+ if (entry == IE_NULL)
goto abort_reply;
-
- entry = &table[index];
bits = entry->ie_bits;
- /* check generation number, collision bit, and type bit */
-
- if ((bits & (IE_BITS_GEN_MASK|IE_BITS_COLLISION|
- MACH_PORT_TYPE_SEND_ONCE)) !=
- (gen | MACH_PORT_TYPE_SEND_ONCE))
+ /* check and type bits */
+ if (IE_BITS_TYPE (bits) != MACH_PORT_TYPE_SEND_ONCE)
goto abort_reply;
/* optimized ipc_right_copyin */
@@ -917,12 +860,8 @@ ipc_kmsg_copyin_header(msg, space, notify)
assert(dest_port->ip_sorights > 0);
ip_unlock(dest_port);
- /* optimized ipc_entry_dealloc */
-
- entry->ie_next = table->ie_next;
- table->ie_next = index;
- entry->ie_bits = gen;
entry->ie_object = IO_NULL;
+ ipc_entry_dealloc (space, dest_name, entry);
is_write_unlock(space);
msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
@@ -1342,10 +1281,10 @@ ipc_kmsg_copyin_header(msg, space, notify)
}
mach_msg_return_t
-ipc_kmsg_copyin_body(kmsg, space, map)
- ipc_kmsg_t kmsg;
- ipc_space_t space;
- vm_map_t map;
+ipc_kmsg_copyin_body(
+ ipc_kmsg_t kmsg,
+ ipc_space_t space,
+ vm_map_t map)
{
ipc_object_t dest;
vm_offset_t saddr, eaddr;
@@ -1562,11 +1501,11 @@ ipc_kmsg_copyin_body(kmsg, space, map)
*/
mach_msg_return_t
-ipc_kmsg_copyin(kmsg, space, map, notify)
- ipc_kmsg_t kmsg;
- ipc_space_t space;
- vm_map_t map;
- mach_port_t notify;
+ipc_kmsg_copyin(
+ ipc_kmsg_t kmsg,
+ ipc_space_t space,
+ vm_map_t map,
+ mach_port_t notify)
{
mach_msg_return_t mr;
@@ -1597,8 +1536,7 @@ ipc_kmsg_copyin(kmsg, space, map, notify)
*/
void
-ipc_kmsg_copyin_from_kernel(
- ipc_kmsg_t kmsg)
+ipc_kmsg_copyin_from_kernel(ipc_kmsg_t kmsg)
{
mach_msg_bits_t bits = kmsg->ikm_header.msgh_bits;
mach_msg_type_name_t rname = MACH_MSGH_BITS_REMOTE(bits);
@@ -1757,10 +1695,10 @@ ipc_kmsg_copyin_from_kernel(
*/
mach_msg_return_t
-ipc_kmsg_copyout_header(msg, space, notify)
- mach_msg_header_t *msg;
- ipc_space_t space;
- mach_port_t notify;
+ipc_kmsg_copyout_header(
+ mach_msg_header_t *msg,
+ ipc_space_t space,
+ mach_port_t notify)
{
mach_msg_bits_t mbits = msg->msgh_bits;
ipc_port_t dest = (ipc_port_t) msg->msgh_remote_port;
@@ -1774,6 +1712,7 @@ ipc_kmsg_copyout_header(msg, space, notify)
case MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND, 0): {
mach_port_t dest_name;
ipc_port_t nsrequest;
+ unsigned long payload;
/* receiving an asynchronous message */
@@ -1792,6 +1731,7 @@ ipc_kmsg_copyout_header(msg, space, notify)
dest_name = dest->ip_receiver_name;
else
dest_name = MACH_PORT_NULL;
+ payload = dest->ip_protected_payload;
if ((--dest->ip_srights == 0) &&
((nsrequest = dest->ip_nsrequest) != IP_NULL)) {
@@ -1805,21 +1745,27 @@ ipc_kmsg_copyout_header(msg, space, notify)
} else
ip_unlock(dest);
- msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
- MACH_MSGH_BITS(0, MACH_MSG_TYPE_PORT_SEND));
- msg->msgh_local_port = dest_name;
+ if (! ipc_port_flag_protected_payload(dest)) {
+ msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
+ MACH_MSGH_BITS(0, MACH_MSG_TYPE_PORT_SEND));
+ msg->msgh_local_port = dest_name;
+ } else {
+ msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
+ MACH_MSGH_BITS(
+ 0, MACH_MSG_TYPE_PROTECTED_PAYLOAD));
+ msg->msgh_protected_payload = payload;
+ }
msg->msgh_remote_port = MACH_PORT_NULL;
return MACH_MSG_SUCCESS;
}
case MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND,
MACH_MSG_TYPE_PORT_SEND_ONCE): {
- ipc_entry_t table;
- mach_port_index_t index;
ipc_entry_t entry;
ipc_port_t reply = (ipc_port_t) msg->msgh_local_port;
mach_port_t dest_name, reply_name;
ipc_port_t nsrequest;
+ unsigned long payload;
/* receiving a request message */
@@ -1827,8 +1773,7 @@ ipc_kmsg_copyout_header(msg, space, notify)
break;
is_write_lock(space);
- if (!space->is_active ||
- ((index = (table = space->is_table)->ie_next) == 0)) {
+ if (!space->is_active || space->is_free_list == NULL) {
is_write_unlock(space);
break;
}
@@ -1858,11 +1803,14 @@ ipc_kmsg_copyout_header(msg, space, notify)
assert(reply->ip_sorights > 0);
ip_unlock(reply);
- /* optimized ipc_entry_get */
-
- entry = &table[index];
- table->ie_next = entry->ie_next;
- entry->ie_request = 0;
+ kern_return_t kr;
+ kr = ipc_entry_get (space, &reply_name, &entry);
+ if (kr) {
+ ip_unlock(reply);
+ ip_unlock(dest);
+ is_write_unlock(space);
+ break;
+ }
{
mach_port_gen_t gen;
@@ -1870,8 +1818,6 @@ ipc_kmsg_copyout_header(msg, space, notify)
assert((entry->ie_bits &~ IE_BITS_GEN_MASK) == 0);
gen = entry->ie_bits + IE_BITS_GEN_ONE;
- reply_name = MACH_PORT_MAKE(index, gen);
-
/* optimized ipc_right_copyout */
entry->ie_bits = gen | (MACH_PORT_TYPE_SEND_ONCE | 1);
@@ -1890,6 +1836,7 @@ ipc_kmsg_copyout_header(msg, space, notify)
dest_name = dest->ip_receiver_name;
else
dest_name = MACH_PORT_NULL;
+ payload = dest->ip_protected_payload;
if ((--dest->ip_srights == 0) &&
((nsrequest = dest->ip_nsrequest) != IP_NULL)) {
@@ -1903,16 +1850,24 @@ ipc_kmsg_copyout_header(msg, space, notify)
} else
ip_unlock(dest);
- msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
- MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE,
- MACH_MSG_TYPE_PORT_SEND));
- msg->msgh_local_port = dest_name;
+ if (! ipc_port_flag_protected_payload(dest)) {
+ msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
+ MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE,
+ MACH_MSG_TYPE_PORT_SEND));
+ msg->msgh_local_port = dest_name;
+ } else {
+ msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
+ MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE,
+ MACH_MSG_TYPE_PROTECTED_PAYLOAD));
+ msg->msgh_protected_payload = payload;
+ }
msg->msgh_remote_port = reply_name;
return MACH_MSG_SUCCESS;
}
case MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, 0): {
mach_port_t dest_name;
+ unsigned long payload;
/* receiving a reply message */
@@ -1926,6 +1881,8 @@ ipc_kmsg_copyout_header(msg, space, notify)
assert(dest->ip_sorights > 0);
+ payload = dest->ip_protected_payload;
+
if (dest->ip_receiver == space) {
ip_release(dest);
dest->ip_sorights--;
@@ -1938,9 +1895,17 @@ ipc_kmsg_copyout_header(msg, space, notify)
dest_name = MACH_PORT_NULL;
}
- msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
- MACH_MSGH_BITS(0, MACH_MSG_TYPE_PORT_SEND_ONCE));
- msg->msgh_local_port = dest_name;
+ if (! ipc_port_flag_protected_payload(dest)) {
+ msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
+ MACH_MSGH_BITS(0,
+ MACH_MSG_TYPE_PORT_SEND_ONCE));
+ msg->msgh_local_port = dest_name;
+ } else {
+ msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
+ MACH_MSGH_BITS(0,
+ MACH_MSG_TYPE_PROTECTED_PAYLOAD));
+ msg->msgh_protected_payload = payload;
+ }
msg->msgh_remote_port = MACH_PORT_NULL;
return MACH_MSG_SUCCESS;
}
@@ -1956,6 +1921,7 @@ ipc_kmsg_copyout_header(msg, space, notify)
mach_msg_type_name_t reply_type = MACH_MSGH_BITS_LOCAL(mbits);
ipc_port_t reply = (ipc_port_t) msg->msgh_local_port;
mach_port_t dest_name, reply_name;
+ unsigned long payload;
if (IP_VALID(reply)) {
ipc_port_t notify_port;
@@ -2036,28 +2002,20 @@ ipc_kmsg_copyout_header(msg, space, notify)
goto copyout_dest;
}
- kr = ipc_entry_get(space, &reply_name, &entry);
+ kr = ipc_entry_alloc(space, &reply_name, &entry);
if (kr != KERN_SUCCESS) {
ip_unlock(reply);
if (notify_port != IP_NULL)
ipc_port_release_sonce(notify_port);
- /* space is locked */
- kr = ipc_entry_grow_table(space);
- if (kr != KERN_SUCCESS) {
- /* space is unlocked */
-
- if (kr == KERN_RESOURCE_SHORTAGE)
- return (MACH_RCV_HEADER_ERROR|
- MACH_MSG_IPC_KERNEL);
- else
- return (MACH_RCV_HEADER_ERROR|
- MACH_MSG_IPC_SPACE);
- }
- /* space is locked again; start over */
-
- continue;
+ is_write_unlock(space);
+ if (kr == KERN_RESOURCE_SHORTAGE)
+ return (MACH_RCV_HEADER_ERROR|
+ MACH_MSG_IPC_KERNEL);
+ else
+ return (MACH_RCV_HEADER_ERROR|
+ MACH_MSG_IPC_SPACE);
}
assert(IE_BITS_TYPE(entry->ie_bits)
@@ -2202,6 +2160,7 @@ ipc_kmsg_copyout_header(msg, space, notify)
*/
copyout_dest:
+ payload = dest->ip_protected_payload;
if (ip_active(dest)) {
ipc_object_copyout_dest(space, (ipc_object_t) dest,
@@ -2230,9 +2189,17 @@ ipc_kmsg_copyout_header(msg, space, notify)
if (IP_VALID(reply))
ipc_port_release(reply);
- msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
- MACH_MSGH_BITS(reply_type, dest_type));
- msg->msgh_local_port = dest_name;
+ if (! ipc_port_flag_protected_payload(dest)) {
+ msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
+ MACH_MSGH_BITS(reply_type, dest_type));
+ msg->msgh_local_port = dest_name;
+ } else {
+ msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
+ MACH_MSGH_BITS(reply_type,
+ MACH_MSG_TYPE_PROTECTED_PAYLOAD));
+ msg->msgh_protected_payload = payload;
+ }
+
msg->msgh_remote_port = reply_name;
}
@@ -2257,11 +2224,11 @@ ipc_kmsg_copyout_header(msg, space, notify)
*/
mach_msg_return_t
-ipc_kmsg_copyout_object(space, object, msgt_name, namep)
- ipc_space_t space;
- ipc_object_t object;
- mach_msg_type_name_t msgt_name;
- mach_port_t *namep;
+ipc_kmsg_copyout_object(
+ ipc_space_t space,
+ ipc_object_t object,
+ mach_msg_type_name_t msgt_name,
+ mach_port_t *namep)
{
if (!IO_VALID(object)) {
*namep = (mach_port_t) object;
@@ -2279,7 +2246,7 @@ ipc_kmsg_copyout_object(space, object, msgt_name, namep)
goto slow_copyout;
{
- register ipc_port_t port = (ipc_port_t) object;
+ ipc_port_t port = (ipc_port_t) object;
ipc_entry_t entry;
is_write_lock(space);
@@ -2290,12 +2257,13 @@ ipc_kmsg_copyout_object(space, object, msgt_name, namep)
ip_lock(port);
if (!ip_active(port) ||
- !ipc_hash_local_lookup(space, (ipc_object_t) port,
- namep, &entry)) {
+ (entry = ipc_reverse_lookup(space,
+ (ipc_object_t) port)) == NULL) {
ip_unlock(port);
is_write_unlock(space);
goto slow_copyout;
}
+ *namep = entry->ie_name;
/*
* Copyout the send right, incrementing urefs
@@ -2312,7 +2280,7 @@ ipc_kmsg_copyout_object(space, object, msgt_name, namep)
assert(IE_BITS_UREFS(entry->ie_bits) < MACH_PORT_UREFS_MAX);
{
- register ipc_entry_bits_t bits = entry->ie_bits + 1;
+ ipc_entry_bits_t bits = entry->ie_bits + 1;
if (IE_BITS_UREFS(bits) < MACH_PORT_UREFS_MAX)
entry->ie_bits = bits;
@@ -2367,10 +2335,11 @@ ipc_kmsg_copyout_object(space, object, msgt_name, namep)
*/
mach_msg_return_t
-ipc_kmsg_copyout_body(saddr, eaddr, space, map)
- vm_offset_t saddr, eaddr;
- ipc_space_t space;
- vm_map_t map;
+ipc_kmsg_copyout_body(
+ vm_offset_t saddr,
+ vm_offset_t eaddr,
+ ipc_space_t space,
+ vm_map_t map)
{
mach_msg_return_t mr = MACH_MSG_SUCCESS;
kern_return_t kr;
@@ -2519,11 +2488,11 @@ ipc_kmsg_copyout_body(saddr, eaddr, space, map)
*/
mach_msg_return_t
-ipc_kmsg_copyout(kmsg, space, map, notify)
- ipc_kmsg_t kmsg;
- ipc_space_t space;
- vm_map_t map;
- mach_port_t notify;
+ipc_kmsg_copyout(
+ ipc_kmsg_t kmsg,
+ ipc_space_t space,
+ vm_map_t map,
+ mach_port_t notify)
{
mach_msg_bits_t mbits = kmsg->ikm_header.msgh_bits;
mach_msg_return_t mr;
@@ -2613,9 +2582,9 @@ ipc_kmsg_copyout_pseudo(
*/
void
-ipc_kmsg_copyout_dest(kmsg, space)
- ipc_kmsg_t kmsg;
- ipc_space_t space;
+ipc_kmsg_copyout_dest(
+ ipc_kmsg_t kmsg,
+ ipc_space_t space)
{
mach_msg_bits_t mbits = kmsg->ikm_header.msgh_bits;
ipc_object_t dest = (ipc_object_t) kmsg->ikm_header.msgh_remote_port;
@@ -2661,9 +2630,9 @@ ipc_kmsg_copyout_dest(kmsg, space)
#if MACH_KDB
char *
-ipc_type_name(type_name, received)
- int type_name;
- boolean_t received;
+ipc_type_name(
+ int type_name,
+ boolean_t received)
{
switch (type_name) {
case MACH_MSG_TYPE_BOOLEAN:
@@ -2744,8 +2713,7 @@ ipc_print_type_name(
* ipc_kmsg_print [ debug ]
*/
void
-ipc_kmsg_print(kmsg)
- ipc_kmsg_t kmsg;
+ipc_kmsg_print(ipc_kmsg_t kmsg)
{
db_printf("kmsg=0x%x\n", kmsg);
db_printf("ikm_next=0x%x,prev=0x%x,size=%d,marequest=0x%x",
@@ -2761,8 +2729,7 @@ ipc_kmsg_print(kmsg)
* ipc_msg_print [ debug ]
*/
void
-ipc_msg_print(msgh)
- mach_msg_header_t *msgh;
+ipc_msg_print(mach_msg_header_t *msgh)
{
vm_offset_t saddr, eaddr;
diff --git a/ipc/ipc_kmsg.h b/ipc/ipc_kmsg.h
index 8867310d..393c0392 100644
--- a/ipc/ipc_kmsg.h
+++ b/ipc/ipc_kmsg.h
@@ -38,7 +38,7 @@
#include <mach/message.h>
#include <kern/assert.h>
#include <kern/cpu_number.h>
-#include <kern/macro_help.h>
+#include <kern/macros.h>
#include <kern/kalloc.h>
#include <ipc/ipc_marequest.h>
#include <ipc/ipc_object.h>
@@ -72,11 +72,24 @@ typedef struct ipc_kmsg {
#define ikm_plus_overhead(size) ((vm_size_t)((size) + IKM_OVERHEAD))
#define ikm_less_overhead(size) ((mach_msg_size_t)((size) - IKM_OVERHEAD))
+#if MACH_IPC_TEST
/*
- * XXX For debugging.
+ * For debugging.
*/
#define IKM_BOGUS ((ipc_kmsg_t) 0xffffff10)
+#define ikm_mark_bogus(kmsg) \
+MACRO_BEGIN \
+ (kmsg)->ikm_next = IKM_BOGUS; \
+ (kmsg)->ikm_prev = IKM_BOGUS; \
+MACRO_END
+
+#else /* MACH_IPC_TEST */
+
+#define ikm_mark_bogus(kmsg) ;
+
+#endif /* MACH_IPC_TEST */
+
/*
* We keep a per-processor cache of kernel message buffers.
* The cache saves the overhead/locking of using kalloc/kfree.
@@ -92,9 +105,12 @@ extern ipc_kmsg_t ipc_kmsg_cache[NCPUS];
/*
* The size of the kernel message buffers that will be cached.
* IKM_SAVED_KMSG_SIZE includes overhead; IKM_SAVED_MSG_SIZE doesn't.
+ *
+ * We use the page size for IKM_SAVED_KMSG_SIZE to make sure the
+ * page is pinned to a single processor.
*/
-#define IKM_SAVED_KMSG_SIZE ((vm_size_t) 256)
+#define IKM_SAVED_KMSG_SIZE PAGE_SIZE
#define IKM_SAVED_MSG_SIZE ikm_less_overhead(IKM_SAVED_KMSG_SIZE)
#define ikm_alloc(size) \
@@ -140,8 +156,7 @@ MACRO_BEGIN \
MACRO_END
/*
- * struct ipc_kmsg_queue is defined in kern/thread.h instead of here,
- * so that kern/thread.h doesn't have to include ipc/ipc_kmsg.h.
+ * struct ipc_kmsg_queue is defined in ipc/ipc_kmsg_queue.h
*/
#include <ipc/ipc_kmsg_queue.h>
@@ -196,9 +211,7 @@ MACRO_BEGIN \
_next->ikm_prev = _prev; \
_prev->ikm_next = _next; \
} \
- /* XXX Debug paranoia */ \
- kmsg->ikm_next = IKM_BOGUS; \
- kmsg->ikm_prev = IKM_BOGUS; \
+ ikm_mark_bogus (kmsg); \
MACRO_END
#define ipc_kmsg_enqueue_macro(queue, kmsg) \
diff --git a/ipc/ipc_kmsg_queue.h b/ipc/ipc_kmsg_queue.h
index 51ccbe24..b4b3df1d 100644
--- a/ipc/ipc_kmsg_queue.h
+++ b/ipc/ipc_kmsg_queue.h
@@ -27,5 +27,5 @@
#define _IPC_KMSG_QUEUE_H_
struct ipc_kmsg_queue {
struct ipc_kmsg *ikmq_base; };
-#endif
+#endif /* _IPC_KMSG_QUEUE_H_ */
diff --git a/ipc/ipc_machdep.h b/ipc/ipc_machdep.h
index e864c4b0..c205ba45 100755
--- a/ipc/ipc_machdep.h
+++ b/ipc/ipc_machdep.h
@@ -24,6 +24,9 @@
* the rights to redistribute these changes.
*/
+#ifndef _IPC_IPC_MACHDEP_H_
+#define _IPC_IPC_MACHDEP_H_
+
/*
* At times, we need to know the size of a port in bits
*/
@@ -38,3 +41,4 @@
#define PORT_T_SIZE_IN_BITS 32
#endif
+#endif /* _IPC_IPC_MACHDEP_H_ */
diff --git a/ipc/ipc_marequest.c b/ipc/ipc_marequest.c
index 06c53eb4..ded1711d 100644
--- a/ipc/ipc_marequest.c
+++ b/ipc/ipc_marequest.c
@@ -160,11 +160,11 @@ ipc_marequest_init(void)
*/
mach_msg_return_t
-ipc_marequest_create(space, port, notify, marequestp)
- ipc_space_t space;
- ipc_port_t port;
- mach_port_t notify;
- ipc_marequest_t *marequestp;
+ipc_marequest_create(
+ ipc_space_t space,
+ ipc_port_t port,
+ mach_port_t notify,
+ ipc_marequest_t *marequestp)
{
mach_port_t name;
ipc_entry_t entry;
@@ -256,9 +256,9 @@ ipc_marequest_create(space, port, notify, marequestp)
*/
void
-ipc_marequest_cancel(space, name)
- ipc_space_t space;
- mach_port_t name;
+ipc_marequest_cancel(
+ ipc_space_t space,
+ mach_port_t name)
{
ipc_marequest_bucket_t bucket;
ipc_marequest_t marequest, *last;
@@ -292,9 +292,10 @@ ipc_marequest_cancel(space, name)
*/
void
-ipc_marequest_rename(space, old, new)
- ipc_space_t space;
- mach_port_t old, new;
+ipc_marequest_rename(
+ ipc_space_t space,
+ mach_port_t old,
+ mach_port_t new)
{
ipc_marequest_bucket_t bucket;
ipc_marequest_t marequest, *last;
@@ -336,8 +337,7 @@ ipc_marequest_rename(space, old, new)
*/
void
-ipc_marequest_destroy(marequest)
- ipc_marequest_t marequest;
+ipc_marequest_destroy(ipc_marequest_t marequest)
{
ipc_space_t space = marequest->imar_space;
mach_port_t name;
@@ -404,10 +404,10 @@ ipc_marequest_destroy(marequest)
*/
unsigned int
-ipc_marequest_info(maxp, info, count)
- unsigned int *maxp;
- hash_info_bucket_t *info;
- unsigned int count;
+ipc_marequest_info(
+ unsigned int *maxp,
+ hash_info_bucket_t *info,
+ unsigned int count)
{
ipc_marequest_index_t i;
diff --git a/ipc/ipc_mqueue.c b/ipc/ipc_mqueue.c
index 80a34d3a..9138aec4 100644
--- a/ipc/ipc_mqueue.c
+++ b/ipc/ipc_mqueue.c
@@ -79,9 +79,9 @@ ipc_mqueue_init(
void
ipc_mqueue_move(
- ipc_mqueue_t dest,
- ipc_mqueue_t source,
- ipc_port_t port)
+ ipc_mqueue_t dest,
+ ipc_mqueue_t source,
+ const ipc_port_t port)
{
ipc_kmsg_queue_t oldq, newq;
ipc_thread_queue_t blockedq;
@@ -171,10 +171,10 @@ ipc_mqueue_changed(
*/
mach_msg_return_t
-ipc_mqueue_send(kmsg, option, time_out)
- ipc_kmsg_t kmsg;
- mach_msg_option_t option;
- mach_msg_timeout_t time_out;
+ipc_mqueue_send(
+ ipc_kmsg_t kmsg,
+ mach_msg_option_t option,
+ mach_msg_timeout_t time_out)
{
ipc_port_t port;
diff --git a/ipc/ipc_mqueue.h b/ipc/ipc_mqueue.h
index ef0f9425..2af5e02e 100644
--- a/ipc/ipc_mqueue.h
+++ b/ipc/ipc_mqueue.h
@@ -37,7 +37,8 @@
#include <mach/message.h>
#include <kern/assert.h>
#include <kern/lock.h>
-#include <kern/macro_help.h>
+#include <kern/macros.h>
+#include <ipc/ipc_kmsg_queue.h>
#include <ipc/ipc_kmsg.h>
#include <ipc/ipc_thread.h>
diff --git a/ipc/ipc_notify.c b/ipc/ipc_notify.c
index 25fa421b..df5f68bc 100644
--- a/ipc/ipc_notify.c
+++ b/ipc/ipc_notify.c
@@ -59,8 +59,7 @@ mach_dead_name_notification_t ipc_notify_dead_name_template;
*/
void
-ipc_notify_init_port_deleted(n)
- mach_port_deleted_notification_t *n;
+ipc_notify_init_port_deleted(mach_port_deleted_notification_t *n)
{
mach_msg_header_t *m = &n->not_header;
mach_msg_type_t *t = &n->not_type;
@@ -90,8 +89,7 @@ ipc_notify_init_port_deleted(n)
*/
void
-ipc_notify_init_msg_accepted(n)
- mach_msg_accepted_notification_t *n;
+ipc_notify_init_msg_accepted(mach_msg_accepted_notification_t *n)
{
mach_msg_header_t *m = &n->not_header;
mach_msg_type_t *t = &n->not_type;
@@ -121,8 +119,7 @@ ipc_notify_init_msg_accepted(n)
*/
void
-ipc_notify_init_port_destroyed(
- mach_port_destroyed_notification_t *n)
+ipc_notify_init_port_destroyed(mach_port_destroyed_notification_t *n)
{
mach_msg_header_t *m = &n->not_header;
mach_msg_type_t *t = &n->not_type;
@@ -255,9 +252,9 @@ ipc_notify_init(void)
*/
void
-ipc_notify_port_deleted(port, name)
- ipc_port_t port;
- mach_port_t name;
+ipc_notify_port_deleted(
+ ipc_port_t port,
+ mach_port_t name)
{
ipc_kmsg_t kmsg;
mach_port_deleted_notification_t *n;
@@ -289,9 +286,9 @@ ipc_notify_port_deleted(port, name)
*/
void
-ipc_notify_msg_accepted(port, name)
- ipc_port_t port;
- mach_port_t name;
+ipc_notify_msg_accepted(
+ ipc_port_t port,
+ mach_port_t name)
{
ipc_kmsg_t kmsg;
mach_msg_accepted_notification_t *n;
@@ -326,9 +323,9 @@ ipc_notify_msg_accepted(port, name)
*/
void
-ipc_notify_port_destroyed(port, right)
- ipc_port_t port;
- ipc_port_t right;
+ipc_notify_port_destroyed(
+ ipc_port_t port,
+ ipc_port_t right)
{
ipc_kmsg_t kmsg;
mach_port_destroyed_notification_t *n;
@@ -362,9 +359,9 @@ ipc_notify_port_destroyed(port, right)
*/
void
-ipc_notify_no_senders(port, mscount)
- ipc_port_t port;
- mach_port_mscount_t mscount;
+ipc_notify_no_senders(
+ ipc_port_t port,
+ mach_port_mscount_t mscount)
{
ipc_kmsg_t kmsg;
mach_no_senders_notification_t *n;
@@ -396,8 +393,7 @@ ipc_notify_no_senders(port, mscount)
*/
void
-ipc_notify_send_once(port)
- ipc_port_t port;
+ipc_notify_send_once(ipc_port_t port)
{
ipc_kmsg_t kmsg;
mach_send_once_notification_t *n;
@@ -428,9 +424,9 @@ ipc_notify_send_once(port)
*/
void
-ipc_notify_dead_name(port, name)
- ipc_port_t port;
- mach_port_t name;
+ipc_notify_dead_name(
+ ipc_port_t port,
+ mach_port_t name)
{
ipc_kmsg_t kmsg;
mach_dead_name_notification_t *n;
diff --git a/ipc/ipc_object.c b/ipc/ipc_object.c
index b8cae8f5..320fbcb2 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>
@@ -156,11 +155,12 @@ ipc_object_alloc_dead(
ipc_entry_t entry;
kern_return_t kr;
-
+ is_write_lock(space);
kr = ipc_entry_alloc(space, namep, &entry);
- if (kr != KERN_SUCCESS)
+ if (kr != KERN_SUCCESS) {
+ is_write_unlock(space);
return kr;
- /* space is write-locked */
+ }
/* null object, MACH_PORT_TYPE_DEAD_NAME, 1 uref */
@@ -192,11 +192,12 @@ ipc_object_alloc_dead_name(
ipc_entry_t entry;
kern_return_t kr;
-
+ is_write_lock(space);
kr = ipc_entry_alloc_name(space, name, &entry);
- if (kr != KERN_SUCCESS)
+ if (kr != KERN_SUCCESS) {
+ is_write_unlock(space);
return kr;
- /* space is write-locked */
+ }
if (ipc_right_inuse(space, name, entry))
return KERN_NAME_EXISTS;
@@ -255,12 +256,13 @@ ipc_object_alloc(
memset(pset, 0, sizeof(*pset));
}
+ is_write_lock(space);
kr = ipc_entry_alloc(space, namep, &entry);
if (kr != KERN_SUCCESS) {
+ is_write_unlock(space);
io_free(otype, object);
return kr;
}
- /* space is write-locked */
entry->ie_bits |= type | urefs;
entry->ie_object = object;
@@ -322,12 +324,13 @@ ipc_object_alloc_name(
memset(pset, 0, sizeof(*pset));
}
+ is_write_lock(space);
kr = ipc_entry_alloc_name(space, name, &entry);
if (kr != KERN_SUCCESS) {
+ is_write_unlock(space);
io_free(otype, object);
return kr;
}
- /* space is write-locked */
if (ipc_right_inuse(space, name, entry)) {
io_free(otype, object);
@@ -481,6 +484,7 @@ ipc_object_copyin_from_kernel(
port->ip_receiver_name = MACH_PORT_NULL;
port->ip_destination = IP_NULL;
+ ipc_port_flag_protected_payload_clear(port);
ip_unlock(port);
break;
}
@@ -629,15 +633,10 @@ ipc_object_copyout(
break;
}
- kr = ipc_entry_get(space, &name, &entry);
+ kr = ipc_entry_alloc(space, &name, &entry);
if (kr != KERN_SUCCESS) {
- /* unlocks/locks space, so must start again */
-
- kr = ipc_entry_grow_table(space);
- if (kr != KERN_SUCCESS)
- return kr; /* space is unlocked */
-
- continue;
+ is_write_unlock(space);
+ return kr;
}
assert(IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE);
@@ -690,15 +689,10 @@ ipc_object_copyout_multiname(space, object, namep)
return KERN_INVALID_TASK;
}
- kr = ipc_entry_get(space, &name, &entry);
+ kr = ipc_entry_alloc(space, &name, &entry);
if (kr != KERN_SUCCESS) {
- /* unlocks/locks space, so must start again */
-
- kr = ipc_entry_grow_table(space);
- if (kr != KERN_SUCCESS)
- return kr; /* space is unlocked */
-
- continue;
+ is_write_unlock(space);
+ return kr; /* space is unlocked */
}
assert(IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE);
@@ -763,10 +757,12 @@ ipc_object_copyout_name(
assert(IO_VALID(object));
assert(io_otype(object) == IOT_PORT);
+ is_write_lock(space);
kr = ipc_entry_alloc_name(space, name, &entry);
- if (kr != KERN_SUCCESS)
+ if (kr != KERN_SUCCESS) {
+ is_write_unlock(space);
return kr;
- /* space is write-locked and active */
+ }
if ((msgt_name != MACH_MSG_TYPE_PORT_SEND_ONCE) &&
ipc_right_reverse(space, object, &oname, &oentry)) {
@@ -940,10 +936,12 @@ ipc_object_rename(
ipc_entry_t oentry, nentry;
kern_return_t kr;
+ is_write_lock(space);
kr = ipc_entry_alloc_name(space, nname, &nentry);
- if (kr != KERN_SUCCESS)
+ if (kr != KERN_SUCCESS) {
+ is_write_unlock(space);
return kr;
- /* space is write-locked and active */
+ }
if (ipc_right_inuse(space, nname, nentry)) {
/* space is unlocked */
@@ -1007,7 +1005,7 @@ char *ikot_print_array[IKOT_MAX_TYPE] = {
void
ipc_object_print(
- ipc_object_t object)
+ const ipc_object_t object)
{
int kotype;
diff --git a/ipc/ipc_object.h b/ipc/ipc_object.h
index adf5bca4..be5bea71 100644
--- a/ipc/ipc_object.h
+++ b/ipc/ipc_object.h
@@ -38,7 +38,7 @@
#include <mach/message.h>
#include <ipc/ipc_types.h>
#include <kern/lock.h>
-#include <kern/macro_help.h>
+#include <kern/macros.h>
#include <kern/slab.h>
typedef unsigned int ipc_object_refs_t;
@@ -57,7 +57,9 @@ typedef struct ipc_object {
#define IO_VALID(io) (((io) != IO_NULL) && ((io) != IO_DEAD))
#define IO_BITS_KOTYPE 0x0000ffff /* used by the object */
-#define IO_BITS_OTYPE 0x7fff0000 /* determines a cache */
+#define IO_BITS_OTYPE 0x3fff0000 /* determines a cache */
+/* The following masks are used to store attributes of ipc ports. */
+#define IO_BITS_PROTECTED_PAYLOAD 0x40000000 /* pp set? */
#define IO_BITS_ACTIVE 0x80000000U /* is object alive? */
#define io_active(io) ((int)(io)->io_bits < 0) /* hack */
diff --git a/ipc/ipc_port.c b/ipc/ipc_port.c
index 8e41c3ca..86a4ee2a 100644
--- a/ipc/ipc_port.c
+++ b/ipc/ipc_port.c
@@ -53,6 +53,7 @@
#if MACH_KDB
#include <ddb/db_output.h>
+#include <ipc/ipc_print.h>
#endif /* MACH_KDB */
@@ -93,11 +94,11 @@ ipc_port_timestamp(void)
*/
kern_return_t
-ipc_port_dnrequest(port, name, soright, indexp)
- ipc_port_t port;
- mach_port_t name;
- ipc_port_t soright;
- ipc_port_request_index_t *indexp;
+ipc_port_dnrequest(
+ ipc_port_t port,
+ mach_port_t name,
+ ipc_port_t soright,
+ ipc_port_request_index_t *indexp)
{
ipc_port_request_t ipr, table;
ipc_port_request_index_t index;
@@ -141,8 +142,7 @@ ipc_port_dnrequest(port, name, soright, indexp)
*/
kern_return_t
-ipc_port_dngrow(port)
- ipc_port_t port;
+ipc_port_dngrow(ipc_port_t port)
{
ipc_table_size_t its;
ipc_port_request_t otable, ntable;
@@ -274,9 +274,9 @@ ipc_port_dncancel(
void
ipc_port_pdrequest(
- ipc_port_t port,
- ipc_port_t notify,
- ipc_port_t *previousp)
+ ipc_port_t port,
+ const ipc_port_t notify,
+ ipc_port_t *previousp)
{
ipc_port_t previous;
@@ -381,8 +381,7 @@ ipc_port_set_qlimit(
*/
ipc_mqueue_t
-ipc_port_lock_mqueue(port)
- ipc_port_t port;
+ipc_port_lock_mqueue(ipc_port_t port)
{
if (port->ip_pset != IPS_NULL) {
ipc_pset_t pset = port->ip_pset;
@@ -412,9 +411,9 @@ ipc_port_lock_mqueue(port)
*/
void
-ipc_port_set_seqno(port, seqno)
- ipc_port_t port;
- mach_port_seqno_t seqno;
+ipc_port_set_seqno(
+ ipc_port_t port,
+ mach_port_seqno_t seqno)
{
ipc_mqueue_t mqueue;
@@ -424,6 +423,44 @@ ipc_port_set_seqno(port, seqno)
}
/*
+ * Routine: ipc_port_set_protected_payload
+ * Purpose:
+ * Changes a port's protected payload.
+ * Conditions:
+ * The port is locked and active.
+ */
+
+void
+ipc_port_set_protected_payload(ipc_port_t port, unsigned long payload)
+{
+ ipc_mqueue_t mqueue;
+
+ mqueue = ipc_port_lock_mqueue(port);
+ port->ip_protected_payload = payload;
+ ipc_port_flag_protected_payload_set(port);
+ imq_unlock(mqueue);
+}
+
+/*
+ * Routine: ipc_port_clear_protected_payload
+ * Purpose:
+ * Clear a port's protected payload.
+ * Conditions:
+ * The port is locked and active.
+ */
+
+void
+ipc_port_clear_protected_payload(ipc_port_t port)
+{
+ ipc_mqueue_t mqueue;
+
+ mqueue = ipc_port_lock_mqueue(port);
+ ipc_port_flag_protected_payload_clear(port);
+ imq_unlock(mqueue);
+}
+
+
+/*
* Routine: ipc_port_clear_receiver
* Purpose:
* Prepares a receive right for transmission/destruction.
@@ -492,6 +529,8 @@ ipc_port_init(
port->ip_seqno = 0;
port->ip_msgcount = 0;
port->ip_qlimit = MACH_PORT_QLIMIT_DEFAULT;
+ ipc_port_flag_protected_payload_clear(port);
+ port->ip_protected_payload = 0;
ipc_mqueue_init(&port->ip_messages);
ipc_thread_queue_init(&port->ip_blocked);
@@ -614,6 +653,7 @@ ipc_port_destroy(
/* make port be in limbo */
port->ip_receiver_name = MACH_PORT_NULL;
port->ip_destination = IP_NULL;
+ ipc_port_flag_protected_payload_clear(port);
ip_unlock(port);
if (!ipc_port_check_circularity(port, pdrequest)) {
@@ -1134,16 +1174,15 @@ ipc_port_release_receive(
*/
ipc_port_t
-ipc_port_alloc_special(space)
- ipc_space_t space;
+ipc_port_alloc_special(ipc_space_t space)
{
ipc_port_t port;
- port = (ipc_port_t) io_alloc(IOT_PORT);
+ port = ip_alloc();
if (port == IP_NULL)
return IP_NULL;
- io_lock_init(&port->ip_object);
+ ip_lock_init(port);
port->ip_references = 1;
port->ip_object.io_bits = io_makebits(TRUE, IOT_PORT, 0);
@@ -1211,12 +1250,17 @@ ipc_port_dealloc_special(
void
ipc_port_print(port)
- ipc_port_t port;
+ const ipc_port_t port;
{
printf("port 0x%x\n", port);
indent += 2;
+ iprintf("flags ");
+ printf("has_protected_payload=%d",
+ ipc_port_flag_protected_payload(port));
+ printf("\n");
+
ipc_object_print(&port->ip_object);
iprintf("receiver=0x%x", port->ip_receiver);
printf(", receiver_name=0x%x\n", port->ip_receiver_name);
@@ -1239,7 +1283,9 @@ ipc_port_print(port)
printf(", sndrs=0x%x", port->ip_blocked.ithq_base);
printf(", kobj=0x%x\n", port->ip_kobject);
- indent -=2;
+ iprintf("protected_payload=%p\n", (void *) port->ip_protected_payload);
+
+ indent -= 2;
}
#endif /* MACH_KDB */
diff --git a/ipc/ipc_port.h b/ipc/ipc_port.h
index 70ec4946..ade69679 100644
--- a/ipc/ipc_port.h
+++ b/ipc/ipc_port.h
@@ -43,11 +43,12 @@
#include <mach/kern_return.h>
#include <mach/port.h>
#include <kern/lock.h>
-#include <kern/macro_help.h>
+#include <kern/macros.h>
#include <kern/ipc_kobject.h>
#include <ipc/ipc_mqueue.h>
#include <ipc/ipc_table.h>
#include <ipc/ipc_thread.h>
+#include <ipc/ipc_object.h>
#include "ipc_target.h"
#include <mach/rpc.h>
@@ -96,6 +97,7 @@ struct ipc_port {
mach_port_msgcount_t ip_msgcount;
mach_port_msgcount_t ip_qlimit;
struct ipc_thread_queue ip_blocked;
+ unsigned long ip_protected_payload;
};
#define ip_object ip_target.ipt_object
@@ -262,6 +264,12 @@ extern void
ipc_port_set_seqno(ipc_port_t, mach_port_seqno_t);
extern void
+ipc_port_set_protected_payload(ipc_port_t, unsigned long);
+
+extern void
+ipc_port_clear_protected_payload(ipc_port_t);
+
+extern void
ipc_port_clear_receiver(ipc_port_t);
extern void
@@ -325,7 +333,23 @@ ipc_port_dealloc_special(ipc_port_t, ipc_space_t);
#define ipc_port_release(port) \
ipc_object_release(&(port)->ip_object)
-extern void
-ipc_port_print(ipc_port_t);
+static inline boolean_t
+ipc_port_flag_protected_payload(const struct ipc_port *port)
+{
+ return !! (port->ip_target.ipt_object.io_bits
+ & IO_BITS_PROTECTED_PAYLOAD);
+}
+
+static inline void
+ipc_port_flag_protected_payload_set(struct ipc_port *port)
+{
+ port->ip_target.ipt_object.io_bits |= IO_BITS_PROTECTED_PAYLOAD;
+}
+
+static inline void
+ipc_port_flag_protected_payload_clear(struct ipc_port *port)
+{
+ port->ip_target.ipt_object.io_bits &= ~IO_BITS_PROTECTED_PAYLOAD;
+}
#endif /* _IPC_IPC_PORT_H_ */
diff --git a/ipc/ipc_print.h b/ipc/ipc_print.h
new file mode 100644
index 00000000..5e8e4f34
--- /dev/null
+++ b/ipc/ipc_print.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2013 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _IPC_PRINT_H_
+#define _IPC_PRINT_H_
+
+#if MACH_KDB
+
+#include <mach/mach_types.h>
+#include <mach/message.h>
+#include <ipc/ipc_types.h>
+#include <ipc/ipc_pset.h>
+
+extern void ipc_port_print(const ipc_port_t);
+
+extern void ipc_pset_print(const ipc_pset_t);
+
+extern void ipc_kmsg_print(const ipc_kmsg_t);
+
+extern void ipc_msg_print(mach_msg_header_t*);
+
+#endif /* MACH_KDB */
+
+#endif /* IPC_PRINT_H */
diff --git a/ipc/ipc_pset.c b/ipc/ipc_pset.c
index e2b3c862..884e8972 100644
--- a/ipc/ipc_pset.c
+++ b/ipc/ipc_pset.c
@@ -48,6 +48,7 @@
#if MACH_KDB
#include <ddb/db_output.h>
+#include <ipc/ipc_print.h>
#endif /* MACH_KDB */
@@ -333,7 +334,7 @@ ipc_pset_destroy(
void
ipc_pset_print(
- ipc_pset_t pset)
+ const ipc_pset_t pset)
{
printf("pset 0x%x\n", pset);
@@ -344,7 +345,7 @@ ipc_pset_print(
iprintf("kmsgs = 0x%x", pset->ips_messages.imq_messages.ikmq_base);
printf(",rcvrs = 0x%x\n", pset->ips_messages.imq_threads.ithq_base);
- indent -=2;
+ indent -= 2;
}
#endif /* MACH_KDB */
diff --git a/ipc/ipc_pset.h b/ipc/ipc_pset.h
index ac984f99..e9936fef 100644
--- a/ipc/ipc_pset.h
+++ b/ipc/ipc_pset.h
@@ -89,7 +89,4 @@ ipc_pset_destroy(ipc_pset_t);
#define ipc_pset_release(pset) \
ipc_object_release(&(pset)->ips_object)
-extern void
-ipc_pset_print(ipc_pset_t);
-
#endif /* _IPC_IPC_PSET_H_ */
diff --git a/ipc/ipc_right.c b/ipc/ipc_right.c
index 41fe3de1..773b3b10 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);
@@ -331,10 +331,10 @@ ipc_right_dncancel(
*/
boolean_t
-ipc_right_inuse(space, name, entry)
- ipc_space_t space;
- mach_port_t name;
- ipc_entry_t entry;
+ipc_right_inuse(
+ ipc_space_t space,
+ mach_port_t name,
+ ipc_entry_t entry)
{
ipc_entry_bits_t bits = entry->ie_bits;
@@ -359,11 +359,11 @@ ipc_right_inuse(space, name, entry)
*/
boolean_t
-ipc_right_check(space, port, name, entry)
- ipc_space_t space;
- ipc_port_t port;
- mach_port_t name;
- ipc_entry_t entry;
+ipc_right_check(
+ ipc_space_t space,
+ ipc_port_t port,
+ mach_port_t name,
+ ipc_entry_t entry)
{
ipc_entry_bits_t bits;
@@ -392,7 +392,7 @@ ipc_right_check(space, port, name, entry)
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);
@@ -423,7 +423,7 @@ ipc_right_check(space, port, name, entry)
* Purpose:
* Cleans up an entry in a dead space.
* The entry isn't deallocated or removed
- * from reverse hash tables.
+ * from the reverse mappings.
* Conditions:
* The space is dead and unlocked.
*/
@@ -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);
@@ -697,10 +696,10 @@ ipc_right_destroy(
*/
kern_return_t
-ipc_right_dealloc(space, name, entry)
- ipc_space_t space;
- mach_port_t name;
- ipc_entry_t entry;
+ipc_right_dealloc(
+ ipc_space_t space,
+ mach_port_t name,
+ ipc_entry_t entry)
{
ipc_entry_bits_t bits = entry->ie_bits;
mach_port_type_t type = IE_BITS_TYPE(bits);
@@ -789,8 +788,7 @@ ipc_right_dealloc(space, name, entry)
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);
@@ -874,12 +872,12 @@ ipc_right_dealloc(space, name, entry)
*/
kern_return_t
-ipc_right_delta(space, name, entry, right, delta)
- ipc_space_t space;
- mach_port_t name;
- ipc_entry_t entry;
- mach_port_right_t right;
- mach_port_delta_t delta;
+ipc_right_delta(
+ ipc_space_t space,
+ mach_port_t name,
+ ipc_entry_t entry,
+ mach_port_right_t right,
+ mach_port_delta_t delta)
{
ipc_entry_bits_t bits = entry->ie_bits;
@@ -1134,8 +1132,7 @@ ipc_right_delta(space, name, entry, 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 {
@@ -1432,6 +1429,12 @@ ipc_right_copyin(
port->ip_receiver_name = MACH_PORT_NULL;
port->ip_destination = IP_NULL;
+
+ /*
+ * Clear the protected payload field to retain
+ * the behavior of mach_msg.
+ */
+ ipc_port_flag_protected_payload_clear(port);
ip_unlock(port);
*objectp = (ipc_object_t) port;
@@ -1528,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);
@@ -1790,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);
@@ -1915,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;
@@ -1932,6 +1933,12 @@ ipc_right_copyout(
port->ip_receiver_name = name;
port->ip_receiver = space;
+ /*
+ * Clear the protected payload field to retain
+ * the behavior of mach_msg.
+ */
+ ipc_port_flag_protected_payload_clear(port);
+
assert((bits & MACH_PORT_TYPE_RECEIVE) == 0);
if (bits & MACH_PORT_TYPE_SEND) {
@@ -1944,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);
@@ -2071,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;
@@ -2085,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_space.c b/ipc/ipc_space.c
index ab55e838..894cf58e 100644
--- a/ipc/ipc_space.c
+++ b/ipc/ipc_space.c
@@ -46,8 +46,6 @@
#include <kern/slab.h>
#include <ipc/port.h>
#include <ipc/ipc_entry.h>
-#include <ipc/ipc_splay.h>
-#include <ipc/ipc_hash.h>
#include <ipc/ipc_table.h>
#include <ipc/ipc_port.h>
#include <ipc/ipc_space.h>
@@ -82,6 +80,9 @@ ipc_space_release(
ipc_space_release_macro(space);
}
+/* A place-holder object for the zeroth entry. */
+struct ipc_entry zero_entry;
+
/*
* Routine: ipc_space_create
* Purpose:
@@ -98,56 +99,27 @@ ipc_space_release(
kern_return_t
ipc_space_create(
- ipc_table_size_t initial,
ipc_space_t *spacep)
{
ipc_space_t space;
- ipc_entry_t table;
- ipc_entry_num_t new_size;
- mach_port_index_t index;
space = is_alloc();
if (space == IS_NULL)
return KERN_RESOURCE_SHORTAGE;
- table = it_entries_alloc(initial);
- if (table == IE_NULL) {
- is_free(space);
- return KERN_RESOURCE_SHORTAGE;
- }
-
- new_size = initial->its_size;
- memset((void *) table, 0, new_size * sizeof(struct ipc_entry));
-
- /*
- * Initialize the free list in the table.
- * Add the entries in reverse order, and
- * set the generation number to -1, so that
- * initial allocations produce "natural" names.
- */
-
- for (index = 0; index < new_size; index++) {
- ipc_entry_t entry = &table[index];
-
- entry->ie_bits = IE_BITS_GEN_MASK;
- entry->ie_next = index+1;
- }
- table[new_size-1].ie_next = 0;
-
is_ref_lock_init(space);
space->is_references = 2;
is_lock_init(space);
space->is_active = TRUE;
- space->is_growing = FALSE;
- space->is_table = table;
- space->is_table_size = new_size;
- space->is_table_next = initial+1;
- ipc_splay_tree_init(&space->is_tree);
- space->is_tree_total = 0;
- space->is_tree_small = 0;
- space->is_tree_hash = 0;
+ rdxtree_init(&space->is_map);
+ rdxtree_init(&space->is_reverse_map);
+ /* The zeroth entry is reserved. */
+ rdxtree_insert(&space->is_map, 0, &zero_entry);
+ space->is_size = 1;
+ space->is_free_list = NULL;
+ space->is_free_list_size = 0;
*spacep = space;
return KERN_SUCCESS;
@@ -201,10 +173,6 @@ void
ipc_space_destroy(
ipc_space_t space)
{
- ipc_tree_entry_t tentry;
- ipc_entry_t table;
- ipc_entry_num_t size;
- mach_port_index_t index;
boolean_t active;
assert(space != IS_NULL);
@@ -217,59 +185,25 @@ ipc_space_destroy(
if (!active)
return;
- /*
- * If somebody is trying to grow the table,
- * we must wait until they finish and figure
- * out the space died.
- */
+ ipc_entry_t entry;
+ struct rdxtree_iter iter;
+ rdxtree_for_each(&space->is_map, &iter, entry) {
+ if (entry->ie_name == MACH_PORT_NULL)
+ continue;
- is_read_lock(space);
- while (space->is_growing) {
- assert_wait((event_t) space, FALSE);
- is_read_unlock(space);
- thread_block((void (*)(void)) 0);
- is_read_lock(space);
- }
- is_read_unlock(space);
-
- /*
- * Now we can futz with it without having it locked.
- */
-
- table = space->is_table;
- size = space->is_table_size;
-
- for (index = 0; index < size; index++) {
- ipc_entry_t entry = &table[index];
mach_port_type_t type = IE_BITS_TYPE(entry->ie_bits);
if (type != MACH_PORT_TYPE_NONE) {
mach_port_t name =
- MACH_PORT_MAKEB(index, entry->ie_bits);
+ MACH_PORT_MAKEB(entry->ie_name, entry->ie_bits);
ipc_right_clean(space, name, entry);
}
- }
-
- it_entries_free(space->is_table_next-1, table);
-
- for (tentry = ipc_splay_traverse_start(&space->is_tree);
- tentry != ITE_NULL;
- tentry = ipc_splay_traverse_next(&space->is_tree, TRUE)) {
- mach_port_type_t type = IE_BITS_TYPE(tentry->ite_bits);
- mach_port_t name = tentry->ite_name;
-
- assert(type != MACH_PORT_TYPE_NONE);
-
- /* use object before ipc_right_clean releases ref */
-
- if (type == MACH_PORT_TYPE_SEND)
- ipc_hash_global_delete(space, tentry->ite_object,
- name, tentry);
- ipc_right_clean(space, name, &tentry->ite_entry);
+ ie_free(entry);
}
- ipc_splay_traverse_finish(&space->is_tree);
+ 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 c4683d20..73c90ef8 100644
--- a/ipc/ipc_space.h
+++ b/ipc/ipc_space.h
@@ -42,25 +42,18 @@
#include <mach/boolean.h>
#include <mach/kern_return.h>
#include <mach/mach_types.h>
-#include <kern/macro_help.h>
+#include <machine/vm_param.h>
+#include <kern/macros.h>
#include <kern/lock.h>
+#include <kern/rdxtree.h>
#include <kern/slab.h>
-#include <ipc/ipc_splay.h>
+#include <ipc/ipc_entry.h>
#include <ipc/ipc_types.h>
/*
* Every task has a space of IPC capabilities.
* IPC operations like send and receive use this space.
* IPC kernel calls manipulate the space of the target task.
- *
- * Every space has a non-NULL is_table with is_table_size entries.
- * A space may have a NULL is_tree. is_tree_small records the
- * number of entries in the tree that, if the table were to grow
- * to the next larger size, would move from the tree to the table.
- *
- * is_growing marks when the table is in the process of growing.
- * When the table is growing, it can't be freed or grown by another
- * thread, because of krealloc/kmem_realloc's requirements.
*/
typedef unsigned int ipc_space_refs_t;
@@ -69,18 +62,18 @@ struct ipc_space {
decl_simple_lock_data(,is_ref_lock_data)
ipc_space_refs_t is_references;
- decl_simple_lock_data(,is_lock_data)
+ struct lock is_lock_data;
boolean_t is_active; /* is the space alive? */
- boolean_t is_growing; /* is the space growing? */
- ipc_entry_t is_table; /* an array of entries */
- ipc_entry_num_t is_table_size; /* current size of table */
- struct ipc_table_size *is_table_next; /* info for larger table */
- struct ipc_splay_tree is_tree; /* a splay tree of entries */
- ipc_entry_num_t is_tree_total; /* number of entries in the tree */
- ipc_entry_num_t is_tree_small; /* # of small entries in the tree */
- ipc_entry_num_t is_tree_hash; /* # of hashed entries in the tree */
+ struct rdxtree is_map; /* a map of entries */
+ size_t is_size; /* number of entries */
+ struct rdxtree 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
+ in the free list */
};
+
#define IS_NULL ((ipc_space_t) 0)
extern struct kmem_cache ipc_space_cache;
@@ -114,16 +107,16 @@ MACRO_BEGIN \
is_free(is); \
MACRO_END
-#define is_lock_init(is) simple_lock_init(&(is)->is_lock_data)
+#define is_lock_init(is) lock_init(&(is)->is_lock_data, TRUE)
-#define is_read_lock(is) simple_lock(&(is)->is_lock_data)
-#define is_read_unlock(is) simple_unlock(&(is)->is_lock_data)
+#define is_read_lock(is) lock_read(&(is)->is_lock_data)
+#define is_read_unlock(is) lock_done(&(is)->is_lock_data)
-#define is_write_lock(is) simple_lock(&(is)->is_lock_data)
-#define is_write_lock_try(is) simple_lock_try(&(is)->is_lock_data)
-#define is_write_unlock(is) simple_unlock(&(is)->is_lock_data)
+#define is_write_lock(is) lock_write(&(is)->is_lock_data)
+#define is_write_lock_try(is) lock_try_write(&(is)->is_lock_data)
+#define is_write_unlock(is) lock_done(&(is)->is_lock_data)
-#define is_write_to_read_lock(is)
+#define is_write_to_read_lock(is) lock_write_to_read(&(is)->is_lock_data)
extern void ipc_space_reference(struct ipc_space *space);
extern void ipc_space_release(struct ipc_space *space);
@@ -131,8 +124,187 @@ extern void ipc_space_release(struct ipc_space *space);
#define is_reference(is) ipc_space_reference(is)
#define is_release(is) ipc_space_release(is)
-kern_return_t ipc_space_create(ipc_table_size_t, ipc_space_t *);
+kern_return_t ipc_space_create(ipc_space_t *);
kern_return_t ipc_space_create_special(struct ipc_space **);
void ipc_space_destroy(struct ipc_space *);
+/* IPC entry lookups. */
+
+/*
+ * Routine: ipc_entry_lookup
+ * Purpose:
+ * Searches for an entry, given its name.
+ * Conditions:
+ * The space must be read or write locked throughout.
+ * The space must be active.
+ */
+
+static inline ipc_entry_t
+ipc_entry_lookup(
+ ipc_space_t space,
+ mach_port_t name)
+{
+ ipc_entry_t entry;
+
+ assert(space->is_active);
+ entry = rdxtree_lookup(&space->is_map, (rdxtree_key_t) name);
+ if (entry != IE_NULL
+ && IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE)
+ entry = NULL;
+ assert((entry == IE_NULL) || IE_BITS_TYPE(entry->ie_bits));
+ return entry;
+}
+
+/*
+ * Routine: ipc_entry_get
+ * Purpose:
+ * Tries to allocate an entry out of the space.
+ * Conditions:
+ * The space is write-locked and active throughout.
+ * An object may be locked. Will not allocate memory.
+ * Returns:
+ * KERN_SUCCESS A free entry was found.
+ * KERN_NO_SPACE No entry allocated.
+ */
+
+static inline kern_return_t
+ipc_entry_get(
+ ipc_space_t space,
+ mach_port_t *namep,
+ ipc_entry_t *entryp)
+{
+ mach_port_t new_name;
+ ipc_entry_t free_entry;
+
+ assert(space->is_active);
+
+ /* Get entry from the free list. */
+ free_entry = space->is_free_list;
+ if (free_entry == IE_NULL)
+ return KERN_NO_SPACE;
+
+ space->is_free_list = free_entry->ie_next_free;
+ space->is_free_list_size -= 1;
+
+ /*
+ * Initialize the new entry. We need only
+ * increment the generation number and clear ie_request.
+ */
+
+ {
+ mach_port_gen_t gen;
+
+ assert((free_entry->ie_bits &~ IE_BITS_GEN_MASK) == 0);
+ gen = free_entry->ie_bits + IE_BITS_GEN_ONE;
+ free_entry->ie_bits = gen;
+ free_entry->ie_request = 0;
+ new_name = MACH_PORT_MAKE(free_entry->ie_name, gen);
+ }
+
+ /*
+ * The new name can't be MACH_PORT_NULL because index
+ * is non-zero. It can't be MACH_PORT_DEAD because
+ * the table isn't allowed to grow big enough.
+ * (See comment in ipc/ipc_table.h.)
+ */
+
+ assert(MACH_PORT_VALID(new_name));
+ assert(free_entry->ie_object == IO_NULL);
+
+ space->is_size += 1;
+ *namep = new_name;
+ *entryp = free_entry;
+ return KERN_SUCCESS;
+}
+
+/*
+ * Routine: ipc_entry_dealloc
+ * Purpose:
+ * Deallocates an entry from a space.
+ * Conditions:
+ * The space must be write-locked throughout.
+ * The space must be active.
+ */
+
+static inline void
+ipc_entry_dealloc(
+ ipc_space_t space,
+ mach_port_t name,
+ ipc_entry_t entry)
+{
+ assert(space->is_active);
+ assert(entry->ie_object == IO_NULL);
+ assert(entry->ie_request == 0);
+
+ if (space->is_free_list_size < IS_FREE_LIST_SIZE_LIMIT) {
+ space->is_free_list_size += 1;
+ entry->ie_bits &= IE_BITS_GEN_MASK;
+ entry->ie_next_free = space->is_free_list;
+ space->is_free_list = entry;
+ } else {
+ rdxtree_remove(&space->is_map, (rdxtree_key_t) name);
+ ie_free(entry);
+ }
+ space->is_size -= 1;
+}
+
+/* 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)); \
+ })
+
+/* Insert (OBJ, ENTRY) pair into the reverse mapping. SPACE must
+ be write-locked. */
+static inline kern_return_t
+ipc_reverse_insert(ipc_space_t space,
+ ipc_object_t obj,
+ ipc_entry_t entry)
+{
+ assert(space != IS_NULL);
+ assert(obj != IO_NULL);
+ return (kern_return_t) rdxtree_insert(&space->is_reverse_map,
+ KEY(obj), entry);
+}
+
+/* Remove OBJ from the reverse mapping. SPACE must be
+ write-locked. */
+static inline ipc_entry_t
+ipc_reverse_remove(ipc_space_t space,
+ ipc_object_t obj)
+{
+ assert(space != IS_NULL);
+ assert(obj != IO_NULL);
+ return rdxtree_remove(&space->is_reverse_map, KEY(obj));
+}
+
+/* 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);
+}
+
+/* Return ENTRY related to OBJ, or NULL if no such entry is found in
+ the reverse mapping. SPACE must be read-locked or
+ write-locked. */
+static inline ipc_entry_t
+ipc_reverse_lookup(ipc_space_t space,
+ ipc_object_t obj)
+{
+ assert(space != IS_NULL);
+ assert(obj != IO_NULL);
+ return rdxtree_lookup(&space->is_reverse_map, KEY(obj));
+}
+
+#undef KEY
+
#endif /* _IPC_IPC_SPACE_H_ */
diff --git a/ipc/ipc_splay.c b/ipc/ipc_splay.c
deleted file mode 100644
index 6fb5bcbc..00000000
--- 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 d3316ef8..00000000
--- 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_ */
diff --git a/ipc/ipc_table.c b/ipc/ipc_table.c
index cbb6a894..0f8592a3 100644
--- a/ipc/ipc_table.c
+++ b/ipc/ipc_table.c
@@ -42,20 +42,8 @@
#include <kern/slab.h>
#include <vm/vm_kern.h>
-/*
- * Forward declarations
- */
-void ipc_table_fill(
- ipc_table_size_t its,
- unsigned int num,
- unsigned int min,
- vm_size_t elemsize);
-
-ipc_table_size_t ipc_table_entries;
-unsigned int ipc_table_entries_size = 512;
-
ipc_table_size_t ipc_table_dnrequests;
-unsigned int ipc_table_dnrequests_size = 64;
+const unsigned int ipc_table_dnrequests_size = 64;
void
ipc_table_fill(
@@ -101,20 +89,6 @@ ipc_table_fill(
void
ipc_table_init(void)
{
- ipc_table_entries = (ipc_table_size_t)
- kalloc(sizeof(struct ipc_table_size) *
- ipc_table_entries_size);
- assert(ipc_table_entries != ITS_NULL);
-
- ipc_table_fill(ipc_table_entries, ipc_table_entries_size - 1,
- 4, sizeof(struct ipc_entry));
-
- /* the last two elements should have the same size */
-
- ipc_table_entries[ipc_table_entries_size - 1].its_size =
- ipc_table_entries[ipc_table_entries_size - 2].its_size;
-
-
ipc_table_dnrequests = (ipc_table_size_t)
kalloc(sizeof(struct ipc_table_size) *
ipc_table_dnrequests_size);
@@ -140,42 +114,7 @@ vm_offset_t
ipc_table_alloc(
vm_size_t size)
{
- vm_offset_t table;
-
- if (size < PAGE_SIZE)
- table = kalloc(size);
- else
- if (kmem_alloc(kmem_map, &table, size) != KERN_SUCCESS)
- table = 0;
-
- return table;
-}
-
-/*
- * Routine: ipc_table_realloc
- * Purpose:
- * Reallocate a big table.
- *
- * The new table remaps the old table,
- * so copying is not necessary.
- * Conditions:
- * Only works for page-size or bigger tables.
- * May block.
- */
-
-vm_offset_t
-ipc_table_realloc(
- vm_size_t old_size,
- vm_offset_t old_table,
- vm_size_t new_size)
-{
- vm_offset_t new_table;
-
- if (kmem_realloc(kmem_map, old_table, old_size,
- &new_table, new_size) != KERN_SUCCESS)
- new_table = 0;
-
- return new_table;
+ return kalloc(size);
}
/*
@@ -192,8 +131,5 @@ ipc_table_free(
vm_size_t size,
vm_offset_t table)
{
- if (size < PAGE_SIZE)
- kfree(table, size);
- else
- kmem_free(kmem_map, table, size);
+ kfree(table, size);
}
diff --git a/ipc/ipc_table.h b/ipc/ipc_table.h
index 695adae4..7968e6bb 100644
--- a/ipc/ipc_table.h
+++ b/ipc/ipc_table.h
@@ -30,8 +30,8 @@
* Author: Rich Draves
* Date: 1989
*
- * Definitions for tables, used for IPC capabilities (ipc_entry_t)
- * and dead-name requests (ipc_port_request_t).
+ * Definitions for tables, used for dead-name requests
+ * (ipc_port_request_t).
*/
#ifndef _IPC_IPC_TABLE_H_
@@ -41,20 +41,7 @@
#include <mach/vm_param.h>
/*
- * The is_table_next field of an ipc_space_t points to
- * an ipc_table_size structure. These structures must
- * be elements of an array, ipc_table_entries.
- *
- * The array must end with two elements with the same its_size value.
- * Except for the terminating element, the its_size values must
- * be strictly increasing. The largest (last) its_size value
- * must be less than or equal to MACH_PORT_INDEX(MACH_PORT_DEAD).
- * This ensures that
- * 1) MACH_PORT_INDEX(MACH_PORT_DEAD) isn't a valid index
- * in the table, so ipc_entry_get won't allocate it.
- * 2) MACH_PORT_MAKE(index+1, 0) and MAKE_PORT_MAKE(size, 0)
- * won't ever overflow.
- *
+ * Every its_size value must must be a power of two.
*
* The ipr_size field of the first element in a table of
* dead-name requests (ipc_port_request_t) points to the
@@ -63,8 +50,6 @@
* with an element with zero its_size, and except for this last
* element, the its_size values must be strictly increasing.
*
- * The is_table_next field points to the ipc_table_size structure
- * for the next larger size of table, not the one currently in use.
* The ipr_size field points to the currently used ipc_table_size.
*/
@@ -77,53 +62,31 @@ typedef struct ipc_table_size {
#define ITS_NULL ((ipc_table_size_t) 0)
-extern ipc_table_size_t ipc_table_entries;
extern ipc_table_size_t ipc_table_dnrequests;
extern void
ipc_table_init(void);
/*
- * Note that ipc_table_alloc, ipc_table_realloc, and ipc_table_free
- * all potentially use the VM system. Hence simple locks can't
- * be held across them.
- *
- * We can't use a copying realloc, because the realloc happens
- * with the data unlocked. ipc_table_realloc remaps the data,
- * so it is OK.
+ * Note that ipc_table_alloc, and ipc_table_free all potentially
+ * use the VM system. Hence simple locks can't be held across
+ * them.
*/
/* Allocate a table */
extern vm_offset_t ipc_table_alloc(
vm_size_t size);
-/* Reallocate a big table */
-extern vm_offset_t ipc_table_realloc(
- vm_size_t old_size,
- vm_offset_t old_table,
- vm_size_t new_size);
-
/* Free a table */
extern void ipc_table_free(
vm_size_t size,
vm_offset_t table);
-#define it_entries_alloc(its) \
- ((ipc_entry_t) \
- ipc_table_alloc((its)->its_size * sizeof(struct ipc_entry)))
-
-#define it_entries_reallocable(its) \
- (((its)->its_size * sizeof(struct ipc_entry)) >= PAGE_SIZE)
-
-#define it_entries_realloc(its, table, nits) \
- ((ipc_entry_t) \
- ipc_table_realloc((its)->its_size * sizeof(struct ipc_entry), \
- (vm_offset_t)(table), \
- (nits)->its_size * sizeof(struct ipc_entry)))
-
-#define it_entries_free(its, table) \
- ipc_table_free((its)->its_size * sizeof(struct ipc_entry), \
- (vm_offset_t)(table))
+void ipc_table_fill(
+ ipc_table_size_t its,
+ unsigned int num,
+ unsigned int min,
+ vm_size_t elemsize);
#define it_dnrequests_alloc(its) \
((ipc_port_request_t) \
diff --git a/ipc/ipc_thread.h b/ipc/ipc_thread.h
index fbeea46a..008ab4a9 100644
--- a/ipc/ipc_thread.h
+++ b/ipc/ipc_thread.h
@@ -75,7 +75,7 @@ MACRO_END
#define ipc_thread_rmqueue_first_macro(queue, thread) \
MACRO_BEGIN \
- register ipc_thread_t _next; \
+ ipc_thread_t _next; \
\
assert((queue)->ithq_base == (thread)); \
\
@@ -84,7 +84,7 @@ MACRO_BEGIN \
assert((thread)->ith_prev == (thread)); \
(queue)->ithq_base = ITH_NULL; \
} else { \
- register ipc_thread_t _prev = (thread)->ith_prev; \
+ ipc_thread_t _prev = (thread)->ith_prev; \
\
(queue)->ithq_base = _next; \
_next->ith_prev = _prev; \
@@ -95,14 +95,14 @@ MACRO_END
#define ipc_thread_enqueue_macro(queue, thread) \
MACRO_BEGIN \
- register ipc_thread_t _first = (queue)->ithq_base; \
+ ipc_thread_t _first = (queue)->ithq_base; \
\
if (_first == ITH_NULL) { \
(queue)->ithq_base = (thread); \
assert((thread)->ith_next == (thread)); \
assert((thread)->ith_prev == (thread)); \
} else { \
- register ipc_thread_t _last = _first->ith_prev; \
+ ipc_thread_t _last = _first->ith_prev; \
\
(thread)->ith_next = _first; \
(thread)->ith_prev = _last; \
diff --git a/ipc/mach_debug.c b/ipc/mach_debug.c
index 28dd6935..efb07a4f 100644
--- a/ipc/mach_debug.c
+++ b/ipc/mach_debug.c
@@ -46,7 +46,6 @@
#include <vm/vm_kern.h>
#include <ipc/ipc_space.h>
#include <ipc/ipc_port.h>
-#include <ipc/ipc_hash.h>
#include <ipc/ipc_marequest.h>
#include <ipc/ipc_table.h>
#include <ipc/ipc_right.h>
@@ -94,85 +93,6 @@ mach_port_get_srights(
}
/*
- * Routine: host_ipc_hash_info
- * Purpose:
- * Return information about the global reverse hash table.
- * Conditions:
- * Nothing locked. Obeys CountInOut protocol.
- * Returns:
- * KERN_SUCCESS Returned information.
- * KERN_INVALID_HOST The host is null.
- * KERN_RESOURCE_SHORTAGE Couldn't allocate memory.
- */
-
-kern_return_t
-host_ipc_hash_info(
- host_t host,
- hash_info_bucket_array_t *infop,
- mach_msg_type_number_t *countp)
-{
- vm_offset_t addr;
- vm_size_t size = 0; /* Suppress gcc warning */
- hash_info_bucket_t *info;
- unsigned int potential, actual;
- kern_return_t kr;
-
- if (host == HOST_NULL)
- return KERN_INVALID_HOST;
-
- /* start with in-line data */
-
- info = *infop;
- potential = *countp;
-
- for (;;) {
- actual = ipc_hash_info(info, potential);
- if (actual <= potential)
- break;
-
- /* allocate more memory */
-
- if (info != *infop)
- kmem_free(ipc_kernel_map, addr, size);
-
- size = round_page(actual * sizeof *info);
- kr = kmem_alloc_pageable(ipc_kernel_map, &addr, size);
- if (kr != KERN_SUCCESS)
- return KERN_RESOURCE_SHORTAGE;
-
- info = (hash_info_bucket_t *) addr;
- potential = size/sizeof *info;
- }
-
- if (info == *infop) {
- /* data fit in-line; nothing to deallocate */
-
- *countp = actual;
- } else if (actual == 0) {
- kmem_free(ipc_kernel_map, addr, size);
-
- *countp = 0;
- } else {
- vm_map_copy_t copy;
- vm_size_t used;
-
- used = round_page(actual * sizeof *info);
-
- if (used != size)
- kmem_free(ipc_kernel_map, addr + used, size - used);
-
- kr = vm_map_copyin(ipc_kernel_map, addr, used,
- TRUE, &copy);
- assert(kr == KERN_SUCCESS);
-
- *infop = (hash_info_bucket_t *) copy;
- *countp = actual;
- }
-
- return KERN_SUCCESS;
-}
-
-/*
* Routine: host_ipc_marequest_info
* Purpose:
* Return information about the marequest hash table.
@@ -185,11 +105,11 @@ host_ipc_hash_info(
*/
kern_return_t
-host_ipc_marequest_info(host, maxp, infop, countp)
- host_t host;
- unsigned int *maxp;
- hash_info_bucket_array_t *infop;
- unsigned int *countp;
+host_ipc_marequest_info(
+ host_t host,
+ unsigned int *maxp,
+ hash_info_bucket_array_t *infop,
+ unsigned int *countp)
{
vm_offset_t addr;
vm_size_t size = 0; /* '=0' to shut up lint */
@@ -253,251 +173,6 @@ host_ipc_marequest_info(host, maxp, infop, countp)
}
/*
- * Routine: mach_port_space_info
- * Purpose:
- * Returns information about an IPC space.
- * Conditions:
- * Nothing locked. Obeys CountInOut protocol.
- * Returns:
- * KERN_SUCCESS Returned information.
- * KERN_INVALID_TASK The space is null.
- * KERN_INVALID_TASK The space is dead.
- * KERN_RESOURCE_SHORTAGE Couldn't allocate memory.
- */
-
-kern_return_t
-mach_port_space_info(
- ipc_space_t space,
- ipc_info_space_t *infop,
- ipc_info_name_array_t *tablep,
- mach_msg_type_number_t *tableCntp,
- ipc_info_tree_name_array_t *treep,
- mach_msg_type_number_t *treeCntp)
-{
- ipc_info_name_t *table_info;
- unsigned int table_potential, table_actual;
- vm_offset_t table_addr;
- vm_size_t table_size = 0; /* Suppress gcc warning */
- ipc_info_tree_name_t *tree_info;
- unsigned int tree_potential, tree_actual;
- vm_offset_t tree_addr;
- vm_size_t tree_size = 0; /* Suppress gcc warning */
- ipc_tree_entry_t tentry;
- ipc_entry_t table;
- ipc_entry_num_t tsize;
- mach_port_index_t index;
- kern_return_t kr;
-
- if (space == IS_NULL)
- return KERN_INVALID_TASK;
-
- /* start with in-line memory */
-
- table_info = *tablep;
- table_potential = *tableCntp;
- tree_info = *treep;
- tree_potential = *treeCntp;
-
- for (;;) {
- is_read_lock(space);
- if (!space->is_active) {
- is_read_unlock(space);
- if (table_info != *tablep)
- kmem_free(ipc_kernel_map,
- table_addr, table_size);
- if (tree_info != *treep)
- kmem_free(ipc_kernel_map,
- tree_addr, tree_size);
- return KERN_INVALID_TASK;
- }
-
- table_actual = space->is_table_size;
- tree_actual = space->is_tree_total;
-
- if ((table_actual <= table_potential) &&
- (tree_actual <= tree_potential))
- break;
-
- is_read_unlock(space);
-
- if (table_actual > table_potential) {
- if (table_info != *tablep)
- kmem_free(ipc_kernel_map,
- table_addr, table_size);
-
- table_size = round_page(table_actual *
- sizeof *table_info);
- kr = kmem_alloc(ipc_kernel_map,
- &table_addr, table_size);
- if (kr != KERN_SUCCESS) {
- if (tree_info != *treep)
- kmem_free(ipc_kernel_map,
- tree_addr, tree_size);
-
- return KERN_RESOURCE_SHORTAGE;
- }
-
- table_info = (ipc_info_name_t *) table_addr;
- table_potential = table_size/sizeof *table_info;
- }
-
- if (tree_actual > tree_potential) {
- if (tree_info != *treep)
- kmem_free(ipc_kernel_map,
- tree_addr, tree_size);
-
- tree_size = round_page(tree_actual *
- sizeof *tree_info);
- kr = kmem_alloc(ipc_kernel_map,
- &tree_addr, tree_size);
- if (kr != KERN_SUCCESS) {
- if (table_info != *tablep)
- kmem_free(ipc_kernel_map,
- table_addr, table_size);
-
- return KERN_RESOURCE_SHORTAGE;
- }
-
- tree_info = (ipc_info_tree_name_t *) tree_addr;
- tree_potential = tree_size/sizeof *tree_info;
- }
- }
- /* space is read-locked and active; we have enough wired memory */
-
- infop->iis_genno_mask = MACH_PORT_NGEN(MACH_PORT_DEAD);
- infop->iis_table_size = space->is_table_size;
- infop->iis_table_next = space->is_table_next->its_size;
- infop->iis_tree_size = space->is_tree_total;
- infop->iis_tree_small = space->is_tree_small;
- infop->iis_tree_hash = space->is_tree_hash;
-
- table = space->is_table;
- tsize = space->is_table_size;
-
- for (index = 0; index < tsize; index++) {
- ipc_info_name_t *iin = &table_info[index];
- ipc_entry_t entry = &table[index];
- ipc_entry_bits_t bits = entry->ie_bits;
-
- iin->iin_name = MACH_PORT_MAKEB(index, bits);
- iin->iin_collision = (bits & IE_BITS_COLLISION) ? TRUE : FALSE;
- iin->iin_compat = FALSE;
- iin->iin_marequest = (bits & IE_BITS_MAREQUEST) ? TRUE : FALSE;
- iin->iin_type = IE_BITS_TYPE(bits);
- iin->iin_urefs = IE_BITS_UREFS(bits);
- iin->iin_object = (vm_offset_t) entry->ie_object;
- iin->iin_next = entry->ie_next;
- iin->iin_hash = entry->ie_index;
- }
-
- for (tentry = ipc_splay_traverse_start(&space->is_tree), index = 0;
- tentry != ITE_NULL;
- tentry = ipc_splay_traverse_next(&space->is_tree, FALSE)) {
- ipc_info_tree_name_t *iitn = &tree_info[index++];
- ipc_info_name_t *iin = &iitn->iitn_name;
- ipc_entry_t entry = &tentry->ite_entry;
- ipc_entry_bits_t bits = entry->ie_bits;
-
- assert(IE_BITS_TYPE(bits) != MACH_PORT_TYPE_NONE);
-
- iin->iin_name = tentry->ite_name;
- iin->iin_collision = (bits & IE_BITS_COLLISION) ? TRUE : FALSE;
- iin->iin_compat = FALSE;
- iin->iin_marequest = (bits & IE_BITS_MAREQUEST) ? TRUE : FALSE;
- iin->iin_type = IE_BITS_TYPE(bits);
- iin->iin_urefs = IE_BITS_UREFS(bits);
- iin->iin_object = (vm_offset_t) entry->ie_object;
- iin->iin_next = entry->ie_next;
- iin->iin_hash = entry->ie_index;
-
- if (tentry->ite_lchild == ITE_NULL)
- iitn->iitn_lchild = MACH_PORT_NULL;
- else
- iitn->iitn_lchild = tentry->ite_lchild->ite_name;
-
- if (tentry->ite_rchild == ITE_NULL)
- iitn->iitn_rchild = MACH_PORT_NULL;
- else
- iitn->iitn_rchild = tentry->ite_rchild->ite_name;
-
- }
- ipc_splay_traverse_finish(&space->is_tree);
- is_read_unlock(space);
-
- if (table_info == *tablep) {
- /* data fit in-line; nothing to deallocate */
-
- *tableCntp = table_actual;
- } else if (table_actual == 0) {
- kmem_free(ipc_kernel_map, table_addr, table_size);
-
- *tableCntp = 0;
- } else {
- vm_size_t size_used, rsize_used;
- vm_map_copy_t copy;
-
- /* kmem_alloc doesn't zero memory */
-
- size_used = table_actual * sizeof *table_info;
- rsize_used = round_page(size_used);
-
- if (rsize_used != table_size)
- kmem_free(ipc_kernel_map,
- table_addr + rsize_used,
- table_size - rsize_used);
-
- if (size_used != rsize_used)
- memset((char *) (table_addr + size_used), 0,
- rsize_used - size_used);
-
- kr = vm_map_copyin(ipc_kernel_map, table_addr, rsize_used,
- TRUE, &copy);
-
- assert(kr == KERN_SUCCESS);
-
- *tablep = (ipc_info_name_t *) copy;
- *tableCntp = table_actual;
- }
-
- if (tree_info == *treep) {
- /* data fit in-line; nothing to deallocate */
-
- *treeCntp = tree_actual;
- } else if (tree_actual == 0) {
- kmem_free(ipc_kernel_map, tree_addr, tree_size);
-
- *treeCntp = 0;
- } else {
- vm_size_t size_used, rsize_used;
- vm_map_copy_t copy;
-
- /* kmem_alloc doesn't zero memory */
-
- size_used = tree_actual * sizeof *tree_info;
- rsize_used = round_page(size_used);
-
- if (rsize_used != tree_size)
- kmem_free(ipc_kernel_map,
- tree_addr + rsize_used,
- tree_size - rsize_used);
-
- if (size_used != rsize_used)
- memset((char *) (tree_addr + size_used), 0,
- rsize_used - size_used);
-
- kr = vm_map_copyin(ipc_kernel_map, tree_addr, rsize_used,
- TRUE, &copy);
-
- assert(kr == KERN_SUCCESS);
-
- *treep = (ipc_info_tree_name_t *) copy;
- *treeCntp = tree_actual;
- }
-
- return KERN_SUCCESS;
-}
-
-/*
* Routine: mach_port_dnrequest_info
* Purpose:
* Returns information about the dead-name requests
@@ -603,8 +278,8 @@ mach_port_kernel_object(
return KERN_INVALID_RIGHT;
}
- *typep = (unsigned int) ip_kotype(port);
- *addrp = (vm_offset_t) port->ip_kobject;
+ *typep = ip_kotype(port);
+ *addrp = port->ip_kobject;
ip_unlock(port);
return KERN_SUCCESS;
}
diff --git a/ipc/mach_msg.c b/ipc/mach_msg.c
index 00ab085b..fe0c43e3 100644
--- a/ipc/mach_msg.c
+++ b/ipc/mach_msg.c
@@ -46,6 +46,7 @@
#include <kern/printf.h>
#include <kern/sched_prim.h>
#include <kern/ipc_sched.h>
+#include <kern/exception.h>
#include <vm/vm_map.h>
#include <ipc/ipc_kmsg.h>
#include <ipc/ipc_marequest.h>
@@ -61,9 +62,6 @@
#include <machine/locore.h>
#include <machine/pcb.h>
-extern void exception_raise_continue();
-extern void exception_raise_continue_fast();
-
/*
* Routine: mach_msg_send
* Purpose:
@@ -90,12 +88,12 @@ extern void exception_raise_continue_fast();
*/
mach_msg_return_t
-mach_msg_send(msg, option, send_size, time_out, notify)
- mach_msg_header_t *msg;
- mach_msg_option_t option;
- mach_msg_size_t send_size;
- mach_msg_timeout_t time_out;
- mach_port_t notify;
+mach_msg_send(
+ mach_msg_header_t *msg,
+ mach_msg_option_t option,
+ mach_msg_size_t send_size,
+ mach_msg_timeout_t time_out,
+ mach_port_t notify)
{
ipc_space_t space = current_space();
vm_map_t map = current_map();
@@ -172,13 +170,13 @@ mach_msg_send(msg, option, send_size, time_out, notify)
*/
mach_msg_return_t
-mach_msg_receive(msg, option, rcv_size, rcv_name, time_out, notify)
- mach_msg_header_t *msg;
- mach_msg_option_t option;
- mach_msg_size_t rcv_size;
- mach_port_t rcv_name;
- mach_msg_timeout_t time_out;
- mach_port_t notify;
+mach_msg_receive(
+ mach_msg_header_t *msg,
+ mach_msg_option_t option,
+ mach_msg_size_t rcv_size,
+ mach_port_t rcv_name,
+ mach_msg_timeout_t time_out,
+ mach_port_t notify)
{
ipc_thread_t self = current_thread();
ipc_space_t space = current_space();
@@ -381,26 +379,26 @@ mach_msg_receive_continue(void)
*/
mach_msg_return_t
-mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
- mach_msg_header_t *msg;
- mach_msg_option_t option;
- mach_msg_size_t send_size;
- mach_msg_size_t rcv_size;
- mach_port_t rcv_name;
- mach_msg_timeout_t time_out;
- mach_port_t notify;
+mach_msg_trap(
+ mach_msg_header_t *msg,
+ mach_msg_option_t option,
+ mach_msg_size_t send_size,
+ mach_msg_size_t rcv_size,
+ mach_port_t rcv_name,
+ mach_msg_timeout_t time_out,
+ mach_port_t notify)
{
mach_msg_return_t mr;
/* first check for common cases */
if (option == (MACH_SEND_MSG|MACH_RCV_MSG)) {
- register ipc_thread_t self = current_thread();
+ ipc_thread_t self = current_thread();
ipc_space_t space = self->task->itk_space;
- register ipc_kmsg_t kmsg;
- register ipc_port_t dest_port;
+ ipc_kmsg_t kmsg;
+ ipc_port_t dest_port;
ipc_object_t rcv_object;
- register ipc_mqueue_t rcv_mqueue;
+ ipc_mqueue_t rcv_mqueue;
mach_msg_size_t reply_size;
/*
@@ -484,85 +482,38 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
switch (kmsg->ikm_header.msgh_bits) {
case MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND,
MACH_MSG_TYPE_MAKE_SEND_ONCE): {
- register ipc_entry_t table;
- register ipc_entry_num_t size;
- register ipc_port_t reply_port;
-
- /* sending a request message */
-
+ ipc_port_t reply_port;
{
- register mach_port_index_t index;
- register mach_port_gen_t gen;
-
- {
- register mach_port_t reply_name =
+ mach_port_t reply_name =
kmsg->ikm_header.msgh_local_port;
if (reply_name != rcv_name)
goto slow_copyin;
- /* optimized ipc_entry_lookup of reply_name */
-
- index = MACH_PORT_INDEX(reply_name);
- gen = MACH_PORT_GEN(reply_name);
- }
-
is_read_lock(space);
assert(space->is_active);
- size = space->is_table_size;
- table = space->is_table;
-
- if (index >= size)
- goto abort_request_copyin;
-
- {
- register ipc_entry_t entry;
- register ipc_entry_bits_t bits;
-
- entry = &table[index];
- bits = entry->ie_bits;
-
- /* check generation number and type bit */
-
- if ((bits & (IE_BITS_GEN_MASK|
- MACH_PORT_TYPE_RECEIVE)) !=
- (gen | MACH_PORT_TYPE_RECEIVE))
+ ipc_entry_t entry;
+ entry = ipc_entry_lookup (space, reply_name);
+ if (entry == IE_NULL)
goto abort_request_copyin;
-
reply_port = (ipc_port_t) entry->ie_object;
assert(reply_port != IP_NULL);
}
- }
-
- /* optimized ipc_entry_lookup of dest_name */
-
- {
- register mach_port_index_t index;
- register mach_port_gen_t gen;
{
- register mach_port_t dest_name =
+ mach_port_t dest_name =
kmsg->ikm_header.msgh_remote_port;
- index = MACH_PORT_INDEX(dest_name);
- gen = MACH_PORT_GEN(dest_name);
- }
-
- if (index >= size)
+ ipc_entry_t entry;
+ ipc_entry_bits_t bits;
+ entry = ipc_entry_lookup (space, dest_name);
+ if (entry == IE_NULL)
goto abort_request_copyin;
-
- {
- register ipc_entry_t entry;
- register ipc_entry_bits_t bits;
-
- entry = &table[index];
bits = entry->ie_bits;
- /* check generation number and type bit */
-
- if ((bits & (IE_BITS_GEN_MASK|MACH_PORT_TYPE_SEND)) !=
- (gen | MACH_PORT_TYPE_SEND))
+ /* check type bits */
+ if (IE_BITS_TYPE (bits) != MACH_PORT_TYPE_SEND)
goto abort_request_copyin;
assert(IE_BITS_UREFS(bits) > 0);
@@ -570,7 +521,6 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
dest_port = (ipc_port_t) entry->ie_object;
assert(dest_port != IP_NULL);
}
- }
/*
* To do an atomic copyin, need simultaneous
@@ -651,13 +601,10 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
}
case MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE, 0): {
- register ipc_entry_num_t size;
- register ipc_entry_t table;
-
/* sending a reply message */
{
- register mach_port_t reply_name =
+ mach_port_t reply_name =
kmsg->ikm_header.msgh_local_port;
if (reply_name != MACH_PORT_NULL)
@@ -667,35 +614,18 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
is_write_lock(space);
assert(space->is_active);
- /* optimized ipc_entry_lookup */
-
- size = space->is_table_size;
- table = space->is_table;
-
- {
- register ipc_entry_t entry;
- register mach_port_gen_t gen;
- register mach_port_index_t index;
-
{
- register mach_port_t dest_name =
+ ipc_entry_t entry;
+ mach_port_t dest_name =
kmsg->ikm_header.msgh_remote_port;
- index = MACH_PORT_INDEX(dest_name);
- gen = MACH_PORT_GEN(dest_name);
- }
-
- if (index >= size)
+ entry = ipc_entry_lookup (space, dest_name);
+ if (entry == IE_NULL)
goto abort_reply_dest_copyin;
- entry = &table[index];
-
- /* check generation, collision bit, and type bit */
-
- if ((entry->ie_bits & (IE_BITS_GEN_MASK|
- IE_BITS_COLLISION|
- MACH_PORT_TYPE_SEND_ONCE)) !=
- (gen | MACH_PORT_TYPE_SEND_ONCE))
+ /* check type bits */
+ if (IE_BITS_TYPE (entry->ie_bits) !=
+ MACH_PORT_TYPE_SEND_ONCE)
goto abort_reply_dest_copyin;
/* optimized ipc_right_copyin */
@@ -718,13 +648,8 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
}
assert(dest_port->ip_sorights > 0);
-
- /* optimized ipc_entry_dealloc */
-
- entry->ie_next = table->ie_next;
- table->ie_next = index;
- entry->ie_bits = gen;
entry->ie_object = IO_NULL;
+ ipc_entry_dealloc (space, dest_name, entry);
}
kmsg->ikm_header.msgh_bits =
@@ -737,35 +662,20 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
assert(dest_port->ip_receiver != ipc_space_kernel);
- /* optimized ipc_entry_lookup/ipc_mqueue_copyin */
-
- {
- register ipc_entry_t entry;
- register ipc_entry_bits_t bits;
+ /* optimized ipc_mqueue_copyin */
{
- register mach_port_index_t index;
- register mach_port_gen_t gen;
-
- index = MACH_PORT_INDEX(rcv_name);
- gen = MACH_PORT_GEN(rcv_name);
-
- if (index >= size)
+ ipc_entry_t entry;
+ ipc_entry_bits_t bits;
+ entry = ipc_entry_lookup (space, rcv_name);
+ if (entry == IE_NULL)
goto abort_reply_rcv_copyin;
-
- entry = &table[index];
bits = entry->ie_bits;
- /* check generation number */
-
- if ((bits & IE_BITS_GEN_MASK) != gen)
- goto abort_reply_rcv_copyin;
- }
-
/* check type bits; looking for receive or set */
if (bits & MACH_PORT_TYPE_PORT_SET) {
- register ipc_pset_t rcv_pset;
+ ipc_pset_t rcv_pset;
rcv_pset = (ipc_pset_t) entry->ie_object;
assert(rcv_pset != IPS_NULL);
@@ -776,7 +686,7 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
rcv_object = (ipc_object_t) rcv_pset;
rcv_mqueue = &rcv_pset->ips_messages;
} else if (bits & MACH_PORT_TYPE_RECEIVE) {
- register ipc_port_t rcv_port;
+ ipc_port_t rcv_port;
rcv_port = (ipc_port_t) entry->ie_object;
assert(rcv_port != IP_NULL);
@@ -841,11 +751,11 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
MACH_MSGH_BITS_CIRCULAR) == 0);
{
- register ipc_mqueue_t dest_mqueue;
- register ipc_thread_t receiver;
+ ipc_mqueue_t dest_mqueue;
+ ipc_thread_t receiver;
{
- register ipc_pset_t dest_pset;
+ ipc_pset_t dest_pset;
dest_pset = dest_port->ip_pset;
if (dest_pset == IPS_NULL)
@@ -1043,6 +953,7 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
ipc_port_t reply_port =
(ipc_port_t) kmsg->ikm_header.msgh_local_port;
mach_port_t dest_name, reply_name;
+ unsigned long payload;
/* receiving a request message */
@@ -1074,30 +985,19 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
ip_unlock(reply_port);
{
- register ipc_entry_t table;
- register ipc_entry_t entry;
- register mach_port_index_t index;
-
- /* optimized ipc_entry_get */
-
- table = space->is_table;
- index = table->ie_next;
-
- if (index == 0)
+ ipc_entry_t entry;
+ kern_return_t kr;
+ kr = ipc_entry_get (space, &reply_name, &entry);
+ if (kr)
goto abort_request_copyout;
-
- entry = &table[index];
- table->ie_next = entry->ie_next;
- entry->ie_request = 0;
+ assert (entry != NULL);
{
- register mach_port_gen_t gen;
+ mach_port_gen_t gen;
assert((entry->ie_bits &~ IE_BITS_GEN_MASK) == 0);
gen = entry->ie_bits + IE_BITS_GEN_ONE;
- reply_name = MACH_PORT_MAKE(index, gen);
-
/* optimized ipc_right_copyout */
entry->ie_bits = gen | (MACH_PORT_TYPE_SEND_ONCE | 1);
@@ -1117,6 +1017,7 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
dest_name = dest_port->ip_receiver_name;
else
dest_name = MACH_PORT_NULL;
+ payload = dest_port->ip_protected_payload;
if ((--dest_port->ip_srights == 0) &&
(dest_port->ip_nsrequest != IP_NULL)) {
@@ -1134,11 +1035,19 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
} else
ip_unlock(dest_port);
- kmsg->ikm_header.msgh_bits =
- MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE,
- MACH_MSG_TYPE_PORT_SEND);
+ if (! ipc_port_flag_protected_payload(dest_port)) {
+ kmsg->ikm_header.msgh_bits = MACH_MSGH_BITS(
+ MACH_MSG_TYPE_PORT_SEND_ONCE,
+ MACH_MSG_TYPE_PORT_SEND);
+ kmsg->ikm_header.msgh_local_port = dest_name;
+ } else {
+ kmsg->ikm_header.msgh_bits = MACH_MSGH_BITS(
+ MACH_MSG_TYPE_PORT_SEND_ONCE,
+ MACH_MSG_TYPE_PROTECTED_PAYLOAD);
+ kmsg->ikm_header.msgh_protected_payload =
+ payload;
+ }
kmsg->ikm_header.msgh_remote_port = reply_name;
- kmsg->ikm_header.msgh_local_port = dest_name;
goto fast_put;
abort_request_copyout:
@@ -1148,7 +1057,8 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
}
case MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, 0): {
- register mach_port_t dest_name;
+ mach_port_t dest_name;
+ unsigned long payload;
/* receiving a reply message */
@@ -1160,6 +1070,8 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
assert(dest_port->ip_sorights > 0);
+ payload = dest_port->ip_protected_payload;
+
if (dest_port->ip_receiver == space) {
ip_release(dest_port);
dest_port->ip_sorights--;
@@ -1172,17 +1084,26 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
dest_name = MACH_PORT_NULL;
}
- kmsg->ikm_header.msgh_bits =
- MACH_MSGH_BITS(0,
- MACH_MSG_TYPE_PORT_SEND_ONCE);
+ if (! ipc_port_flag_protected_payload(dest_port)) {
+ kmsg->ikm_header.msgh_bits = MACH_MSGH_BITS(
+ 0,
+ MACH_MSG_TYPE_PORT_SEND_ONCE);
+ kmsg->ikm_header.msgh_local_port = dest_name;
+ } else {
+ kmsg->ikm_header.msgh_bits = MACH_MSGH_BITS(
+ 0,
+ MACH_MSG_TYPE_PROTECTED_PAYLOAD);
+ kmsg->ikm_header.msgh_protected_payload =
+ payload;
+ }
kmsg->ikm_header.msgh_remote_port = MACH_PORT_NULL;
- kmsg->ikm_header.msgh_local_port = dest_name;
goto fast_put;
}
case MACH_MSGH_BITS_COMPLEX|
MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, 0): {
- register mach_port_t dest_name;
+ mach_port_t dest_name;
+ unsigned long payload;
/* receiving a complex reply message */
@@ -1194,6 +1115,8 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
assert(dest_port->ip_sorights > 0);
+ payload = dest_port->ip_protected_payload;
+
if (dest_port->ip_receiver == space) {
ip_release(dest_port);
dest_port->ip_sorights--;
@@ -1206,12 +1129,23 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
dest_name = MACH_PORT_NULL;
}
- kmsg->ikm_header.msgh_bits =
- MACH_MSGH_BITS_COMPLEX |
- MACH_MSGH_BITS(0,
- MACH_MSG_TYPE_PORT_SEND_ONCE);
+ if (! ipc_port_flag_protected_payload(dest_port)) {
+ kmsg->ikm_header.msgh_bits =
+ MACH_MSGH_BITS_COMPLEX
+ | MACH_MSGH_BITS(
+ 0,
+ MACH_MSG_TYPE_PORT_SEND_ONCE);
+ kmsg->ikm_header.msgh_local_port = dest_name;
+ } else {
+ kmsg->ikm_header.msgh_bits =
+ MACH_MSGH_BITS_COMPLEX
+ | MACH_MSGH_BITS(
+ 0,
+ MACH_MSG_TYPE_PROTECTED_PAYLOAD);
+ kmsg->ikm_header.msgh_protected_payload =
+ payload;
+ }
kmsg->ikm_header.msgh_remote_port = MACH_PORT_NULL;
- kmsg->ikm_header.msgh_local_port = dest_name;
mr = ipc_kmsg_copyout_body(
(vm_offset_t) (&kmsg->ikm_header + 1),
@@ -1322,7 +1256,7 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
* It will work if this is a request message.
*/
- register ipc_port_t reply_port;
+ ipc_port_t reply_port;
reply_port = (ipc_port_t)
kmsg->ikm_header.msgh_local_port;
@@ -1357,7 +1291,7 @@ mach_msg_trap(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
*/
{
- register ipc_port_t reply_port;
+ ipc_port_t reply_port;
/*
* Perform the kernel function.
@@ -1735,8 +1669,7 @@ mach_msg_continue(void)
*/
boolean_t
-mach_msg_interrupt(thread)
- thread_t thread;
+mach_msg_interrupt(thread_t thread)
{
ipc_mqueue_t mqueue;
diff --git a/ipc/mach_port.c b/ipc/mach_port.c
index d0310b55..93a1248f 100644
--- a/ipc/mach_port.c
+++ b/ipc/mach_port.c
@@ -150,10 +150,6 @@ mach_port_names(
mach_port_type_t **typesp,
mach_msg_type_number_t *typesCnt)
{
- ipc_tree_entry_t tentry;
- ipc_entry_t table;
- ipc_entry_num_t tsize;
- mach_port_index_t index;
ipc_entry_num_t actual; /* this many names */
ipc_port_timestamp_t timestamp; /* logical time of this operation */
mach_port_t *names;
@@ -190,7 +186,7 @@ mach_port_names(
/* upper bound on number of names in the space */
- bound = space->is_table_size + space->is_tree_total;
+ bound = space->is_size;
size_needed = round_page(bound * sizeof(mach_port_t));
if (size_needed <= size)
@@ -235,33 +231,16 @@ mach_port_names(
timestamp = ipc_port_timestamp();
- table = space->is_table;
- tsize = space->is_table_size;
-
- for (index = 0; index < tsize; index++) {
- ipc_entry_t entry = &table[index];
+ ipc_entry_t entry;
+ struct rdxtree_iter iter;
+ rdxtree_for_each(&space->is_map, &iter, entry) {
ipc_entry_bits_t bits = entry->ie_bits;
if (IE_BITS_TYPE(bits) != MACH_PORT_TYPE_NONE) {
- mach_port_t name = MACH_PORT_MAKEB(index, bits);
-
- mach_port_names_helper(timestamp, entry, name,
+ mach_port_names_helper(timestamp, entry, entry->ie_name,
names, types, &actual);
}
}
-
- for (tentry = ipc_splay_traverse_start(&space->is_tree);
- tentry != ITE_NULL;
- tentry = ipc_splay_traverse_next(&space->is_tree, FALSE)) {
- ipc_entry_t entry = &tentry->ite_entry;
- mach_port_t name = tentry->ite_name;
-
- assert(IE_BITS_TYPE(tentry->ite_bits) != MACH_PORT_TYPE_NONE);
-
- mach_port_names_helper(timestamp, entry, name,
- names, types, &actual);
- }
- ipc_splay_traverse_finish(&space->is_tree);
is_read_unlock(space);
if (actual == 0) {
@@ -434,10 +413,10 @@ mach_port_rename(
*/
kern_return_t
-mach_port_allocate_name(space, right, name)
- ipc_space_t space;
- mach_port_right_t right;
- mach_port_t name;
+mach_port_allocate_name(
+ ipc_space_t space,
+ mach_port_right_t right,
+ mach_port_t name)
{
kern_return_t kr;
@@ -497,10 +476,10 @@ mach_port_allocate_name(space, right, name)
*/
kern_return_t
-mach_port_allocate(space, right, namep)
- ipc_space_t space;
- mach_port_right_t right;
- mach_port_t *namep;
+mach_port_allocate(
+ ipc_space_t space,
+ mach_port_right_t right,
+ mach_port_t *namep)
{
kern_return_t kr;
@@ -555,7 +534,7 @@ mach_port_allocate(space, right, namep)
* KERN_INVALID_NAME The name doesn't denote a right.
*/
-static volatile int mach_port_deallocate_debug = 0;
+static volatile boolean_t mach_port_deallocate_debug = FALSE;
kern_return_t
mach_port_destroy(
@@ -570,8 +549,8 @@ mach_port_destroy(
kr = ipc_right_lookup_write(space, name, &entry);
if (kr != KERN_SUCCESS) {
- if (name != MACH_PORT_NULL && name != MACH_PORT_DEAD && space == current_space()) {
- printf("task %p destroying an invalid port %lu, most probably a bug.\n", current_task(), name);
+ if (MACH_PORT_VALID (name) && space == current_space()) {
+ printf("task %.*s destroying a bogus port %lu, most probably a bug.\n", sizeof current_task()->name, current_task()->name, name);
if (mach_port_deallocate_debug)
SoftDebugger("mach_port_deallocate");
}
@@ -614,8 +593,8 @@ mach_port_deallocate(
kr = ipc_right_lookup_write(space, name, &entry);
if (kr != KERN_SUCCESS) {
- if (name != MACH_PORT_NULL && name != MACH_PORT_DEAD && space == current_space()) {
- printf("task %p deallocating an invalid port %lu, most probably a bug.\n", current_task(), name);
+ if (MACH_PORT_VALID (name) && space == current_space()) {
+ printf("task %.*s deallocating a bogus port %lu, most probably a bug.\n", sizeof current_task()->name, current_task()->name, name);
if (mach_port_deallocate_debug)
SoftDebugger("mach_port_deallocate");
}
@@ -735,8 +714,19 @@ mach_port_mod_refs(
return KERN_INVALID_VALUE;
kr = ipc_right_lookup_write(space, name, &entry);
- if (kr != KERN_SUCCESS)
+ if (kr != KERN_SUCCESS) {
+ if (MACH_PORT_VALID (name) && space == current_space()) {
+ printf("task %.*s %screasing a bogus port "
+ "%lu by %d, most probably a bug.\n",
+ sizeof current_task()->name,
+ current_task()->name,
+ delta < 0 ? "de" : "in", name,
+ delta < 0 ? -delta : delta);
+ if (mach_port_deallocate_debug)
+ SoftDebugger("mach_port_mod_refs");
+ }
return kr;
+ }
/* space is write-locked and active */
kr = ipc_right_delta(space, name, entry, right, delta); /* unlocks */
@@ -744,48 +734,6 @@ mach_port_mod_refs(
}
/*
- * Routine: old_mach_port_get_receive_status [kernel call]
- * Purpose:
- * Compatibility for code written before sequence numbers.
- * Retrieves mucho info about a receive right.
- * Conditions:
- * Nothing locked.
- * Returns:
- * KERN_SUCCESS Retrieved status.
- * KERN_INVALID_TASK The space is null.
- * KERN_INVALID_TASK The space is dead.
- * KERN_INVALID_NAME The name doesn't denote a right.
- * KERN_INVALID_RIGHT Name doesn't denote receive rights.
- */
-
-kern_return_t
-mach_port_get_receive_status(ipc_space_t, mach_port_t, mach_port_status_t *);
-kern_return_t
-old_mach_port_get_receive_status(space, name, statusp)
- ipc_space_t space;
- mach_port_t name;
- old_mach_port_status_t *statusp;
-{
- mach_port_status_t status;
- kern_return_t kr;
-
- kr = mach_port_get_receive_status(space, name, &status);
- if (kr != KERN_SUCCESS)
- return kr;
-
- statusp->mps_pset = status.mps_pset;
- statusp->mps_mscount = status.mps_mscount;
- statusp->mps_qlimit = status.mps_qlimit;
- statusp->mps_msgcount = status.mps_msgcount;
- statusp->mps_sorights = status.mps_sorights;
- statusp->mps_srights = status.mps_srights;
- statusp->mps_pdrequest = status.mps_pdrequest;
- statusp->mps_nsrequest = status.mps_nsrequest;
-
- return KERN_SUCCESS;
-}
-
-/*
* Routine: mach_port_set_qlimit [kernel call]
* Purpose:
* Changes a receive right's queue limit.
@@ -803,10 +751,10 @@ old_mach_port_get_receive_status(space, name, statusp)
*/
kern_return_t
-mach_port_set_qlimit(space, name, qlimit)
- ipc_space_t space;
- mach_port_t name;
- mach_port_msgcount_t qlimit;
+mach_port_set_qlimit(
+ ipc_space_t space,
+ mach_port_t name,
+ mach_port_msgcount_t qlimit)
{
ipc_port_t port;
kern_return_t kr;
@@ -977,10 +925,7 @@ mach_port_get_set_status(
size = PAGE_SIZE; /* initial guess */
for (;;) {
- ipc_tree_entry_t tentry;
- ipc_entry_t entry, table;
- ipc_entry_num_t tsize;
- mach_port_index_t index;
+ ipc_entry_t entry;
mach_port_t *names;
ipc_pset_t pset;
@@ -1017,11 +962,9 @@ mach_port_get_set_status(
maxnames = size / sizeof(mach_port_t);
actual = 0;
- table = space->is_table;
- tsize = space->is_table_size;
-
- for (index = 0; index < tsize; index++) {
- ipc_entry_t ientry = &table[index];
+ ipc_entry_t ientry;
+ struct rdxtree_iter iter;
+ rdxtree_for_each(&space->is_map, &iter, ientry) {
ipc_entry_bits_t bits = ientry->ie_bits;
if (bits & MACH_PORT_TYPE_RECEIVE) {
@@ -1033,22 +976,6 @@ mach_port_get_set_status(
}
}
- for (tentry = ipc_splay_traverse_start(&space->is_tree);
- tentry != ITE_NULL;
- tentry = ipc_splay_traverse_next(&space->is_tree,FALSE)) {
- ipc_entry_bits_t bits = tentry->ite_bits;
-
- assert(IE_BITS_TYPE(bits) != MACH_PORT_TYPE_NONE);
-
- if (bits & MACH_PORT_TYPE_RECEIVE) {
- ipc_port_t port =
- (ipc_port_t) tentry->ite_object;
-
- mach_port_gst_helper(pset, port, maxnames,
- names, &actual);
- }
- }
- ipc_splay_traverse_finish(&space->is_tree);
is_read_unlock(space);
if (actual <= maxnames)
@@ -1367,10 +1294,10 @@ mach_port_extract_right(
*/
kern_return_t
-mach_port_get_receive_status(space, name, statusp)
- ipc_space_t space;
- mach_port_t name;
- mach_port_status_t *statusp;
+mach_port_get_receive_status(
+ ipc_space_t space,
+ mach_port_t name,
+ mach_port_status_t *statusp)
{
ipc_port_t port;
kern_return_t kr;
@@ -1421,11 +1348,11 @@ mach_port_get_receive_status(space, name, statusp)
#ifdef MIGRATING_THREADS
kern_return_t
-mach_port_set_rpcinfo(space, name, rpc_info, rpc_info_count)
- ipc_space_t space;
- mach_port_t name;
- void *rpc_info;
- unsigned int rpc_info_count;
+mach_port_set_rpcinfo(
+ ipc_space_t space,
+ mach_port_t name,
+ void *rpc_info,
+ unsigned int rpc_info_count)
{
ipc_target_t target;
ipc_object_t object;
@@ -1459,19 +1386,19 @@ mach_port_set_rpcinfo(space, name, rpc_info, rpc_info_count)
int sacts, maxsacts;
#endif
-sact_count()
+void sact_count(void)
{
printf("%d server activations in use, %d max\n", sacts, maxsacts);
}
kern_return_t
-mach_port_create_act(task, name, user_stack, user_rbuf, user_rbuf_size, out_act)
- task_t task;
- mach_port_t name;
- vm_offset_t user_stack;
- vm_offset_t user_rbuf;
- vm_size_t user_rbuf_size;
- Act **out_act;
+mach_port_create_act(
+ task_t task,
+ mach_port_t name,
+ vm_offset_t user_stack,
+ vm_offset_t user_rbuf,
+ vm_size_t user_rbuf_size,
+ Act **out_act)
{
ipc_target_t target;
ipc_space_t space;
@@ -1538,12 +1465,11 @@ mach_port_create_act(task, name, user_stack, user_rbuf, user_rbuf_size, out_act)
#ifdef RPCKERNELSIG
kern_return_t
-mach_port_set_syscall_right(task, name)
- task_t task;
- mach_port_t name;
+mach_port_set_syscall_right(
+ task_t task,
+ mach_port_t name)
{
ipc_entry_t entry;
- ipc_port_t port;
kern_return_t kr;
if (task == IS_NULL)
@@ -1567,3 +1493,76 @@ mach_port_set_syscall_right(task, name)
}
#endif
#endif /* MIGRATING_THREADS */
+
+/*
+ * Routine: mach_port_set_protected_payload [kernel call]
+ * Purpose:
+ * Changes a receive right's protected payload.
+ * Conditions:
+ * Nothing locked.
+ * Returns:
+ * KERN_SUCCESS Set protected payload.
+ * KERN_INVALID_TASK The space is null.
+ * KERN_INVALID_TASK The space is dead.
+ * KERN_INVALID_NAME The name doesn't denote a right.
+ * KERN_INVALID_RIGHT Name doesn't denote receive rights.
+ */
+
+kern_return_t
+mach_port_set_protected_payload(
+ ipc_space_t space,
+ mach_port_t name,
+ unsigned long payload)
+{
+ ipc_port_t port;
+ kern_return_t kr;
+
+ if (space == IS_NULL)
+ return KERN_INVALID_TASK;
+
+ kr = ipc_port_translate_receive(space, name, &port);
+ if (kr != KERN_SUCCESS)
+ return kr;
+ /* port is locked and active */
+
+ ipc_port_set_protected_payload(port, payload);
+
+ ip_unlock(port);
+ return KERN_SUCCESS;
+}
+
+/*
+ * Routine: mach_port_clear_protected_payload [kernel call]
+ * Purpose:
+ * Clears a receive right's protected payload.
+ * Conditions:
+ * Nothing locked.
+ * Returns:
+ * KERN_SUCCESS Clear protected payload.
+ * KERN_INVALID_TASK The space is null.
+ * KERN_INVALID_TASK The space is dead.
+ * KERN_INVALID_NAME The name doesn't denote a right.
+ * KERN_INVALID_RIGHT Name doesn't denote receive rights.
+ */
+
+kern_return_t
+mach_port_clear_protected_payload(
+ ipc_space_t space,
+ mach_port_t name)
+{
+ ipc_port_t port;
+ kern_return_t kr;
+
+ if (space == IS_NULL)
+ return KERN_INVALID_TASK;
+
+ kr = ipc_port_translate_receive(space, name, &port);
+ if (kr != KERN_SUCCESS)
+ return kr;
+ /* port is locked and active */
+
+ ipc_port_clear_protected_payload(port);
+
+ ip_unlock(port);
+ return KERN_SUCCESS;
+}
diff --git a/ipc/mach_port.h b/ipc/mach_port.h
index a82228fe..c4d9a1c3 100644
--- a/ipc/mach_port.h
+++ b/ipc/mach_port.h
@@ -43,6 +43,11 @@ mach_port_allocate (
mach_port_t *namep);
extern kern_return_t
+mach_port_destroy(
+ ipc_space_t space,
+ mach_port_t name);
+
+extern kern_return_t
mach_port_deallocate(
ipc_space_t space,
mach_port_t name);
@@ -54,4 +59,10 @@ mach_port_insert_right(
ipc_port_t poly,
mach_msg_type_name_t polyPoly);
+kern_return_t
+mach_port_get_receive_status(
+ ipc_space_t space,
+ mach_port_t name,
+ mach_port_status_t *statusp);
+
#endif /* _IPC_MACH_PORT_H_ */
diff --git a/ipc/mach_rpc.c b/ipc/mach_rpc.c
index 7f5b2eb2..6ca46cc9 100644
--- a/ipc/mach_rpc.c
+++ b/ipc/mach_rpc.c
@@ -58,9 +58,10 @@
* info to the other side.
*/
kern_return_t
-mach_port_rpc_copy(portp, sact, dact)
- struct rpc_port_desc *portp;
- struct Act *sact, *dact;
+mach_port_rpc_copy(
+ struct rpc_port_desc *portp,
+ struct Act *sact,
+ struct Act *dact)
{
ipc_space_t sspace, dspace;
mach_msg_type_name_t tname;
@@ -141,7 +142,7 @@ mach_port_rpc_copy(portp, sact, dact)
}
kern_return_t
-mach_port_rpc_sig(space, name, buffer, buflen)
+mach_port_rpc_sig(const ipc_space_t space, const char *name, const char *buffer, unsigned int buflen)
{
return KERN_FAILURE;
}
diff --git a/ipc/notify.defs b/ipc/notify.defs
new file mode 100644
index 00000000..db059b8d
--- /dev/null
+++ b/ipc/notify.defs
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2015 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* We use custom functions to send notifications. These functions can
+ be found in `ipc_notify.c'. We use this file merely to produce the
+ list of message ids. */
+
+#include <mach/notify.defs>
diff --git a/ipc/port.h b/ipc/port.h
index 6e9f77b4..49af6e2c 100644
--- a/ipc/port.h
+++ b/ipc/port.h
@@ -29,7 +29,7 @@
/*
*/
/*
- * File: ipc/ipc_port.h
+ * File: ipc/port.h
* Author: Rich Draves
* Date: 1989
*
@@ -45,10 +45,7 @@
* mach_port_t must be an unsigned type. Port values
* have two parts, a generation number and an index.
* These macros encapsulate all knowledge of how
- * a mach_port_t is layed out. However, ipc/ipc_entry.c
- * implicitly assumes when it uses the splay tree functions
- * that the generation number is in the low bits, so that
- * names are ordered first by index and then by generation.
+ * a mach_port_t is laid out.
*
* If the size of generation numbers changes,
* be sure to update IE_BITS_GEN_MASK and friends