home *** CD-ROM | disk | FTP | other *** search
/ MACD 4 / MACD4.iso / Emulatory / AROS / exec / deallocate.c < prev    next >
Encoding:
C/C++ Source or Header  |  1978-03-06  |  4.6 KB  |  195 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: deallocate.c,v 1.7 1996/10/24 15:50:47 aros Exp $
  4.     $Log: deallocate.c,v $
  5.     Revision 1.7  1996/10/24 15:50:47  aros
  6.     Use the official AROS macros over the __AROS versions.
  7.  
  8.     Revision 1.6  1996/10/19 17:07:25  aros
  9.     Include <aros/machine.h> instead of machine.h
  10.  
  11.     Revision 1.5  1996/09/13 17:51:23  digulla
  12.     Use IPTR
  13.  
  14.     Revision 1.4  1996/08/13 13:56:00  digulla
  15.     Replaced AROS_LA by AROS_LHA
  16.     Replaced some AROS_LH*I by AROS_LH*
  17.     Sorted and added includes
  18.  
  19.     Revision 1.3  1996/08/01 17:41:09  digulla
  20.     Added standard header for all files
  21.  
  22.     Desc:
  23.     Lang:
  24. */
  25. #include <exec/execbase.h>
  26. #include <exec/alerts.h>
  27. #include <aros/libcall.h>
  28. #include <aros/machine.h>
  29. #include "memory.h"
  30.  
  31. /*****************************************************************************
  32.  
  33.     NAME */
  34.     #include <exec/memory.h>
  35.     #include <clib/exec_protos.h>
  36.  
  37.     AROS_LH3(void, Deallocate,
  38.  
  39. /*  SYNOPSIS */
  40.     AROS_LHA(struct MemHeader *, freeList,    A0),
  41.     AROS_LHA(APTR,               memoryBlock, A1),
  42.     AROS_LHA(ULONG,              byteSize,    D0),
  43.  
  44. /*  LOCATION */
  45.     struct ExecBase *, SysBase, 32, Exec)
  46.  
  47. /*  FUNCTION
  48.     Free block of memory associated with a given MemHandler structure.
  49.  
  50.     INPUTS
  51.     freeList    - Pointer to the MemHeader structure
  52.     memoryBlock - Pointer to the memory to be freed
  53.     byteSize    - Size of the block
  54.  
  55.     RESULT
  56.  
  57.     NOTES
  58.     The start and end borders of the block are aligned to
  59.     a multiple of sizeof(struct MemChunk) and to include the block.
  60.  
  61.     EXAMPLE
  62.  
  63.     BUGS
  64.  
  65.     SEE ALSO
  66.     Allocate()
  67.  
  68.     INTERNALS
  69.  
  70.     HISTORY
  71.     18-09-95    created by m. fleischer
  72.     15-10-95    more consistency checks added
  73.  
  74. ******************************************************************************/
  75. {
  76.     AROS_LIBFUNC_INIT
  77.  
  78.     struct MemChunk *p1, *p2, *p3;
  79.     UBYTE *p4;
  80.  
  81.     /* If there is no memory free nothing */
  82.     if(!byteSize)
  83.     return;
  84.  
  85.     /* Align size to the requirements */
  86.     byteSize+=(IPTR)memoryBlock&(MEMCHUNK_TOTAL-1);
  87.     byteSize=(byteSize+MEMCHUNK_TOTAL-1)&~(MEMCHUNK_TOTAL-1);
  88.  
  89.     /* Align the block as well */
  90.     memoryBlock=(APTR)((IPTR)memoryBlock&~(MEMCHUNK_TOTAL-1));
  91.  
  92.     /*
  93.     The free memory list is only single linked, i.e. to insert
  94.     elements into the list I need the node as well as it's
  95.     predessor. For the first element I can use freeList->mh_First
  96.     instead of a real predessor.
  97.     */
  98.     p1=(struct MemChunk *)&freeList->mh_First;
  99.     p2=freeList->mh_First;
  100.  
  101.     /* Start and end(+1) of the block */
  102.     p3=(struct MemChunk *)memoryBlock;
  103.     p4=(UBYTE *)p3+byteSize;
  104.  
  105.     /* No chunk in list? Just insert the current one and return. */
  106.     if(p2==NULL)
  107.     {
  108.     p3->mc_Bytes=byteSize;
  109.     p3->mc_Next=NULL;
  110.     p1->mc_Next=p3;
  111.     freeList->mh_Free+=byteSize;
  112.     return;
  113.     }
  114.  
  115.     /* Follow the list to find a place where to insert our memory. */
  116.     do
  117.     {
  118. #if !defined(NO_CONSISTENCY_CHECKS)
  119.     /*
  120.         Do some constistency checks:
  121.         1. All MemChunks must be aligned to MEMCHUNK_TOTAL.
  122.         2. The end (+1) of the current MemChunk
  123.            must be lower than the start of the next one.
  124.     */
  125.     if(  ((IPTR)p2|p2->mc_Bytes)&(MEMCHUNK_TOTAL-1)
  126.         ||(  (UBYTE *)p2+p2->mc_Bytes>=(UBYTE *)p2->mc_Next
  127.         &&p2->mc_Next!=NULL))
  128.         Alert(AN_MemCorrupt|AT_DeadEnd);
  129. #endif
  130.     /* Found a block with a higher address? */
  131.     if(p2>=p3)
  132.     {
  133. #if !defined(NO_CONSISTENCY_CHECKS)
  134.         /*
  135.         If the memory to be freed overlaps with the current
  136.         block something must be wrong.
  137.         */
  138.         if(p4>(UBYTE *)p2)
  139.         {
  140.         Alert(AN_FreeTwice);
  141.         return;
  142.         }
  143. #endif
  144.         /* End the loop with p2 non-zero */
  145.         break;
  146.     }
  147.     /* goto next block */
  148.     p1=p2;
  149.     p2=p2->mc_Next;
  150.  
  151.     /* If the loop ends with p2 zero add it at the end. */
  152.     }while(p2!=NULL);
  153.  
  154.     /* If there was a previous block merge with it. */
  155.     if(p1!=(struct MemChunk *)&freeList->mh_First)
  156.     {
  157. #if !defined(NO_CONSISTENCY_CHECKS)
  158.     /* Check if they overlap. */
  159.     if((UBYTE *)p1+p1->mc_Bytes>(UBYTE *)p3)
  160.     {
  161.         Alert(AN_FreeTwice);
  162.         return;
  163.     }
  164. #endif
  165.     /* Merge if possible */
  166.     if((UBYTE *)p1+p1->mc_Bytes==(UBYTE *)p3)
  167.         p3=p1;
  168.     else
  169.         /* Not possible to merge */
  170.         p1->mc_Next=p3;
  171.     }else
  172.     /*
  173.         There was no previous block. Just insert the memory at
  174.         the start of the list.
  175.     */
  176.     p1->mc_Next=p3;
  177.  
  178.     /* Try to merge with next block (if there is one ;-) ). */
  179.     if(p4==(UBYTE *)p2&&p2!=NULL)
  180.     {
  181.     /*
  182.        Overlap checking already done. Doing it here after
  183.        the list potentially changed would be a bad idea.
  184.     */
  185.     p4+=p2->mc_Bytes;
  186.     p2=p2->mc_Next;
  187.     }
  188.     /* relink the list and return. */
  189.     p3->mc_Next=p2;
  190.     p3->mc_Bytes=p4-(UBYTE *)p3;
  191.     freeList->mh_Free+=byteSize;
  192.     return;
  193.     AROS_LIBFUNC_EXIT
  194. } /* Deallocate */
  195.