2 Copyright (C) 1998 BJ Eirich (aka vecna)
\r
3 This program is free software; you can redistribute it and/or
\r
4 modify it under the terms of the GNU General Public License
\r
5 as published by the Free Software Foundation; either version 2
\r
6 of the License, or (at your option) any later version.
\r
7 This program is distributed in the hope that it will be useful,
\r
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
\r
10 See the GNU General Public Lic
\r
11 See the GNU General Public License for more details.
\r
12 You should have received a copy of the GNU General Public License
\r
13 along with this program; if not, write to the Free Software
\r
14 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
\r
21 void err(char *str, ...);
\r
22 void Log(char *str, ...);
\r
25 // TODO: Move the chunk list from an array to a linked list?
\r
26 // Would eliminate hardcoded chunk limit, but would make
\r
27 // general operation slower. Probably not The Right Thing,
\r
28 // sides the chunk limit can be interesting sometimes. If
\r
29 // it becomes problematic, consider a Binary Tree.
\r
32 // ***************************** Data *****************************
\r
34 #define MAXCHUNKS 200
\r
36 #define PADFILLVALUE 254
\r
39 void MemReport(void);
\r
41 #define errm MemReport(), err
\r
51 memblockType chunks[MAXCHUNKS+1];
\r
54 // ***************************** Code *****************************
\r
56 void *valloc(int amount, char *desc, int owner)
\r
58 if (numchunks == MAXCHUNKS)
\r
59 err("Failed allocated %d bytes (%s), reason: Out of chunks.",
\r
64 chunks[numchunks].pointer = (void *) ((int) malloc(amount + (PADSIZE * 2)) + PADSIZE);
\r
65 chunks[numchunks].size = amount;
\r
66 memset((char *) chunks[numchunks].pointer - PADSIZE, PADFILLVALUE, PADSIZE);
\r
67 memset((char *) chunks[numchunks].pointer +
\r
68 chunks[numchunks].size, PADFILLVALUE, PADSIZE);
\r
70 chunks[numchunks].pointer = malloc(amount);
\r
71 chunks[numchunks].size = amount;
\r
73 chunks[numchunks].owner = owner;
\r
74 strncpy(chunks[numchunks].desc, desc, 19);
\r
75 memset(chunks[numchunks].pointer, 0, chunks[numchunks].size);
\r
76 return chunks[numchunks++].pointer;
\r
79 void *qvalloc(int amount)
\r
83 // Quick and dirty memory allocation. Should be used ONLY
\r
84 // for temporary blocks in speed-critical loops.
\r
86 ptr = malloc(amount);
\r
87 if (!ptr) errm("qvalloc: Failed allocating %d bytes.", amount);
\r
91 void qvfree(void *ptr)
\r
96 int TotalBytesAllocated(void)
\r
100 for (i=0; i<numchunks; i++)
\r
101 tally += chunks[i].size;
\r
106 int FindChunk(void *pointer)
\r
110 for (i=0; i<numchunks; i++)
\r
111 if (chunks[i].pointer == pointer) return i;
\r
115 void FreeChunk(int i)
\r
119 free((void *) ((int) chunks[i].pointer - PADSIZE));
\r
121 free(chunks[i].pointer);
\r
123 for (; i<numchunks; i++)
\r
124 chunks[i]=chunks[i+1];
\r
128 int vfree(void *pointer)
\r
132 i=FindChunk(pointer);
\r
135 Log("vfree: Attempted to free ptr %u that was not allocated. [dumping mem report]", pointer);
\r
144 void FreeByOwner(int owner)
\r
148 for (i=0; i<numchunks; i++)
\r
149 if (chunks[i].owner == owner)
\r
153 void MemReport(void)
\r
158 Log("========================================");
\r
159 Log("= Memory usage report for this session =");
\r
160 Log("========================================");
\r
161 Log("Chunks currently allocated: %d (MAXCHUNKS %d)", numchunks, MAXCHUNKS);
\r
162 Log("%d total bytes allocated. ", TotalBytesAllocated());
\r
164 Log("PARANOID is ON. (pad size: %d pad value: %d)", PADSIZE, PADFILLVALUE);
\r
166 Log("PARANOID is OFF.");
\r
169 Log("Per-chunk analysis: ");
\r
171 for (i=0; i<numchunks; i++)
\r
173 Log("[%3d] Ptr at: %8u size: %8d owner: %3d desc: %s",
\r
174 i, chunks[i].pointer, chunks[i].size, chunks[i].owner, chunks[i].desc);
\r
180 int ChunkIntegrity(int i)
\r
184 tptr=(char *) malloc(PADSIZE);
\r
185 memset(tptr, PADFILLVALUE, PADSIZE);
\r
186 if (memcmp((char *) chunks[i].pointer - PADSIZE, tptr, PADSIZE))
\r
187 return -1; // Prefix corruption
\r
188 if (memcmp((char *) chunks[i].pointer + chunks[i].size, tptr, PADSIZE))
\r
189 return 1; // Suffix corruption
\r
191 return 0; // no corruption
\r
194 void CheckCorruption(void)
\r
198 for (i=0; i<numchunks; i++)
\r
200 j=ChunkIntegrity(i);
\r
202 if (j == -1) errm("Prefix corruption on chunk %d.", i);
\r
203 if (j == 1) errm("Suffix corruption on chunk %d.", i);
\r
207 void CheckCorruption(void)
\r