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
23 // TODO: Move the chunk list from an array to a linked list?
\r
24 // Would eliminate hardcoded chunk limit, but would make
\r
25 // general operation slower. Probably not The Right Thing,
\r
26 // sides the chunk limit can be interesting sometimes. If
\r
27 // it becomes problematic, consider a Binary Tree.
\r
30 // ***************************** Data *****************************
\r
32 #define MAXCHUNKS 1000
\r
34 #define PADFILLVALUE 254
\r
45 memblockType chunks[MAXCHUNKS+1];
\r
48 // ***************************** Code *****************************
\r
50 void *valloc(int amount, char *desc, int owner)
\r
52 if (numchunks == MAXCHUNKS)
\r
53 err("Failed allocated %d bytes (%s), reason: Out of chunks.",
\r
58 chunks[numchunks].pointer = (void *) ((int) malloc(amount + (PADSIZE * 2)) + PADSIZE);
\r
59 chunks[numchunks].size = amount;
\r
60 memset((char *) chunks[numchunks].pointer - PADSIZE, PADFILLVALUE, PADSIZE);
\r
61 memset((char *) chunks[numchunks].pointer +
\r
62 chunks[numchunks].size, PADFILLVALUE, PADSIZE);
\r
64 chunks[numchunks].pointer = malloc(amount);
\r
65 chunks[numchunks].size = amount;
\r
67 chunks[numchunks].owner = owner;
\r
68 strncpy(chunks[numchunks].desc, desc, 39);
\r
69 return chunks[numchunks++].pointer;
\r
72 void *qvalloc(int amount)
\r
76 // Quick and dirty memory allocation. Should be used ONLY
\r
77 // for temporary blocks in speed-critical loops.
\r
79 ptr = malloc(amount);
\r
80 if (!ptr) err("qvalloc: Failed allocating %d bytes.", amount);
\r
84 void qvfree(void *ptr)
\r
89 int TotalBytesAllocated(void)
\r
93 for (i=0; i<numchunks; i++)
\r
94 tally += chunks[i].size;
\r
99 int FindChunk(void *pointer)
\r
103 for (i=0; i<numchunks; i++)
\r
104 if (chunks[i].pointer == pointer) return i;
\r
108 void FreeChunk(int i)
\r
112 free((void *) ((int) chunks[i].pointer - PADSIZE));
\r
114 free(chunks[i].pointer);
\r
116 for (; i<numchunks; i++)
\r
117 chunks[i]=chunks[i+1];
\r
121 int v_free(void *ptr)
\r
123 int i=FindChunk(ptr);
\r
126 Log("vfree: Attempted to free ptr %u that was not allocated. [dumping mem report]", ptr);
\r
135 void FreeByOwner(int owner)
\r
139 for (i=0; i<numchunks; i++)
\r
140 if (chunks[i].owner == owner)
\r
144 void MemReport(void)
\r
149 Log("========================================");
\r
150 Log("= Memory usage report for this session =");
\r
151 Log("========================================");
\r
152 Log("Chunks currently allocated: %d (MAXCHUNKS %d)", numchunks, MAXCHUNKS);
\r
153 Log("%d total bytes allocated. ", TotalBytesAllocated());
\r
155 Log("PARANOID is ON. (pad size: %d pad value: %d)", PADSIZE, PADFILLVALUE);
\r
157 Log("PARANOID is OFF.");
\r
160 Log("Per-chunk analysis: ");
\r
162 for (i=0; i<numchunks; i++)
\r
164 Log("[%3d] Ptr at: %8u size: %8d owner: %3d desc: %s",
\r
165 i, chunks[i].pointer, chunks[i].size, chunks[i].owner, chunks[i].desc);
\r
170 int ChunkIntegrity(int i)
\r
174 tptr=(char *) malloc(PADSIZE);
\r
175 memset(tptr, PADFILLVALUE, PADSIZE);
\r
176 if (memcmp((char *) chunks[i].pointer - PADSIZE, tptr, PADSIZE))
\r
177 return -1; // Prefix corruption
\r
178 if (memcmp((char *) chunks[i].pointer + chunks[i].size, tptr, PADSIZE))
\r
179 return 1; // Suffix corruption
\r
181 return 0; // no corruption
\r
184 void CheckCorruption(void)
\r
188 for (i=0; i<numchunks; i++)
\r
190 j=ChunkIntegrity(i);
\r
192 if (j == -1) { MemReport(); err("Prefix corruption on chunk %d.", i); }
\r
193 if (j == 1) { MemReport(); err("Suffix corruption on chunk %d.", i); }
\r
197 void CheckCorruption(void)
\r