home *** CD-ROM | disk | FTP | other *** search
- /*
- ** termMemory.c
- **
- ** Memory management routines
- **
- ** Copyright © 1990-1995 by Olaf `Olsen' Barthel
- ** All Rights Reserved
- */
-
- #include "termGlobal.h"
-
- // Main memory pool puddle size
-
- #define PUDDLE_SIZE 32768
-
- // Memory allocation data
-
- STATIC struct SignalSemaphore MemorySemaphore;
- STATIC APTR MemoryPool;
-
- // Prototypes for pools.lib
-
- APTR __asm AsmCreatePool(register __d0 ULONG MemFlags,register __d1 ULONG PuddleSize,register __d2 ULONG ThreshSize,register __a6 struct ExecBase *SysBase);
- VOID __asm AsmDeletePool(register __a0 APTR PoolHeader,register __a6 struct ExecBase *SysBase);
- APTR __asm AsmAllocPooled(register __a0 APTR PoolHeader, register __d0 ULONG Size,register __a6 struct ExecBase *SysBase);
- VOID __asm AsmFreePooled(register __a0 APTR PoolHeader,register __a1 APTR Memory,register __d0 ULONG MemSize,register __a6 struct ExecBase *SysBase);
-
- // Diagnostic data
-
- typedef char (* __asm SegTrack(register __a0 ULONG Address,register __a1 ULONG *SegNum,register __a2 ULONG *Offset));
-
- struct SegSem
- {
- struct SignalSemaphore seg_Semaphore;
- SegTrack *seg_Find;
- };
-
- struct FirewallInfo
- {
- ULONG Checksum;
-
- ULONG Address;
- ULONG TotalSize;
- ULONG ReturnAddress;
- ULONG Size;
- ULONG FillByte;
-
- ULONG FirePre;
- ULONG FirePost;
- };
-
- STATIC LONG FirewallPre = 0,FirewallPost = 0;
- STATIC ULONG FillByte = 1;
-
- STATIC LONG Smallest = -1,Largest = -1;
-
- /* MemorySetup():
- *
- * Set up the main memory pool.
- */
-
- BOOLEAN
- MemorySetup()
- {
- BOOL DosOpen = FALSE;
-
- if(!DOSBase)
- {
- if(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",37))
- DosOpen = TRUE;
- }
-
- if(DOSBase)
- {
- UBYTE LocalBuffer[256];
-
- if(GetVar("TERMPREALLOC",LocalBuffer,256,NULL) > 0)
- {
- if(StrToLong(LocalBuffer,&FirewallPre) > 0)
- {
- if(FirewallPre < 16)
- FirewallPre = 16;
-
- FirewallPost = 16;
-
- if(GetVar("TERMPOSTALLOC",LocalBuffer,256,NULL) > 0)
- {
- if(StrToLong(LocalBuffer,&FirewallPre) <= 0)
- FirewallPost = 16;
- }
-
- FirewallPre = (FirewallPre + 15) & ~15;
- FirewallPost = (FirewallPost + 15) & ~15;
-
- if(!FirewallPost)
- FirewallPost = 16;
- }
- else
- FirewallPost = 0;
- }
-
- if(DosOpen)
- {
- CloseLibrary((struct Library *)DOSBase);
- DOSBase = NULL;
- }
- }
-
- InitSemaphore(&MemorySemaphore);
-
- if(MemoryPool = AsmCreatePool(MEMF_PUBLIC | MEMF_ANY,PUDDLE_SIZE,PUDDLE_SIZE,SysBase))
- return(TRUE);
- else
- return(FALSE);
- }
-
- /* MemoryCleanup():
- *
- * Clean up the main memory pool.
- */
-
- VOID
- MemoryCleanup()
- {
- if(Smallest != -1)
- {
- kprintf("term stats: smallest allocation was %ld bytes\n",Smallest);
- Smallest = -1;
- }
-
- if(Largest != -1)
- {
- kprintf("term stats: largest allocation was %ld bytes\n",Largest);
- Largest = -1;
- }
-
- if(MemoryPool)
- {
- AsmDeletePool(MemoryPool,SysBase);
-
- MemoryPool = NULL;
- }
- }
-
- /* FreeVecPooled(APTR Memory):
- *
- * Free a memory chunk.
- */
-
- VOID __asm
- FreeVecPooledLocal(register __a0 APTR Memory,register __a1 ULONG ReturnAddress)
- {
- if(Memory && MemoryPool)
- {
- ULONG *Data = (ULONG *)Memory;
-
- ObtainSemaphore(&MemorySemaphore);
-
- if(FirewallPre)
- {
- struct FirewallInfo *Info;
- ULONG Sum,*Thing;
- WORD i;
-
- Info = (struct FirewallInfo *)(((ULONG)Memory) - (sizeof(struct FirewallInfo) + FirewallPre));
-
- for(Sum = 0, i = 1, Thing = &Info -> Address ; i < sizeof(struct FirewallInfo) / sizeof(ULONG) ; i++)
- Sum += Thing[i];
-
- if(Info -> Checksum == ~Sum && Memory == (APTR)Info -> Address)
- {
- UBYTE *Data;
- LONG i;
- BOOL AllocationProblem = FALSE;
-
- Data = (UBYTE *)Info -> FirePre;
-
- for(i = 0 ; i < FirewallPre ; i++)
- {
- if(Data[i] != Info -> FillByte)
- {
- LONG j;
-
- AllocationProblem = TRUE;
-
- kprintf("term: Allocation @ 0x%08lx, Size %ld got stomped on, %ld bytes trashed before, FillByte %02lx:",Memory,Info -> Size,FirewallPre - i,Info -> FillByte);
-
- Data = &Data[i];
-
- for(j = 0 ; j < FirewallPre - i ; j++)
- {
- if(!(j & 7))
- kprintf("\n %08lx: ",&Data[j]);
-
- kprintf("%02lx ",Data[j]);
- }
-
- kprintf("\n");
-
- break;
- }
- }
-
- Data = (UBYTE *)Info -> FirePost;
-
- for(i = FirewallPost - 1 ; i >= 0 ; i--)
- {
- if(Data[i] != Info -> FillByte)
- {
- LONG j;
-
- Data = (UBYTE *)Info -> FirePost;
-
- if(AllocationProblem)
- kprintf(" %ld bytes trashed after:",i + 1);
- else
- kprintf("term: Allocation @ 0x%08lx, Size %ld got stomped on, %ld bytes trashed after, FillByte 0x%02lx:",Memory,Info -> Size,i + 1,Info -> FillByte);
-
- AllocationProblem = TRUE;
-
- for(j = 0 ; j <= i ; j++)
- {
- if(!(j & 7))
- kprintf("\n %08lx: ",&Data[j]);
-
- kprintf("%02lx ",Data[j]);
- }
-
- kprintf("\n");
-
- break;
- }
- }
-
- if(AllocationProblem)
- {
- struct SegSem *SegTracker;
-
- Forbid();
-
- if(SegTracker = (struct SegSem *)FindSemaphore("SegTracker"))
- {
- char LocalBuffer[256];
- ULONG Segment,Offset;
- char *Name;
-
- kprintf("\n");
-
- if(Name = (*SegTracker -> seg_Find)(Info -> ReturnAddress,&Segment,&Offset))
- {
- CopyMem(Name,LocalBuffer,255);
- LocalBuffer[255] = 0;
-
- kprintf(" Alloc by |%s| %lx:%lx\n",LocalBuffer,Segment,Offset);
- }
-
- if(Name = (*SegTracker -> seg_Find)(ReturnAddress,&Segment,&Offset))
- {
- CopyMem(Name,LocalBuffer,255);
- LocalBuffer[255] = 0;
-
- kprintf(" Free by |%s| %lx:%lx\n",LocalBuffer,Segment,Offset);
- }
- }
-
- Permit();
- }
-
- AsmFreePooled(MemoryPool,Info,Info -> TotalSize,SysBase);
- }
- else
- {
- struct SegSem *SegTracker;
-
- Forbid();
-
- if(SegTracker = (struct SegSem *)FindSemaphore("SegTracker"))
- {
- char LocalBuffer[256];
- ULONG Segment,Offset;
- char *Name;
-
- if(Name = (*SegTracker -> seg_Find)(ReturnAddress,&Segment,&Offset))
- {
- CopyMem(Name,LocalBuffer,255);
- LocalBuffer[255] = 0;
-
- kprintf(" Bogus free from 0x%08lx by |%s| %lx:%lx\n",Memory,LocalBuffer,Segment,Offset);
- }
- }
-
- Permit();
- }
- }
- else
- AsmFreePooled(MemoryPool,&Data[-1],Data[-1],SysBase);
-
- ReleaseSemaphore(&MemorySemaphore);
- }
- }
-
- /* AllocVecPooled(ULONG Size,ULONG Flags):
- *
- * Allocate a memory chunk from the main memory pool and
- * remember its size.
- */
-
- APTR __asm
- AllocVecPooledLocal(register __d0 ULONG Size,register __d1 ULONG Flags,register __a0 ULONG ReturnAddr)
- {
- if(MemoryPool)
- {
- ObtainSemaphore(&MemorySemaphore);
-
- if(FirewallPre)
- {
- struct FirewallInfo *Info;
- ULONG FireSize;
- ULONG RoundSize = (Size + 3) & ~3;
-
- if(Smallest == -1)
- Smallest = Size;
-
- if(Largest == -1)
- Largest = Size;
-
- if(Size < Smallest)
- Smallest = Size;
-
- if(Size > Largest)
- Largest = Size;
-
- FireSize = sizeof(struct FirewallInfo) + FirewallPre + RoundSize + FirewallPost;
-
- if(Info = (struct FirewallInfo *)AsmAllocPooled(MemoryPool,FireSize,SysBase))
- {
- ULONG *Data,Sum,*Thing;
- WORD i;
-
- Info -> Address = ((ULONG)Info) + sizeof(struct FirewallInfo) + FirewallPre;
- Info -> TotalSize = FireSize;
- Info -> ReturnAddress = ReturnAddr;
- Info -> Size = Size;
- Info -> FillByte = FillByte;
-
- Info -> FirePre = (ULONG)&Info[1];
- Info -> FirePost = Info -> FirePre + FirewallPre + RoundSize;
-
- memset((APTR)(Info -> FirePre),FillByte,FirewallPre);
- memset((APTR)(Info -> FirePost),FillByte,FirewallPost);
-
- for(Sum = 0, i = 1, Thing = &Info -> Address ; i < sizeof(struct FirewallInfo) / sizeof(ULONG) ; i++)
- Sum += Thing[i];
-
- Info -> Checksum = ~Sum;
-
- FillByte = (FillByte + 2) & 0xFF;
-
- Data = (ULONG *)Info -> Address;
-
- ReleaseSemaphore(&MemorySemaphore);
-
- if(Flags & MEMF_CLEAR)
- {
- register ULONG *Memory = Data;
-
- Size = RoundSize / sizeof(ULONG) - 1;
-
- do
- *Memory++ = 0;
- while(Size--);
- }
- else
- {
- register ULONG *Memory = Data;
-
- Size = RoundSize / sizeof(ULONG) - 1;
-
- do
- *Memory++ = 0xDEADBEEF;
- while(Size--);
- }
-
- return((APTR)Data);
- }
- }
- else
- {
- ULONG *Data;
-
- Size = (Size + sizeof(ULONG) + 3) & ~3;
-
- if(Data = (ULONG *)AsmAllocPooled(MemoryPool,Size,SysBase))
- {
- ReleaseSemaphore(&MemorySemaphore);
-
- *Data++ = Size;
-
- // Zero the chunk if necessary
-
- if(Flags & MEMF_CLEAR)
- {
- register ULONG *Memory = Data;
-
- Size = Size / sizeof(ULONG) - 2;
-
- do
- *Memory++ = 0;
- while(Size--);
- }
-
- return((APTR)Data);
- }
- }
-
- ReleaseSemaphore(&MemorySemaphore);
- }
-
- return(NULL);
- }
-