/* Free a block of memory allocated by `mmalloc'.
   Copyright 1990, 1991, 1992 Free Software Foundation

   Written May 1989 by Mike Haertel.
   Heavily modified Mar 1992 by Fred Fish.  (fnf@cygnus.com)

The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.

The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Library General Public License for more details.

You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB.  If
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.

   The author may be reached (Email) at the address mike@ai.mit.edu,
   or (US mail) as Mike Haertel c/o Free Software Foundation. */

#include "mmprivate.h"

/* Return memory to the heap.
   Like `mfree' but don't call a mfree_hook if there is one.  */

void
__mmalloc_free (mdp, ptr)
  struct mdesc *mdp;
  PTR ptr;
{
  int type;
  size_t block, blocks;
  register size_t i;
  struct list *prev, *next;

  block = BLOCK (ptr);

  type = mdp -> heapinfo[block].busy.type;
  switch (type)
    {
    case 0:
      /* Get as many statistics as early as we can.  */
      mdp -> heapstats.chunks_used--;
      mdp -> heapstats.bytes_used -=
	  mdp -> heapinfo[block].busy.info.size * BLOCKSIZE;
      mdp -> heapstats.bytes_free +=
	  mdp -> heapinfo[block].busy.info.size * BLOCKSIZE;

      /* Find the free cluster previous to this one in the free list.
	 Start searching at the last block referenced; this may benefit
	 programs with locality of allocation.  */
      i = mdp -> heapindex;
      if (i > block)
	{
	  while (i > block)
	    {
	      i = mdp -> heapinfo[i].free.prev;
	    }
	}
      else
	{
	  do
	    {
	      i = mdp -> heapinfo[i].free.next;
	    }
	  while ((i != 0) && (i < block));
	  i = mdp -> heapinfo[i].free.prev;
	}

      /* Determine how to link this block into the free list.  */
      if (block == i + mdp -> heapinfo[i].free.size)
	{
	  /* Coalesce this block with its predecessor.  */
	  mdp -> heapinfo[i].free.size +=
	    mdp -> heapinfo[block].busy.info.size;
	  block = i;
	}
      else
	{
	  /* Really link this block back into the free list.  */
	  mdp -> heapinfo[block].free.size =
	    mdp -> heapinfo[block].busy.info.size;
	  mdp -> heapinfo[block].free.next = mdp -> heapinfo[i].free.next;
	  mdp -> heapinfo[block].free.prev = i;
	  mdp -> heapinfo[i].free.next = block;
	  mdp -> heapinfo[mdp -> heapinfo[block].free.next].free.prev = block;
	  mdp -> heapstats.chunks_free++;
	}

      /* Now that the block is linked in, see if we can coalesce it
	 with its successor (by deleting its successor from the list
	 and adding in its size).  */
      if (block + mdp -> heapinfo[block].free.size ==
	  mdp -> heapinfo[block].free.next)
	{
	  mdp -> heapinfo[block].free.size
	    += mdp -> heapinfo[mdp -> heapinfo[block].free.next].free.size;
	  mdp -> heapinfo[block].free.next
	    = mdp -> heapinfo[mdp -> heapinfo[block].free.next].free.next;
	  mdp -> heapinfo[mdp -> heapinfo[block].free.next].free.prev = block;
	  mdp -> heapstats.chunks_free--;
	}

      /* Now see if we can return stuff to the system.  */
      blocks = mdp -> heapinfo[block].free.size;
      if (blocks >= FINAL_FREE_BLOCKS && block + blocks == mdp -> heaplimit
	  && mdp -> morecore (mdp, 0) == ADDRESS (block + blocks))
	{
	  register size_t bytes = blocks * BLOCKSIZE;
	  mdp -> heaplimit -= blocks;
	  mdp -> morecore (mdp, -bytes);
	  mdp -> heapinfo[mdp -> heapinfo[block].free.prev].free.next
	    = mdp -> heapinfo[block].free.next;
	  mdp -> heapinfo[mdp -> heapinfo[block].free.next].free.prev
	    = mdp -> heapinfo[block].free.prev;
	  block = mdp -> heapinfo[block].free.prev;
	  mdp -> heapstats.chunks_free--;
	  mdp -> heapstats.bytes_free -= bytes;
	}

      /* Set the next search to begin at this block.  */
      mdp -> heapindex = block;
      break;

    default:
      /* Do some of the statistics.  */
      mdp -> heapstats.chunks_used--;
      mdp -> heapstats.bytes_used -= 1 << type;
      mdp -> heapstats.chunks_free++;
      mdp -> heapstats.bytes_free += 1 << type;

      /* Get the address of the first free fragment in this block.  */
      prev = (struct list *)
	((char *) ADDRESS(block) +
	 (mdp -> heapinfo[block].busy.info.frag.first << type));

      if (mdp -> heapinfo[block].busy.info.frag.nfree ==
	  (BLOCKSIZE >> type) - 1)
	{
	  /* If all fragments of this block are free, remove them
	     from the fragment list and free the whole block.  */
	  next = prev;
	  for (i = 1; i < (size_t) (BLOCKSIZE >> type); ++i)
	    {
	      next = next -> next;
	    }
	  prev -> prev -> next = next;
	  if (next != NULL)
	    {
	      next -> prev = prev -> prev;
	    }
	  mdp -> heapinfo[block].busy.type = 0;
	  mdp -> heapinfo[block].busy.info.size = 1;

	  /* Keep the statistics accurate.  */
	  mdp -> heapstats.chunks_used++;
	  mdp -> heapstats.bytes_used += BLOCKSIZE;
	  mdp -> heapstats.chunks_free -= BLOCKSIZE >> type;
	  mdp -> heapstats.bytes_free -= BLOCKSIZE;

	  mfree ((PTR) mdp, (PTR) ADDRESS(block));
	}
      else if (mdp -> heapinfo[block].busy.info.frag.nfree != 0)
	{
	  /* If some fragments of this block are free, link this
	     fragment into the fragment list after the first free
	     fragment of this block. */
	  next = (struct list *) ptr;
	  next -> next = prev -> next;
	  next -> prev = prev;
	  prev -> next = next;
	  if (next -> next != NULL)
	    {
	      next -> next -> prev = next;
	    }
	  ++mdp -> heapinfo[block].busy.info.frag.nfree;
	}
      else
	{
	  /* No fragments of this block are free, so link this
	     fragment into the fragment list and announce that
	     it is the first free fragment of this block. */
	  prev = (struct list *) ptr;
	  mdp -> heapinfo[block].busy.info.frag.nfree = 1;
	  mdp -> heapinfo[block].busy.info.frag.first =
	    RESIDUAL (ptr, BLOCKSIZE) >> type;
	  prev -> next = mdp -> fraghead[type].next;
	  prev -> prev = &mdp -> fraghead[type];
	  prev -> prev -> next = prev;
	  if (prev -> next != NULL)
	    {
	      prev -> next -> prev = prev;
	    }
	}
      break;
    }
}

/* Return memory to the heap.  */

void
mfree (md, ptr)
  PTR md;
  PTR ptr;
{
  struct mdesc *mdp;
  register struct alignlist *l;

  if (ptr != NULL)
    {
      mdp = MD_TO_MDP (md);
      for (l = mdp -> aligned_blocks; l != NULL; l = l -> next)
	{
	  if (l -> aligned == ptr)
	    {
	      l -> aligned = NULL;  /* Mark the slot in the list as free. */
	      ptr = l -> exact;
	      break;
	    }
	}      
      if (mdp -> mfree_hook != NULL)
	{
	  (*mdp -> mfree_hook) (md, ptr);
	}
      else
	{
	  __mmalloc_free (mdp, ptr);
	}
    }
}

/* When using this package, provide a version of malloc/realloc/free built
   on top of it, so that if we use the default sbrk() region we will not
   collide with another malloc package trying to do the same thing, if
   the application contains any "hidden" calls to malloc/realloc/free (such
   as inside a system library). */

void
free (ptr)
  PTR ptr;
{
  mfree ((PTR) NULL, ptr);
}
