home *** CD-ROM | disk | FTP | other *** search
/ Aminet 18 / aminetcdnumber181997.iso / Aminet / misc / emu / AROSdev.lha / AROS / rom / exec / deallocate.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-09  |  4.8 KB  |  203 lines

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