kern_return_t host_ipc_hash_info( host_t host, hash_info_bucket_array_t *infop, mach_msg_type_number_t *countp) { vm_map_copy_t copy; vm_offset_t addr; vm_size_t size; hash_info_bucket_t *info; natural_t count; kern_return_t kr; if (host == HOST_NULL) return KERN_INVALID_HOST; /* start with in-line data */ count = ipc_hash_size(); size = round_page(count * sizeof(hash_info_bucket_t)); kr = kmem_alloc_pageable(ipc_kernel_map, &addr, size); if (kr != KERN_SUCCESS) return KERN_RESOURCE_SHORTAGE; info = (hash_info_bucket_t *) addr; count = ipc_hash_info(info, count); if (size > count * sizeof(hash_info_bucket_t)) bzero((char *)&info[count], size - count * sizeof(hash_info_bucket_t)); kr = vm_map_copyin(ipc_kernel_map, (vm_map_address_t)addr, (vm_map_size_t)size, TRUE, ©); assert(kr == KERN_SUCCESS); *infop = (hash_info_bucket_t *) copy; *countp = count; return KERN_SUCCESS; }
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, ©); assert(kr == KERN_SUCCESS); *infop = (hash_info_bucket_t *) copy; *countp = actual; } return KERN_SUCCESS; }