Mail Archives: djgpp-workers/2001/05/27/18:24:27.1
This patch should be done barring any problems discovered during this review.
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/27 22:12:12
*************** malloc(size_t size)
*** 217,228 ****
RET(rv);
}
! static inline BLOCK *
! merge(BLOCK *a, BLOCK *b, BLOCK *c)
{
int bu;
BLOCK *bp, **bpp;
#if DEBUG
printf(" merge %u/%08x + %u/%08x = %u\n",
a->size, a, b->size, b, a->size+b->size+8);
--- 217,262 ----
RET(rv);
}
! /* Remove block of memory from the free list. */
! static inline void
! simple_snip_freelist (BLOCK *b)
{
int bu;
BLOCK *bp, **bpp;
+ bu = b2bucket(b);
+ #if DEBUG
+ printf("bucket for %u/%08x is %d\n", b->size, b, bu);
+ #endif
+ bpp = freelist + bu;
+ for (bp = freelist[bu]; bp; bpp=&(bp->next), bp=bp->next)
+ {
+ #if DEBUG
+ printf(" %08x", bp);
+ #endif
+ if (bp == b)
+ {
+ #if DEBUG
+ printf("\n snipping %u/%08x from freelist[%d]\n", bp->size, bp, bu);
+ #endif
+ *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;
+ }
+
+ static inline BLOCK *
+ merge(BLOCK *a, BLOCK *b, BLOCK *c)
+ {
#if DEBUG
printf(" merge %u/%08x + %u/%08x = %u\n",
a->size, a, b->size, b, a->size+b->size+8);
*************** merge(BLOCK *a, BLOCK *b, BLOCK *c)
*** 238,262 ****
#endif
slop = 0;
}
! bu = b2bucket(c);
! #if DEBUG
! printf("bucket for %u/%08x is %d\n", c->size, c, bu);
! #endif
! bpp = freelist+bu;
! for (bp=freelist[bu]; bp; bpp=&(bp->next), bp=bp->next)
! {
! #if DEBUG
! printf(" %08x", bp);
! #endif
! if (bp == c)
! {
! #if DEBUG
! printf("\n snipping %u/%08x from freelist[%d]\n", bp->size, bp, bu);
! #endif
! *bpp = bp->next;
! break;
! }
! }
CHECK(c);
a->size += b->size + 8;
--- 272,279 ----
#endif
slop = 0;
}
! else
! simple_snip_freelist(c);
CHECK(c);
a->size += b->size + 8;
*************** merge(BLOCK *a, BLOCK *b, BLOCK *c)
*** 270,276 ****
void
free(void *ptr)
{
- int b;
BLOCK *block;
if (ptr == 0)
return;
--- 287,292 ----
*************** free(void *ptr)
*** 309,321 ****
block = merge(block, AFTER(block), AFTER(block));
}
CHECK(block);
!
! b = b2bucket(block);
! block->next = freelist[b];
! freelist[b] = block;
CHECK(block);
}
void *
realloc(void *ptr, size_t size)
{
--- 325,397 ----
block = merge(block, AFTER(block), AFTER(block));
}
CHECK(block);
!
! insert_freelist(block);
CHECK(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 extra_space;
+ char is_slop_ptr;
+
+ 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;
+
+ extra_space = (after_sz - alloc_delta);
+ is_slop_ptr = (after == slop);
+
+ if (!is_slop_ptr)
+ {
+ /* Remove the block from free list. */
+ after->bucket = -1;
+ simple_snip_freelist(after);
+ }
+
+ /* Expand the block by shrinking or mergin
+ with the free block that follows it. */
+ if (extra_space > 8)
+ {
+ /* Take part of the free block (or slop) and
+ give to the block being expanded. */
+ BLOCK *after2 = (BLOCK *)((char *)after + alloc_delta);
+ after2->size = after_sz - alloc_delta;
+ after2->bucket = -1;
+ ENDSZ(after2) = after2->size;
+ cur->size += alloc_delta;
+ ENDSZ(cur) = cur->size;
+ if (is_slop_ptr)
+ slop = after2;
+ else
+ insert_freelist(after2);
+ }
+ else
+ {
+ /* Merge the entire free block with the block being expanded. */
+ cur->size += after_sz + 8;
+ ENDSZ(cur) = cur->size;
+ if (is_slop_ptr)
+ slop = 0;
+ }
+ return cur;
+ }
+
void *
realloc(void *ptr, size_t size)
{
*************** realloc(void *ptr, size_t size)
*** 337,342 ****
--- 413,422 ----
return ptr;
copysize = size;
}
+
+ /* Try to increase the size of the allocation by extending the block. */
+ if (realloc_inplace(b, copysize, size))
+ return ptr;
newptr = (char *)malloc(size);
#if DEBUG
- Raw text -