]> 4ch.mooo.com Git - 16.git/blobdiff - 16/v2/source/MAPED/A_MEMORY.C
refresh wwww
[16.git] / 16 / v2 / source / MAPED / A_MEMORY.C
diff --git a/16/v2/source/MAPED/A_MEMORY.C b/16/v2/source/MAPED/A_MEMORY.C
new file mode 100755 (executable)
index 0000000..c8f1598
--- /dev/null
@@ -0,0 +1,211 @@
+/*\r
+Copyright (C) 1998 BJ Eirich (aka vecna)\r
+This program is free software; you can redistribute it and/or\r
+modify it under the terms of the GNU General Public License\r
+as published by the Free Software Foundation; either version 2\r
+of the License, or (at your option) any later version.\r
+This program is distributed in the hope that it will be useful,\r
+but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\r
+See the GNU General Public Lic\r
+See the GNU General Public License for more details.\r
+You should have received a copy of the GNU General Public License\r
+along with this program; if not, write to the Free Software\r
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
+*/\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+void err(char *str, ...);\r
+void Log(char *str, ...);\r
+\r
+// *****\r
+// TODO: Move the chunk list from an array to a linked list?\r
+//       Would eliminate hardcoded chunk limit, but would make\r
+//       general operation slower. Probably not The Right Thing,\r
+//       sides the chunk limit can be interesting sometimes. If\r
+//       it becomes problematic, consider a Binary Tree.\r
+// *****\r
+\r
+// ***************************** Data *****************************\r
+\r
+#define MAXCHUNKS 200\r
+#define PARANOID 1\r
+#define PADFILLVALUE 254\r
+#define PADSIZE 256\r
+\r
+void MemReport(void);\r
+\r
+#define errm MemReport(), err\r
+\r
+typedef struct\r
+{\r
+   void *pointer;\r
+   int  size;\r
+   int  owner;\r
+   char desc[20];\r
+} memblockType;\r
+\r
+memblockType chunks[MAXCHUNKS+1];\r
+int numchunks=0;\r
+\r
+// ***************************** Code *****************************\r
+\r
+void *valloc(int amount, char *desc, int owner)\r
+{\r
+   if (numchunks == MAXCHUNKS)\r
+     err("Failed allocated %d bytes (%s), reason: Out of chunks.",\r
+        amount, desc);\r
+\r
+#ifdef PARANOID\r
+   CheckCorruption();\r
+   chunks[numchunks].pointer = (void *) ((int) malloc(amount + (PADSIZE * 2)) + PADSIZE);\r
+   chunks[numchunks].size = amount;\r
+   memset((char *) chunks[numchunks].pointer - PADSIZE, PADFILLVALUE, PADSIZE);\r
+   memset((char *) chunks[numchunks].pointer +\r
+               chunks[numchunks].size, PADFILLVALUE, PADSIZE);\r
+#else\r
+   chunks[numchunks].pointer = malloc(amount);\r
+   chunks[numchunks].size = amount;\r
+#endif\r
+   chunks[numchunks].owner = owner;\r
+   strncpy(chunks[numchunks].desc, desc, 19);\r
+   memset(chunks[numchunks].pointer, 0, chunks[numchunks].size);\r
+   return chunks[numchunks++].pointer;\r
+}\r
+\r
+void *qvalloc(int amount)\r
+{\r
+   void *ptr;\r
+\r
+   // Quick and dirty memory allocation. Should be used ONLY\r
+   // for temporary blocks in speed-critical loops.\r
+\r
+   ptr = malloc(amount);\r
+   if (!ptr) errm("qvalloc: Failed allocating %d bytes.", amount);\r
+   return ptr;\r
+}\r
+\r
+void qvfree(void *ptr)\r
+{\r
+   free(ptr);\r
+}\r
+\r
+int TotalBytesAllocated(void)\r
+{\r
+   int i, tally=0;\r
+\r
+   for (i=0; i<numchunks; i++)\r
+      tally += chunks[i].size;\r
+\r
+   return tally;\r
+}\r
+\r
+int FindChunk(void *pointer)\r
+{\r
+   int i;\r
+\r
+   for (i=0; i<numchunks; i++)\r
+      if (chunks[i].pointer == pointer) return i;\r
+   return -1;\r
+}\r
+\r
+void FreeChunk(int i)\r
+{\r
+#ifdef PARANOID\r
+   CheckCorruption();\r
+   free((void *) ((int) chunks[i].pointer - PADSIZE));\r
+#else\r
+   free(chunks[i].pointer);\r
+#endif\r
+   for (; i<numchunks; i++)\r
+      chunks[i]=chunks[i+1];\r
+   numchunks--;\r
+}\r
+\r
+int vfree(void *pointer)\r
+{\r
+   int i;\r
+\r
+   i=FindChunk(pointer);\r
+   if (i == -1)\r
+   {\r
+      Log("vfree: Attempted to free ptr %u that was not allocated. [dumping mem report]", pointer);\r
+      MemReport();\r
+      return -1;\r
+   }\r
+   FreeChunk(i);\r
+\r
+   return 0;\r
+}\r
+\r
+void FreeByOwner(int owner)\r
+{\r
+   int i;\r
+\r
+   for (i=0; i<numchunks; i++)\r
+      if (chunks[i].owner == owner)\r
+         FreeChunk(i--);\r
+}\r
+\r
+void MemReport(void)\r
+{\r
+   int i;\r
+\r
+   Log("");\r
+   Log("========================================");\r
+   Log("= Memory usage report for this session =");\r
+   Log("========================================");\r
+   Log("Chunks currently allocated: %d (MAXCHUNKS %d)", numchunks, MAXCHUNKS);\r
+   Log("%d total bytes allocated. ", TotalBytesAllocated());\r
+#ifdef PARANOID\r
+   Log("PARANOID is ON. (pad size: %d pad value: %d)", PADSIZE, PADFILLVALUE);\r
+#else\r
+   Log("PARANOID is OFF.");\r
+#endif\r
+   Log("");\r
+   Log("Per-chunk analysis: ");\r
+\r
+   for (i=0; i<numchunks; i++)\r
+   {\r
+       Log("[%3d] Ptr at: %8u size: %8d owner: %3d desc: %s",\r
+          i, chunks[i].pointer, chunks[i].size, chunks[i].owner, chunks[i].desc);\r
+   }\r
+\r
+}\r
+\r
+#ifdef PARANOID\r
+int ChunkIntegrity(int i)\r
+{\r
+   char *tptr;\r
+\r
+   tptr=(char *) malloc(PADSIZE);\r
+   memset(tptr, PADFILLVALUE, PADSIZE);\r
+   if (memcmp((char *) chunks[i].pointer - PADSIZE, tptr, PADSIZE))\r
+      return -1;      // Prefix corruption\r
+   if (memcmp((char *) chunks[i].pointer + chunks[i].size, tptr, PADSIZE))\r
+      return 1;       // Suffix corruption\r
+   free(tptr);\r
+   return 0;          // no corruption\r
+}\r
+\r
+void CheckCorruption(void)\r
+{\r
+   int i, j;\r
+\r
+   for (i=0; i<numchunks; i++)\r
+   {\r
+      j=ChunkIntegrity(i);\r
+      if (!j) continue;\r
+      if (j == -1) errm("Prefix corruption on chunk %d.", i);\r
+      if (j ==  1) errm("Suffix corruption on chunk %d.", i);\r
+   }\r
+}\r
+#else\r
+void CheckCorruption(void)\r
+{\r
+   return;\r
+}\r
+#endif\r