Subject: Re: realloc
To: Jason Thorpe <>
From: Chris G Demetriou <>
List: tech-kern
Date: 06/04/1996 22:13:11
> If it were useful, a real realloc() would be cool, otherwise, writing a 
> macfs_realloc() that does the simple ralloc algorithm might be appropriate.

I decided to write a real realloc(), that does 'the right (and
efficient) thing' with our memory allocator, etc.

It is below.

It was cloned from 'free()', and hacked to suit.

	(1) it compiles on the i386.  i've not tried to run it.
	(2) if allocation fails because M_NOWAIT supplied, doesn't
	    free old block of memory.

I'm sure there are other things to say about it, but i have to leave
to catch a bus right now...  8-)

feel free to debug it, etc.  If the right people think it's
appropriate, I can add it to kern_malloc.c...

 * 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;
	long alloc;

	 * Realloc() with a NULL pointer is the same as malloc().
	 * Realloc() with zero size is the same as free().
	if (curaddr == NULL)
		return (malloc(newsize, type, flags));
	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;

	 * Check for returns of data that do not point to the
	 * beginning of the allocation.
	if (cursize > NBPG * CLSIZE)
		alloc = addrmask[BUCKETINDX(NBPG * CLSIZE)];
		alloc = addrmask[kup->ku_indx];
	if (((u_long)curaddr & alloc) != 0)
		panic("realloc: unaligned addr %p, cursize %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);