From: "Mark E." To: djgpp-workers AT delorie DOT com Date: Thu, 17 May 2001 15:17:27 -0400 MIME-Version: 1.0 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Subject: realloc enhancement Message-ID: <3B03EB87.15564.BB69E@localhost> X-mailer: Pegasus Mail for Win32 (v3.12c) Reply-To: djgpp-workers AT delorie DOT com This patch enhances realloc by trying to extend the allocated block before allocating a new one. How does it look? Note that I had to change a word to get this note through. Index: malloc.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/ansi/stdlib/malloc.c,v retrieving revision 1.8 diff -c -p -r1.8 malloc.c *** malloc.c 2001/01/20 04:09:57 1.8 --- malloc.c 2001/05/17 17:26:54 *************** free(void *ptr) *** 316,321 **** --- 316,388 ---- CHECK(block); } + /* delete block of memory from the free list. */ + static inline void + delete_freelist (BLOCK *b) + { + int bu = b2bucket (b); + BLOCK *bp, **bpp; + + bpp = freelist + bu; + for (bp = freelist[bu]; bp; bp = bp->next) + { + if (bp == b) + { + *bpp = bp->next; + break; + } + } + } + + /* Insert block of memory into free list. */ + static inline void + insert_freelist (BLOCK *b) + { + int bu = b2bucket (b); + b->next = freelist[bu]; + freelist[bu] = b; + } + + /* 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, delta; + + after = AFTER(cur); + after_sz = after->size; + + /* Fail if the block following the one being extended is in use. */ + if (after_sz & 1) + return NULL; + + /* Size of block increase. */ + delta = new_size - old_size; + + /* Fail if the free block is not large enough. */ + if (delta > after_sz) + return NULL; + + /* delete block from free list. */ + delete_freelist(after); + + /* Trim extra space from the free block when its large enough + to make a new block. */ + if (after_sz - delta >= 16) + { + BLOCK *after2 = split_block(after, delta + 8); + /* Add trimmed block to free list. */ + insert_freelist(after2); + } + + /* Merge the two blocks. */ + cur->size += after->size + 8; + ENDSZ(cur) = cur->size; + + return cur; + } + void * realloc(void *ptr, size_t size) { *************** realloc(void *ptr, size_t size) *** 337,342 **** --- 404,413 ---- 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