Subject: Re: realloc
To: Jason Thorpe <thorpej@nas.nasa.gov>
From: Chris G Demetriou <Chris_G_Demetriou@ux2.sp.cs.cmu.edu>
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.
Notes:
(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...
chris
============================================================================
/*
* 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().
* 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;
#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, 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);
}