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 -