-
-void
-krealloc(
- void **addrp,
- vm_size_t old_size,
- vm_size_t new_size,
- simple_lock_t lock)
-{
- register int zindex;
- register vm_size_t allocsize;
- void *naddr;
- vm_map_t alloc_map = VM_MAP_NULL;
-
- /* can only be used for increasing allocation size */
-
- assert(new_size > old_size);
-
- /* if old_size is zero, then we are simply allocating */
-
- if (old_size == 0) {
- simple_unlock(lock);
- naddr = kalloc(new_size);
- simple_lock(lock);
- *addrp = naddr;
- return;
- }
-
- /* if old block was kmem_alloc'd, then use kmem_realloc if necessary */
-
- if (old_size >= kalloc_max_prerounded) {
- if (old_size >= kalloc_kernmap_size)
- alloc_map = kernel_map;
- else
- alloc_map = kalloc_map;
-
- old_size = round_page(old_size);
- new_size = round_page(new_size);
- if (new_size > old_size) {
-
- if (KERN_SUCCESS != kmem_realloc(alloc_map,
- (vm_offset_t)*addrp, old_size,
- (vm_offset_t *)&naddr, new_size))
- panic("krealloc: kmem_realloc");
-
- simple_lock(lock);
- *addrp = (void *) naddr;
-
- /* kmem_realloc() doesn't free old page range. */
- kmem_free(alloc_map, (vm_offset_t)*addrp, old_size);
-
- kalloc_large_total += (new_size - old_size);
-
- if (kalloc_large_total > kalloc_large_max)
- kalloc_large_max = kalloc_large_total;
-
- }
- return;
- }
-
- /* compute the size of the block that we actually allocated */
-
- allocsize = KALLOC_MINSIZE;
- zindex = first_k_zone;
- while (allocsize < old_size) {
- allocsize <<= 1;
- zindex++;
- }
-
- /* if new size fits in old block, then return */
-
- if (new_size <= allocsize) {
- return;
- }
-
- /* if new size does not fit in zone, kmem_alloc it, else zalloc it */
-
- simple_unlock(lock);
- if (new_size >= kalloc_max_prerounded) {
- if (new_size >= kalloc_kernmap_size)
- alloc_map = kernel_map;
- else
- alloc_map = kalloc_map;
- if (KERN_SUCCESS != kmem_alloc(alloc_map,
- (vm_offset_t *)&naddr, new_size)) {
- panic("krealloc: kmem_alloc");
- simple_lock(lock);
- *addrp = NULL;
- return;
- }
- kalloc_large_inuse++;
- kalloc_large_total += new_size;
-
- if (kalloc_large_total > kalloc_large_max)
- kalloc_large_max = kalloc_large_total;
- } else {
- register int new_zindex;
-
- allocsize <<= 1;
- new_zindex = zindex + 1;
- while (allocsize < new_size) {
- allocsize <<= 1;
- new_zindex++;
- }
- naddr = zalloc(k_zone[new_zindex]);
- }
- simple_lock(lock);
-
- /* copy existing data */
-
- bcopy((const char *)*addrp, (char *)naddr, old_size);
-
- /* free old block, and return */
-
- zfree(k_zone[zindex], *addrp);
-
- /* set up new address */
-
- *addrp = (void *) naddr;
-}
-
-
-void *
-kget(
- vm_size_t size)
-{
- register int zindex;
- register vm_size_t allocsize;
-
- /* size must not be too large for a zone */
-
- if (size >= kalloc_max_prerounded) {
- /* This will never work, so we might as well panic */
- panic("kget");
- }
-
- /* compute the size of the block that we will actually allocate */
-
- allocsize = KALLOC_MINSIZE;
- zindex = first_k_zone;
- while (allocsize < size) {
- allocsize <<= 1;
- zindex++;
- }
-
- /* allocate from the appropriate zone */
-
- assert(allocsize < kalloc_max);
- return(zget(k_zone[zindex]));
-}
-