home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / C / OTL-MC7.DMS / in.adf / classsource.lha / ClassSource / Exec / Memory / Memory.c
Encoding:
C/C++ Source or Header  |  1995-02-12  |  5.9 KB  |  300 lines

  1.  
  2. #include <classes/Exec/Memory.h>
  3. #include <exec/alerts.h>
  4.  
  5. #include <pragma/exec_lib.h>
  6.  
  7. #define PHeapSize     65536
  8.  
  9. PoolListC::PoolListC()
  10.     : ListC()
  11. {
  12. }
  13.  
  14. PoolListC::~PoolListC()
  15. {
  16.     struct MemHeader *mh;
  17.     ULONG b;
  18.     while (mh = (struct MemHeader *) remHead()) {
  19.         b = ((ULONG) mh->mh_Upper) - ((ULONG) mh->mh_Lower);
  20.         if (b > 0)
  21.             FreeMem(mh->mh_Lower,b);
  22.         FreeMem(mh,sizeof(struct MemHeader));
  23.     };
  24. }
  25.  
  26. // *************************************************************
  27.  
  28. void *PublicHeapC::operator new(size_t bytes)
  29. {
  30.     void *mem;
  31.     ListCursorC lc(pool);
  32.     while (!lc.isDone()) {
  33.         if (mem = Allocate((struct MemHeader *) lc.item(),bytes))
  34.             return mem;
  35.         lc.next();
  36.     };
  37.     struct MemHeader *mh = (struct MemHeader *) AllocMem(
  38.         sizeof(struct MemHeader),MEMF_PUBLIC|MEMF_CLEAR);
  39.     if (!mh)
  40.         return NULL;
  41.     struct MemChunk *mc;
  42.     ULONG b = bytes > PHeapSize ? bytes : PHeapSize;
  43.     if (!(mc = (struct MemChunk *) AllocMem(b,MEMF_PUBLIC)))
  44.     {
  45.         FreeMem(mh,sizeof(struct MemHeader));
  46.         return NULL;
  47.     };
  48.     mh->mh_Node.ln_Type = NT_MEMORY;
  49.     mh->mh_First = mc;
  50.     mh->mh_Lower = (APTR) mc;
  51.     mh->mh_Upper = (APTR) (((ULONG) mc) + b);
  52.     mh->mh_Free = b;
  53.     mc->mc_Next = NULL;
  54.     mc->mc_Bytes = b;
  55.     pool.addHead((NodeC &) *mh);
  56.     return Allocate(mh,bytes);
  57. }
  58.  
  59. void PublicHeapC::operator delete(void *object, size_t bytes)
  60. {
  61.     if (!object)
  62.         return;
  63.     ListCursorC lc(pool);
  64.     struct MemHeader *mh;
  65.     while (!lc.isDone()) {
  66.         mh = (struct MemHeader *) lc.item();
  67.         if (((ULONG) object >= (ULONG) mh->mh_Lower)
  68.             && ((ULONG) object < (ULONG) mh->mh_Upper))
  69.         {
  70.             Deallocate(mh,object,bytes);
  71.             if (((ULONG) mh->mh_Upper) - ((ULONG) mh->mh_Lower) <= mh->mh_Free)
  72.             {
  73.                 Remove((struct Node *) mh);
  74.                 FreeMem(mh->mh_Lower,mh->mh_Free);
  75.                 FreeMem(mh,sizeof(struct MemHeader));
  76.             };
  77.             return;
  78.         };
  79.         lc.next();
  80.     };
  81.     Alert(AN_BadFreeAddr);
  82. }
  83.  
  84. PoolListC PublicHeapC::pool;
  85.  
  86. // ******************************************************************
  87.  
  88. MemoryC::MemoryC()
  89.     : ShareManualC()
  90. {
  91.     mMemory = NULL;
  92.     mSize = 0;
  93. }
  94.  
  95. MemoryC::MemoryC(const MemoryC &s)
  96. {
  97.     mMemory = s.mMemory;
  98.     mSize = s.mSize;
  99.     if (mMemory)
  100.         reference();
  101. }
  102.  
  103. MemoryC::~MemoryC()
  104. {
  105.     if (mMemory)
  106.     {
  107.         dereference();
  108.         if (only())
  109.             FreeMem(mMemory,mSize);
  110.     };
  111. }
  112.  
  113. MemoryC &MemoryC::operator = (const MemoryC &s)
  114. {
  115.     if (this != &s)
  116.     {
  117.         if (mMemory)
  118.         {
  119.             if (only())
  120.                 FreeMem(mMemory,mSize);
  121.         }
  122.         else
  123.             dereference();
  124.         ShareManualC::operator= (s);
  125.         mMemory = s.mMemory;
  126.         mSize = s.mSize;
  127.         if (mMemory)
  128.             reference();
  129.     };
  130.     return *this;
  131. }
  132.  
  133. APTR MemoryC::allocate(ULONG bytes, ULONG flags)
  134. {
  135.     if (mMemory)
  136.         throw MemoryX(bytes,flags);
  137.     mSize = bytes;
  138.     mMemory = AllocMem(bytes,flags);
  139.     if (!mMemory)
  140.         throw MemoryX(bytes,flags);
  141.     reference();
  142.     return mMemory;
  143. }
  144.  
  145. VOID MemoryC::free()
  146. {
  147.     if (mMemory)
  148.     {
  149.         dereference();
  150.         if (only())
  151.             FreeMem(mMemory,mSize);
  152.         mMemory = NULL;
  153.         mSize = 0;
  154.     };
  155. }
  156.  
  157. ULONG MemoryC::available(ULONG flags)
  158. {
  159.     return AvailMem(flags);
  160. }
  161.  
  162. // *************************************************************
  163.  
  164. MemoryPoolC::MemoryPoolC(ULONG flags, ULONG poolsize)
  165.     : ListC()
  166. {
  167.     mflags = flags;
  168.     psize = poolsize;
  169. }
  170.  
  171. MemoryPoolC::~MemoryPoolC()
  172. {
  173.     struct MemHeader *mh;
  174.     ULONG b;
  175.     while (mh = (struct MemHeader *) remHead()) {
  176.         b = ((ULONG) mh->mh_Upper) - ((ULONG) mh->mh_Lower);
  177.         if (b > 0)
  178.             FreeMem(mh->mh_Lower,b);
  179.         FreeMem(mh,sizeof(struct MemHeader));
  180.     };
  181. }
  182.  
  183. VOID MemoryPoolC::changePoolsize(ULONG poolsize)
  184. {
  185.     psize = poolsize;
  186. }
  187.  
  188. APTR MemoryPoolC::allocate(ULONG bytes)
  189. {
  190.     void *mem;
  191.     ListCursorC lc(*this);
  192.     while (!lc.isDone()) {
  193.         if (mem = Allocate((struct MemHeader *) lc.item(),bytes))
  194.             return mem;
  195.         lc.next();
  196.     };
  197.     struct MemHeader *mh = (struct MemHeader *) AllocMem(
  198.         sizeof(struct MemHeader),(mflags & MEMF_PUBLIC) | MEMF_CLEAR);
  199.     if (!mh)
  200.         throw MemoryX(bytes,mflags & MEMF_PUBLIC);
  201.     struct MemChunk *mc;
  202.     ULONG b = bytes > psize ? bytes : psize;
  203.     if (!(mc = (struct MemChunk *) AllocMem(b,mflags & MEMF_PUBLIC)))
  204.     {
  205.         FreeMem(mh,sizeof(struct MemHeader));
  206.         throw MemoryX(bytes,mflags & MEMF_PUBLIC);
  207.     };
  208.     mh->mh_Node.ln_Type = NT_MEMORY;
  209.     mh->mh_First = mc;
  210.     mh->mh_Lower = (APTR) mc;
  211.     mh->mh_Upper = (APTR) (((ULONG) mc) + b);
  212.     mh->mh_Free = b;
  213.     mc->mc_Next = NULL;
  214.     mc->mc_Bytes = b;
  215.     addHead((NodeC &) *mh);
  216.     return Allocate(mh,bytes);
  217. }
  218.  
  219. VOID MemoryPoolC::free(APTR address, ULONG bytes)
  220. {
  221.     if (!address)
  222.         return;
  223.     ListCursorC lc(*this);
  224.     struct MemHeader *mh;
  225.     while (!lc.isDone()) {
  226.         mh = (struct MemHeader *) lc.item();
  227.         if (((ULONG) address >= (ULONG) mh->mh_Lower)
  228.             && ((ULONG) address < (ULONG) mh->mh_Upper))
  229.         {
  230.             Deallocate(mh,address,bytes);
  231.             if (((ULONG) mh->mh_Upper) - ((ULONG) mh->mh_Lower) <= mh->mh_Free)
  232.             {
  233.                 Remove((struct Node *) mh);
  234.                 FreeMem(mh->mh_Lower,mh->mh_Free);
  235.                 FreeMem(mh,sizeof(struct MemHeader));
  236.             };
  237.             return;
  238.         };
  239.         lc.next();
  240.     };
  241.     Alert(AN_BadFreeAddr);
  242. }
  243.  
  244. // *************************************************************
  245.  
  246. SmallMemoryPoolC::SmallMemoryPoolC(ULONG flags, ULONG poolsize)
  247.     : pools(sizeof(SmallMemoryBlock),10)
  248. {
  249.     mflags = flags;
  250.     psize = poolsize;
  251.     pool = NULL;
  252. }
  253.  
  254. SmallMemoryPoolC::~SmallMemoryPoolC()
  255. {
  256.     flush();
  257. }
  258.  
  259. APTR SmallMemoryPoolC::allocate(ULONG bytes)
  260. {
  261.     if (!pool)
  262.     {
  263.         APTR mem = AllocMem(psize,mflags);
  264.         if (!mem)
  265.             throw MemoryX(psize,mflags);
  266.         pool = &(struct SmallMemoryBlock &) pools.addTail();
  267.         pool->memory = mem;
  268.         pool->size = psize;
  269.         pool->full = 0;
  270.     };
  271.     if (pool->full + bytes > pool->size)
  272.     {
  273.         APTR mem = AllocMem(psize,mflags);
  274.         if (!mem)
  275.             throw MemoryX(psize,mflags);
  276.         pool = &(struct SmallMemoryBlock &) pools.addTail();
  277.         pool->memory = mem;
  278.         pool->size = psize;
  279.         pool->full = 0;
  280.     };
  281.     APTR retval = (APTR) (((ULONG) pool->memory) + pool->full);
  282.     pool->full += bytes;
  283.     return retval;
  284. }
  285.  
  286. VOID SmallMemoryPoolC::free(APTR address, ULONG size)
  287. {
  288. }
  289.  
  290. VOID SmallMemoryPoolC::flush()
  291. {
  292.     gen_arraycursor gac(pools);
  293.     while (!gac.isDone()) {
  294.         struct SmallMemoryBlock *i = &(struct SmallMemoryBlock &) gac.item();
  295.         if (i->memory)
  296.             FreeMem(i->memory,i->size);
  297.         gac.next();
  298.     };
  299. }
  300.