diff options
Diffstat (limited to 'ipc/ipc_space.c')
-rw-r--r-- | ipc/ipc_space.c | 104 |
1 files changed, 18 insertions, 86 deletions
diff --git a/ipc/ipc_space.c b/ipc/ipc_space.c index dcc96b3..ea3cb3b 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: @@ -102,53 +103,24 @@ ipc_space_create( 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; @@ -202,10 +174,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); @@ -218,60 +186,24 @@ 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); /* |