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; *spacep = space; return KERN_SUCCESS; }
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); }