Mail Archives: djgpp-workers/2001/05/24/15:02:50
> Please post the patched realloc in its entirety (it is easier to grasp
> that way), including its immediate subroutines that you wrote.
What I have isn't in final form yet but it works.
/* Remove block of memory from the free list. */
static inline void
remove_freelist (BLOCK *b)
{
int bu;
BLOCK *bp, **bpp;
bu = b2bucket (b);
bpp = freelist + bu;
for (bp = freelist[bu]; bp; bpp=&(bp->next), bp=bp->next)
{
if (bp == b)
{
*bpp = bp->next;
break;
}
}
}
/* Insert block of memory into free list. */
static inline void
insert_freelist(BLOCK *block)
{
int bu = b2bucket(block);
block->next = freelist[bu];
freelist[bu] = block;
}
/* Try to increase the size of the allocated block. */
static BLOCK *
realloc_inplace(BLOCK *cur, size_t old_size, size_t new_size)
{
BLOCK *after;
size_t after_sz, alloc_delta;
int split_extra;
after = AFTER(cur);
after_sz = after->size;
new_size = (new_size + (ALIGN-1)) & ~(ALIGN-1);
/* Fail if the block following the one being extended is in use. */
if (after_sz & 1)
return NULL;
/* Size of block increase. */
alloc_delta = new_size - old_size;
/* Fail if the free block is not large enough. */
if (alloc_delta > after_sz)
return NULL;
after->bucket = -1;
/* Is there enough leftover space to form a new block? */
split_extra = (after_sz - alloc_delta >= 16);
if (after == slop)
{
if (split_extra)
slop = split_block(after, alloc_delta);
else
slop = 0;
}
else
{
remove_freelist(after);
if (split_extra)
{
BLOCK *after2 = split_block(after, alloc_delta);
after2->bucket = -1;
insert_freelist(after2);
}
}
cur->size += after->size + 8;
ENDSZ(cur) = cur->size;
return cur;
}
void *
realloc(void *ptr, size_t size)
{
BLOCK *b;
char *newptr;
size_t copysize;
if (ptr == 0)
return malloc(size);
b = (BLOCK *)((char *)ptr-4);
copysize = b->size & ~1;
if (size <= copysize)
{
#if 0
if (copysize < 2*MIN_SAVE_EXTRA
|| (size >= copysize-512 && size >= copysize/2))
#endif
return ptr;
copysize = size;
}
/* Try to increase the size of the allocation. */
if (realloc_inplace (b, copysize, size))
return ptr;
newptr = (char *)malloc(size);
#if DEBUG
printf("realloc %u %u/%08x %08x->%08, %u\n",
size, b->size & ~1, b, ptr, newptr, copysize);
#endif
if (!newptr)
return NULL;
memcpy(newptr, ptr, copysize);
free(ptr);
return newptr;
}
- Raw text -