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

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: allocate.c,v 1.9 1997/01/01 03:46:05 ldp Exp $
  4.     $Log: allocate.c,v $
  5.     Revision 1.9  1997/01/01 03:46:05  ldp
  6.     Committed Amiga native (support) code
  7.  
  8.     Changed clib to proto
  9.  
  10.     Revision 1.8  1996/12/10 13:51:36  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:43  aros
  14.     Use the official AROS macros over the __AROS versions.
  15.  
  16.     Revision 1.6  1996/10/19 17:07:24  aros
  17.     Include <aros/machine.h> instead of machine.h
  18.  
  19.     Revision 1.5  1996/09/13 17:51:21  digulla
  20.     Use IPTR
  21.  
  22.     Revision 1.4  1996/08/13 13:55:57  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:04  digulla
  28.     Added standard header for all files
  29.  
  30.     Desc:
  31.     Lang:
  32. */
  33. #include "exec_intern.h"
  34. #include "memory.h"
  35. #include <aros/machine.h>
  36. #include <exec/alerts.h>
  37. #include <aros/libcall.h>
  38. #include <exec/memory.h>
  39. #include <proto/exec.h>
  40.  
  41. /*****************************************************************************
  42.  
  43.     NAME */
  44.  
  45. AROS_LH2(APTR, Allocate,
  46.  
  47. /*  SYNOPSIS */
  48.     AROS_LHA(struct MemHeader *, freeList, A0),
  49.     AROS_LHA(ULONG,              byteSize, D0),
  50.  
  51. /*  LOCATION */
  52.     struct ExecBase *, SysBase, 31, Exec)
  53.  
  54. /*  FUNCTION
  55.     Allocate memory out of a private region handled by the MemHeader
  56.     structure.
  57.  
  58.     INPUTS
  59.     freeList - Pointer to the MemHeader structure which holds the memory
  60.     byteSize - Number of bytes you want to get
  61.  
  62.     RESULT
  63.     A pointer to the number of bytes you wanted or NULL if the memory
  64.     couldn't be allocated
  65.  
  66.     NOTES
  67.     The memory is aligned to sizeof(struct MemChunk). All requests
  68.     are rounded up to a multiple of that size.
  69.  
  70.     EXAMPLE
  71.     #define POOLSIZE 4096
  72.     \* Get a MemHeader structure and some private memory *\
  73.     mh=(struct MemHeader *)
  74.         AllocMem(sizeof(struct MemHeader)+POOLSIZE,MEMF_ANY);
  75.     if(mh!=NULL)
  76.     {
  77.         \* Build a private pool *\
  78.         mh->mh_First=(struct MemChunk *)(mh+1);
  79.         mh->mh_First->mc_Next=NULL;
  80.         mh->mh_First->mc_Bytes=POOLSIZE;
  81.         mh->mh_Free=POOLSIZE;
  82.         {
  83.         \* Use the pool *\
  84.         UBYTE *mem1,*mem2;
  85.         mem1=Allocate(mh,1000);
  86.         mem2=Allocate(mh,2000);
  87.         \* Do something with memory... *\
  88.         }
  89.         \* Free everything at once *\
  90.         FreeMem(mh,sizeof(struct MemHeader)+POOLSIZE);
  91.     }
  92.  
  93.     BUGS
  94.  
  95.     SEE ALSO
  96.     Deallocate()
  97.  
  98.     INTERNALS
  99.  
  100.     HISTORY
  101.     17-09-95    created by m. fleischer
  102.     16-10-95    increased portability
  103.  
  104. ******************************************************************************/
  105. {
  106.     AROS_LIBFUNC_INIT
  107.     struct MemChunk *p1, *p2;
  108.  
  109.     /* Zero bytes requested? May return everything ;-). */
  110.     if(!byteSize)
  111.     return NULL;
  112.  
  113.     /* First round byteSize to a multiple of MEMCHUNK_TOTAL. */
  114.     byteSize=(byteSize+MEMCHUNK_TOTAL-1)&~(MEMCHUNK_TOTAL-1);
  115.  
  116.     /* Is there enough free memory in the list? */
  117.     if(freeList->mh_Free<byteSize)
  118.     return NULL;
  119.  
  120.     /*
  121.     The free memory list is only single linked, i.e. to remove
  122.     elements from the list I need the node as well as it's
  123.     predessor. For the first element I can use freeList->mh_First
  124.     instead of a real predessor.
  125.     */
  126.     p1=(struct MemChunk *)&freeList->mh_First;
  127.     p2=p1->mc_Next;
  128.  
  129.     /* Is the list enpty? */
  130.     if(p2==NULL)
  131.     return NULL;
  132.  
  133.     /* Follow the list */
  134.     for(;;)
  135.     {
  136. #if !defined(NO_CONSISTENCY_CHECKS)
  137.     /* Consistency check: Check alignment restrictions */
  138.     if( ((IPTR)p2|(ULONG)p2->mc_Bytes) & (MEMCHUNK_TOTAL-1) )
  139.     {
  140.         Alert(AN_MemCorrupt);
  141.         return NULL;
  142.     }
  143. #endif
  144.     /* Check if current block is large enough */
  145.     if(p2->mc_Bytes>=byteSize)
  146.     {
  147.         /* It is. Remove it from the list and return it. */
  148.         if(p2->mc_Bytes==byteSize)
  149.         /* Fits exactly. Just relink the list. */
  150.         p1->mc_Next=p2->mc_Next;
  151.         else
  152.         {
  153.         /* Split the current chunk and return the first bytes. */
  154.         p1->mc_Next=(struct MemChunk *)((UBYTE *)p2+byteSize);
  155.         p1=p1->mc_Next;
  156.         p1->mc_Next=p2->mc_Next;
  157.         p1->mc_Bytes=p2->mc_Bytes-byteSize;
  158.         }
  159.         /* Adjust free memory count and return */
  160.         freeList->mh_Free-=byteSize;
  161.         return p2;
  162.     }
  163.  
  164.     /* Go to next block */
  165.     p1=p2;
  166.     p2=p1->mc_Next;
  167.  
  168.     /* Check if this was the end */
  169.     if(p2==NULL)
  170.         return NULL;
  171. #if !defined(NO_CONSISTENCY_CHECKS)
  172.     /*
  173.         Consistency check:
  174.         If the end of the last block+1 is bigger or equal to
  175.         the start of the current block something must be wrong.
  176.     */
  177.     if((UBYTE *)p2<=(UBYTE *)p1+p1->mc_Bytes)
  178.     {
  179.         Alert(AN_MemCorrupt);
  180.         return NULL;
  181.     }
  182. #endif
  183.     }
  184.     AROS_LIBFUNC_EXIT
  185. } /* Allocate */
  186.