--- Gnu-Mach/ipc/ipc_space.c 2020/09/02 04:36:56 1.1 +++ Gnu-Mach/ipc/ipc_space.c 2020/09/02 04:49:46 1.1.1.4 @@ -36,19 +36,16 @@ * Functions to manipulate IPC capability spaces. */ -#include -#include +#include #include #include #include #include #include -#include +#include #include #include -#include -#include #include #include #include @@ -56,12 +53,9 @@ -zone_t ipc_space_zone; +struct kmem_cache ipc_space_cache; ipc_space_t ipc_space_kernel; ipc_space_t ipc_space_reply; -#if NORMA_IPC -ipc_space_t ipc_space_remote; -#endif NORMA_IPC /* * Routine: ipc_space_reference @@ -86,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,83 +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; - -#if MACH_IPC_COMPAT - { - mach_port_t name; - ipc_port_t port; - kern_return_t kr; - - /* - * ipc_port_alloc_compat probably won't look at is_notify, - * but make sure all fields have sane values anyway. - */ - - space->is_notify = IP_NULL; - - kr = ipc_port_alloc_compat(space, &name, &port); - if (kr != KERN_SUCCESS) { - ipc_space_destroy(space); - is_release(space); - return kr; - } - ip_reference(port); - port->ip_srights++; - ip_unlock(port); - space->is_notify = port; - } -#endif MACH_IPC_COMPAT + 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; @@ -232,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); @@ -248,64 +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. - */ - - 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; + ipc_entry_t entry; + struct rdxtree_iter iter; + rdxtree_for_each(&space->is_map, &iter, entry) { + if (entry->ie_name == MACH_PORT_NULL) + continue; - 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); - -#if MACH_IPC_COMPAT - if (IP_VALID(space->is_notify)) - ipc_port_release_send(space->is_notify); -#endif MACH_IPC_COMPAT + rdxtree_remove_all(&space->is_map); + rdxtree_remove_all(&space->is_reverse_map); /* * Because the space is now dead,