OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [uClibc/] [libc/] [stdlib/] [malloc/] [realloc.c] - Rev 1771

Go to most recent revision | Compare with Previous | Blame | View Log

/*
 * libc/stdlib/malloc/realloc.c -- realloc function
 *
 *  Copyright (C) 2002  NEC Corporation
 *  Copyright (C) 2002  Miles Bader <miles@gnu.org>
 *
 * This file is subject to the terms and conditions of the GNU Lesser
 * General Public License.  See the file COPYING.LIB in the main
 * directory of this archive for more details.
 * 
 * Written by Miles Bader <miles@gnu.org>
 */
 
#include <stdlib.h>
#include <string.h>
#include <errno.h>
 
#include "malloc.h"
#include "heap.h"
 
 
void *
realloc (void *mem, size_t new_size)
{
  size_t size;
  char *base_mem;
 
  /* Check for special cases.  */
  if (! mem)
    return malloc (new_size);
  if (! new_size)
    {
      free (mem);
      return malloc (new_size);
    }
 
  /* Normal realloc.  */
 
  base_mem = MALLOC_BASE (mem);
  size = MALLOC_SIZE (mem);
 
  /* Include extra space to record the size of the allocated block.
     Also make sure that we're dealing in a multiple of the heap
     allocation unit (SIZE is already guaranteed to be so).*/
  new_size = HEAP_ADJUST_SIZE (new_size + MALLOC_HEADER_SIZE);
 
  MALLOC_DEBUG (1, "realloc: 0x%lx, %d (base = 0x%lx, total_size = %d)",
		(long)mem, new_size, (long)base_mem, size);
 
  if (new_size > size)
    /* Grow the block.  */
    {
      size_t extra = new_size - size;
 
      __heap_lock (&__malloc_heap);
      extra = __heap_alloc_at (&__malloc_heap, base_mem + size, extra);
      __heap_unlock (&__malloc_heap);
 
      if (extra)
	/* Record the changed size.  */
	MALLOC_SET_SIZE (base_mem, size + extra);
      else
	/* Our attempts to extend MEM in place failed, just
	   allocate-and-copy.  */
	{
	  void *new_mem = malloc (new_size - MALLOC_HEADER_SIZE);
	  if (new_mem)
	    {
	      memcpy (new_mem, mem, size - MALLOC_HEADER_SIZE);
	      free (mem);
	    }
	  mem = new_mem;
	}
    }
  else if (new_size + MALLOC_REALLOC_MIN_FREE_SIZE <= size)
    /* Shrink the block.  */
    {
      __heap_lock (&__malloc_heap);
      __heap_free (&__malloc_heap, base_mem + new_size, size - new_size);
      __heap_unlock (&__malloc_heap);
      MALLOC_SET_SIZE (base_mem, new_size);
    }
 
  if (mem)
    MALLOC_DEBUG (-1, "realloc: returning 0x%lx (base:0x%lx, total_size:%d)",
		  (long)mem, (long)MALLOC_BASE(mem), (long)MALLOC_SIZE(mem));
  else
    MALLOC_DEBUG (-1, "realloc: returning 0");
 
  return mem;
}
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.