From f8ed933394ff0f324edb2d96f66e495f63b5416d Mon Sep 17 00:00:00 2001 From: cgd Date: Tue, 27 Aug 1996 20:01:42 +0000 Subject: [PATCH] implement realloc(), just like the user-land version, except it takes "type" and "flags" arguments a la kernel malloc(). --- sys/kern/kern_malloc.c | 86 +++++++++++++++++++++++++++++++++++++++++- sys/sys/malloc.h | 4 +- 2 files changed, 88 insertions(+), 2 deletions(-) diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c index ade09bd477da..1658f30895b9 100644 --- a/sys/kern/kern_malloc.c +++ b/sys/kern/kern_malloc.c @@ -1,6 +1,7 @@ -/* $NetBSD: kern_malloc.c,v 1.19 1996/08/13 23:25:10 thorpej Exp $ */ +/* $NetBSD: kern_malloc.c,v 1.20 1996/08/27 20:01:42 cgd Exp $ */ /* + * Copyright 1996 Christopher G. Demetriou. All rights reserved. * Copyright (c) 1987, 1991, 1993 * The Regents of the University of California. All rights reserved. * @@ -369,6 +370,89 @@ free(addr, type) splx(s); } +/* + * Change the size of a block of memory. + */ +void * +realloc(curaddr, newsize, type, flags) + void *curaddr; + unsigned long newsize; + int type, flags; +{ + register struct kmemusage *kup; + long cursize; + void *newaddr; +#ifdef DIAGNOSTIC + long alloc; +#endif + + /* + * Realloc() with a NULL pointer is the same as malloc(). + */ + if (curaddr == NULL) + return (malloc(newsize, type, flags)); + + /* + * Realloc() with zero size is the same as free(). + */ + if (newsize == 0) { + free(curaddr, type); + return (NULL); + } + + /* + * Find out how large the old allocation was (and do some + * sanity checking). + */ + kup = btokup(curaddr); + cursize = 1 << kup->ku_indx; + +#ifdef DIAGNOSTIC + /* + * Check for returns of data that do not point to the + * beginning of the allocation. + */ + if (cursize > NBPG * CLSIZE) + alloc = addrmask[BUCKETINDX(NBPG * CLSIZE)]; + else + alloc = addrmask[kup->ku_indx]; + if (((u_long)curaddr & alloc) != 0) + panic("realloc: unaligned addr %p, size %ld, type %s, mask %ld\n", + curaddr, cursize, memname[type], alloc); +#endif /* DIAGNOSTIC */ + + if (cursize > MAXALLOCSAVE) + cursize = ctob(kup->ku_pagecnt); + + /* + * If we already actually have as much as they want, we're done. + */ + if (newsize <= cursize) + return (curaddr); + + /* + * Can't satisfy the allocation with the existing block. + * Allocate a new one and copy the data. + */ + newaddr = malloc(newsize, type, flags); + if (newaddr == NULL) { + /* + * Malloc() failed, because flags included M_NOWAIT. + * Return NULL to indicate that failure. The old + * pointer is still valid. + */ + return NULL; + } + bcopy(curaddr, newaddr, cursize); + + /* + * We were successful: free the old allocation and return + * the new one. + */ + free(curaddr, type); + return (newaddr); +} + /* * Initialize the kernel memory allocator */ diff --git a/sys/sys/malloc.h b/sys/sys/malloc.h index 51c9423554e1..f2dfffc04e3d 100644 --- a/sys/sys/malloc.h +++ b/sys/sys/malloc.h @@ -1,4 +1,4 @@ -/* $NetBSD: malloc.h,v 1.23 1996/04/05 04:52:52 mhitch Exp $ */ +/* $NetBSD: malloc.h,v 1.24 1996/08/27 20:01:51 cgd Exp $ */ /* * Copyright (c) 1987, 1993 @@ -330,5 +330,7 @@ extern char *kmembase; extern struct kmembuckets bucket[]; extern void *malloc __P((unsigned long size, int type, int flags)); extern void free __P((void *addr, int type)); +extern void *realloc __P((void *curaddr, unsigned long newsize, int type, + int flags)); #endif /* _KERNEL */ #endif /* !_SYS_MALLOC_H_ */