From: "Mark E." To: djgpp-workers AT delorie DOT com Date: Thu, 24 May 2001 15:01:20 -0400 MIME-Version: 1.0 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Subject: Re: ehhanced realloc test program Message-ID: <3B0D2240.25662.FBD929@localhost> References: <3B0BFD5F DOT 25329 DOT 475F21 AT localhost> In-reply-to: X-mailer: Pegasus Mail for Win32 (v3.12c) Reply-To: djgpp-workers AT delorie DOT com > 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; }