home *** CD-ROM | disk | FTP | other *** search
-
- #include <classes/Exec/Memory.h>
- #include <exec/alerts.h>
-
- #include <pragma/exec_lib.h>
-
- #define PHeapSize 65536
-
- PoolListC::PoolListC()
- : ListC()
- {
- }
-
- PoolListC::~PoolListC()
- {
- struct MemHeader *mh;
- ULONG b;
- while (mh = (struct MemHeader *) remHead()) {
- b = ((ULONG) mh->mh_Upper) - ((ULONG) mh->mh_Lower);
- if (b > 0)
- FreeMem(mh->mh_Lower,b);
- FreeMem(mh,sizeof(struct MemHeader));
- };
- }
-
- // *************************************************************
-
- void *PublicHeapC::operator new(size_t bytes)
- {
- void *mem;
- ListCursorC lc(pool);
- while (!lc.isDone()) {
- if (mem = Allocate((struct MemHeader *) lc.item(),bytes))
- return mem;
- lc.next();
- };
- struct MemHeader *mh = (struct MemHeader *) AllocMem(
- sizeof(struct MemHeader),MEMF_PUBLIC|MEMF_CLEAR);
- if (!mh)
- return NULL;
- struct MemChunk *mc;
- ULONG b = bytes > PHeapSize ? bytes : PHeapSize;
- if (!(mc = (struct MemChunk *) AllocMem(b,MEMF_PUBLIC)))
- {
- FreeMem(mh,sizeof(struct MemHeader));
- return NULL;
- };
- mh->mh_Node.ln_Type = NT_MEMORY;
- mh->mh_First = mc;
- mh->mh_Lower = (APTR) mc;
- mh->mh_Upper = (APTR) (((ULONG) mc) + b);
- mh->mh_Free = b;
- mc->mc_Next = NULL;
- mc->mc_Bytes = b;
- pool.addHead((NodeC &) *mh);
- return Allocate(mh,bytes);
- }
-
- void PublicHeapC::operator delete(void *object, size_t bytes)
- {
- if (!object)
- return;
- ListCursorC lc(pool);
- struct MemHeader *mh;
- while (!lc.isDone()) {
- mh = (struct MemHeader *) lc.item();
- if (((ULONG) object >= (ULONG) mh->mh_Lower)
- && ((ULONG) object < (ULONG) mh->mh_Upper))
- {
- Deallocate(mh,object,bytes);
- if (((ULONG) mh->mh_Upper) - ((ULONG) mh->mh_Lower) <= mh->mh_Free)
- {
- Remove((struct Node *) mh);
- FreeMem(mh->mh_Lower,mh->mh_Free);
- FreeMem(mh,sizeof(struct MemHeader));
- };
- return;
- };
- lc.next();
- };
- Alert(AN_BadFreeAddr);
- }
-
- PoolListC PublicHeapC::pool;
-
- // ******************************************************************
-
- MemoryC::MemoryC()
- : ShareManualC()
- {
- mMemory = NULL;
- mSize = 0;
- }
-
- MemoryC::MemoryC(const MemoryC &s)
- {
- mMemory = s.mMemory;
- mSize = s.mSize;
- if (mMemory)
- reference();
- }
-
- MemoryC::~MemoryC()
- {
- if (mMemory)
- {
- dereference();
- if (only())
- FreeMem(mMemory,mSize);
- };
- }
-
- MemoryC &MemoryC::operator = (const MemoryC &s)
- {
- if (this != &s)
- {
- if (mMemory)
- {
- if (only())
- FreeMem(mMemory,mSize);
- }
- else
- dereference();
- ShareManualC::operator= (s);
- mMemory = s.mMemory;
- mSize = s.mSize;
- if (mMemory)
- reference();
- };
- return *this;
- }
-
- APTR MemoryC::allocate(ULONG bytes, ULONG flags)
- {
- if (mMemory)
- throw MemoryX(bytes,flags);
- mSize = bytes;
- mMemory = AllocMem(bytes,flags);
- if (!mMemory)
- throw MemoryX(bytes,flags);
- reference();
- return mMemory;
- }
-
- VOID MemoryC::free()
- {
- if (mMemory)
- {
- dereference();
- if (only())
- FreeMem(mMemory,mSize);
- mMemory = NULL;
- mSize = 0;
- };
- }
-
- ULONG MemoryC::available(ULONG flags)
- {
- return AvailMem(flags);
- }
-
- // *************************************************************
-
- MemoryPoolC::MemoryPoolC(ULONG flags, ULONG poolsize)
- : ListC()
- {
- mflags = flags;
- psize = poolsize;
- }
-
- MemoryPoolC::~MemoryPoolC()
- {
- struct MemHeader *mh;
- ULONG b;
- while (mh = (struct MemHeader *) remHead()) {
- b = ((ULONG) mh->mh_Upper) - ((ULONG) mh->mh_Lower);
- if (b > 0)
- FreeMem(mh->mh_Lower,b);
- FreeMem(mh,sizeof(struct MemHeader));
- };
- }
-
- VOID MemoryPoolC::changePoolsize(ULONG poolsize)
- {
- psize = poolsize;
- }
-
- APTR MemoryPoolC::allocate(ULONG bytes)
- {
- void *mem;
- ListCursorC lc(*this);
- while (!lc.isDone()) {
- if (mem = Allocate((struct MemHeader *) lc.item(),bytes))
- return mem;
- lc.next();
- };
- struct MemHeader *mh = (struct MemHeader *) AllocMem(
- sizeof(struct MemHeader),(mflags & MEMF_PUBLIC) | MEMF_CLEAR);
- if (!mh)
- throw MemoryX(bytes,mflags & MEMF_PUBLIC);
- struct MemChunk *mc;
- ULONG b = bytes > psize ? bytes : psize;
- if (!(mc = (struct MemChunk *) AllocMem(b,mflags & MEMF_PUBLIC)))
- {
- FreeMem(mh,sizeof(struct MemHeader));
- throw MemoryX(bytes,mflags & MEMF_PUBLIC);
- };
- mh->mh_Node.ln_Type = NT_MEMORY;
- mh->mh_First = mc;
- mh->mh_Lower = (APTR) mc;
- mh->mh_Upper = (APTR) (((ULONG) mc) + b);
- mh->mh_Free = b;
- mc->mc_Next = NULL;
- mc->mc_Bytes = b;
- addHead((NodeC &) *mh);
- return Allocate(mh,bytes);
- }
-
- VOID MemoryPoolC::free(APTR address, ULONG bytes)
- {
- if (!address)
- return;
- ListCursorC lc(*this);
- struct MemHeader *mh;
- while (!lc.isDone()) {
- mh = (struct MemHeader *) lc.item();
- if (((ULONG) address >= (ULONG) mh->mh_Lower)
- && ((ULONG) address < (ULONG) mh->mh_Upper))
- {
- Deallocate(mh,address,bytes);
- if (((ULONG) mh->mh_Upper) - ((ULONG) mh->mh_Lower) <= mh->mh_Free)
- {
- Remove((struct Node *) mh);
- FreeMem(mh->mh_Lower,mh->mh_Free);
- FreeMem(mh,sizeof(struct MemHeader));
- };
- return;
- };
- lc.next();
- };
- Alert(AN_BadFreeAddr);
- }
-
- // *************************************************************
-
- SmallMemoryPoolC::SmallMemoryPoolC(ULONG flags, ULONG poolsize)
- : pools(sizeof(SmallMemoryBlock),10)
- {
- mflags = flags;
- psize = poolsize;
- pool = NULL;
- }
-
- SmallMemoryPoolC::~SmallMemoryPoolC()
- {
- flush();
- }
-
- APTR SmallMemoryPoolC::allocate(ULONG bytes)
- {
- if (!pool)
- {
- APTR mem = AllocMem(psize,mflags);
- if (!mem)
- throw MemoryX(psize,mflags);
- pool = &(struct SmallMemoryBlock &) pools.addTail();
- pool->memory = mem;
- pool->size = psize;
- pool->full = 0;
- };
- if (pool->full + bytes > pool->size)
- {
- APTR mem = AllocMem(psize,mflags);
- if (!mem)
- throw MemoryX(psize,mflags);
- pool = &(struct SmallMemoryBlock &) pools.addTail();
- pool->memory = mem;
- pool->size = psize;
- pool->full = 0;
- };
- APTR retval = (APTR) (((ULONG) pool->memory) + pool->full);
- pool->full += bytes;
- return retval;
- }
-
- VOID SmallMemoryPoolC::free(APTR address, ULONG size)
- {
- }
-
- VOID SmallMemoryPoolC::flush()
- {
- gen_arraycursor gac(pools);
- while (!gac.isDone()) {
- struct SmallMemoryBlock *i = &(struct SmallMemoryBlock &) gac.item();
- if (i->memory)
- FreeMem(i->memory,i->size);
- gac.next();
- };
- }
-