Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

l_memory.c

Go to the documentation of this file.
00001 /*
00002 ===========================================================================
00003 Copyright (C) 1999-2005 Id Software, Inc.
00004 
00005 This file is part of Quake III Arena source code.
00006 
00007 Quake III Arena source code is free software; you can redistribute it
00008 and/or modify it under the terms of the GNU General Public License as
00009 published by the Free Software Foundation; either version 2 of the License,
00010 or (at your option) any later version.
00011 
00012 Quake III Arena source code is distributed in the hope that it will be
00013 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Foobar; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 ===========================================================================
00021 */
00022 
00023 /*****************************************************************************
00024  * name:        l_memory.c
00025  *
00026  * desc:        memory allocation
00027  *
00028  * $Archive: /MissionPack/code/botlib/l_memory.c $
00029  *
00030  *****************************************************************************/
00031 
00032 #include "../game/q_shared.h"
00033 #include "../game/botlib.h"
00034 #include "l_log.h"
00035 #include "be_interface.h"
00036 
00037 //#define MEMDEBUG
00038 //#define MEMORYMANEGER
00039 
00040 #define MEM_ID      0x12345678l
00041 #define HUNK_ID     0x87654321l
00042 
00043 int allocatedmemory;
00044 int totalmemorysize;
00045 int numblocks;
00046 
00047 #ifdef MEMORYMANEGER
00048 
00049 typedef struct memoryblock_s
00050 {
00051     unsigned long int id;
00052     void *ptr;
00053     int size;
00054 #ifdef MEMDEBUG
00055     char *label;
00056     char *file;
00057     int line;
00058 #endif //MEMDEBUG
00059     struct memoryblock_s *prev, *next;
00060 } memoryblock_t;
00061 
00062 memoryblock_t *memory;
00063 
00064 //===========================================================================
00065 //
00066 // Parameter:           -
00067 // Returns:             -
00068 // Changes Globals:     -
00069 //===========================================================================
00070 void LinkMemoryBlock(memoryblock_t *block)
00071 {
00072     block->prev = NULL;
00073     block->next = memory;
00074     if (memory) memory->prev = block;
00075     memory = block;
00076 } //end of the function LinkMemoryBlock
00077 //===========================================================================
00078 //
00079 // Parameter:           -
00080 // Returns:             -
00081 // Changes Globals:     -
00082 //===========================================================================
00083 void UnlinkMemoryBlock(memoryblock_t *block)
00084 {
00085     if (block->prev) block->prev->next = block->next;
00086     else memory = block->next;
00087     if (block->next) block->next->prev = block->prev;
00088 } //end of the function UnlinkMemoryBlock
00089 //===========================================================================
00090 //
00091 // Parameter:           -
00092 // Returns:             -
00093 // Changes Globals:     -
00094 //===========================================================================
00095 #ifdef MEMDEBUG
00096 void *GetMemoryDebug(unsigned long size, char *label, char *file, int line)
00097 #else
00098 void *GetMemory(unsigned long size)
00099 #endif //MEMDEBUG
00100 {
00101     void *ptr;
00102     memoryblock_t *block;
00103   assert(botimport.GetMemory); // bk001129 - was NULL'ed
00104     ptr = botimport.GetMemory(size + sizeof(memoryblock_t));
00105     block = (memoryblock_t *) ptr;
00106     block->id = MEM_ID;
00107     block->ptr = (char *) ptr + sizeof(memoryblock_t);
00108     block->size = size + sizeof(memoryblock_t);
00109 #ifdef MEMDEBUG
00110     block->label = label;
00111     block->file = file;
00112     block->line = line;
00113 #endif //MEMDEBUG
00114     LinkMemoryBlock(block);
00115     allocatedmemory += block->size;
00116     totalmemorysize += block->size + sizeof(memoryblock_t);
00117     numblocks++;
00118     return block->ptr;
00119 } //end of the function GetMemoryDebug
00120 //===========================================================================
00121 //
00122 // Parameter:           -
00123 // Returns:             -
00124 // Changes Globals:     -
00125 //===========================================================================
00126 #ifdef MEMDEBUG
00127 void *GetClearedMemoryDebug(unsigned long size, char *label, char *file, int line)
00128 #else
00129 void *GetClearedMemory(unsigned long size)
00130 #endif //MEMDEBUG
00131 {
00132     void *ptr;
00133 #ifdef MEMDEBUG
00134     ptr = GetMemoryDebug(size, label, file, line);
00135 #else
00136     ptr = GetMemory(size);
00137 #endif //MEMDEBUG
00138     Com_Memset(ptr, 0, size);
00139     return ptr;
00140 } //end of the function GetClearedMemory
00141 //===========================================================================
00142 //
00143 // Parameter:           -
00144 // Returns:             -
00145 // Changes Globals:     -
00146 //===========================================================================
00147 #ifdef MEMDEBUG
00148 void *GetHunkMemoryDebug(unsigned long size, char *label, char *file, int line)
00149 #else
00150 void *GetHunkMemory(unsigned long size)
00151 #endif //MEMDEBUG
00152 {
00153     void *ptr;
00154     memoryblock_t *block;
00155 
00156     ptr = botimport.HunkAlloc(size + sizeof(memoryblock_t));
00157     block = (memoryblock_t *) ptr;
00158     block->id = HUNK_ID;
00159     block->ptr = (char *) ptr + sizeof(memoryblock_t);
00160     block->size = size + sizeof(memoryblock_t);
00161 #ifdef MEMDEBUG
00162     block->label = label;
00163     block->file = file;
00164     block->line = line;
00165 #endif //MEMDEBUG
00166     LinkMemoryBlock(block);
00167     allocatedmemory += block->size;
00168     totalmemorysize += block->size + sizeof(memoryblock_t);
00169     numblocks++;
00170     return block->ptr;
00171 } //end of the function GetHunkMemoryDebug
00172 //===========================================================================
00173 //
00174 // Parameter:           -
00175 // Returns:             -
00176 // Changes Globals:     -
00177 //===========================================================================
00178 #ifdef MEMDEBUG
00179 void *GetClearedHunkMemoryDebug(unsigned long size, char *label, char *file, int line)
00180 #else
00181 void *GetClearedHunkMemory(unsigned long size)
00182 #endif //MEMDEBUG
00183 {
00184     void *ptr;
00185 #ifdef MEMDEBUG
00186     ptr = GetHunkMemoryDebug(size, label, file, line);
00187 #else
00188     ptr = GetHunkMemory(size);
00189 #endif //MEMDEBUG
00190     Com_Memset(ptr, 0, size);
00191     return ptr;
00192 } //end of the function GetClearedHunkMemory
00193 //===========================================================================
00194 //
00195 // Parameter:           -
00196 // Returns:             -
00197 // Changes Globals:     -
00198 //===========================================================================
00199 memoryblock_t *BlockFromPointer(void *ptr, char *str)
00200 {
00201     memoryblock_t *block;
00202 
00203     if (!ptr)
00204     {
00205 #ifdef MEMDEBUG
00206         //char *crash = (char *) NULL;
00207         //crash[0] = 1;
00208         botimport.Print(PRT_FATAL, "%s: NULL pointer\n", str);
00209 #endif // MEMDEBUG
00210         return NULL;
00211     } //end if
00212     block = (memoryblock_t *) ((char *) ptr - sizeof(memoryblock_t));
00213     if (block->id != MEM_ID && block->id != HUNK_ID)
00214     {
00215         botimport.Print(PRT_FATAL, "%s: invalid memory block\n", str);
00216         return NULL;
00217     } //end if
00218     if (block->ptr != ptr)
00219     {
00220         botimport.Print(PRT_FATAL, "%s: memory block pointer invalid\n", str);
00221         return NULL;
00222     } //end if
00223     return block;
00224 } //end of the function BlockFromPointer
00225 //===========================================================================
00226 //
00227 // Parameter:           -
00228 // Returns:             -
00229 // Changes Globals:     -
00230 //===========================================================================
00231 void FreeMemory(void *ptr)
00232 {
00233     memoryblock_t *block;
00234 
00235     block = BlockFromPointer(ptr, "FreeMemory");
00236     if (!block) return;
00237     UnlinkMemoryBlock(block);
00238     allocatedmemory -= block->size;
00239     totalmemorysize -= block->size + sizeof(memoryblock_t);
00240     numblocks--;
00241     //
00242     if (block->id == MEM_ID)
00243     {
00244         botimport.FreeMemory(block);
00245     } //end if
00246 } //end of the function FreeMemory
00247 //===========================================================================
00248 //
00249 // Parameter:           -
00250 // Returns:             -
00251 // Changes Globals:     -
00252 //===========================================================================
00253 int AvailableMemory(void)
00254 {
00255     return botimport.AvailableMemory();
00256 } //end of the function AvailableMemory
00257 //===========================================================================
00258 //
00259 // Parameter:           -
00260 // Returns:             -
00261 // Changes Globals:     -
00262 //===========================================================================
00263 int MemoryByteSize(void *ptr)
00264 {
00265     memoryblock_t *block;
00266 
00267     block = BlockFromPointer(ptr, "MemoryByteSize");
00268     if (!block) return 0;
00269     return block->size;
00270 } //end of the function MemoryByteSize
00271 //===========================================================================
00272 //
00273 // Parameter:           -
00274 // Returns:             -
00275 // Changes Globals:     -
00276 //===========================================================================
00277 void PrintUsedMemorySize(void)
00278 {
00279     botimport.Print(PRT_MESSAGE, "total allocated memory: %d KB\n", allocatedmemory >> 10);
00280     botimport.Print(PRT_MESSAGE, "total botlib memory: %d KB\n", totalmemorysize >> 10);
00281     botimport.Print(PRT_MESSAGE, "total memory blocks: %d\n", numblocks);
00282 } //end of the function PrintUsedMemorySize
00283 //===========================================================================
00284 //
00285 // Parameter:           -
00286 // Returns:             -
00287 // Changes Globals:     -
00288 //===========================================================================
00289 void PrintMemoryLabels(void)
00290 {
00291     memoryblock_t *block;
00292     int i;
00293 
00294     PrintUsedMemorySize();
00295     i = 0;
00296     Log_Write("============= Botlib memory log ==============\r\n");
00297     Log_Write("\r\n");
00298     for (block = memory; block; block = block->next)
00299     {
00300 #ifdef MEMDEBUG
00301         if (block->id == HUNK_ID)
00302         {
00303             Log_Write("%6d, hunk %p, %8d: %24s line %6d: %s\r\n", i, block->ptr, block->size, block->file, block->line, block->label);
00304         } //end if
00305         else
00306         {
00307             Log_Write("%6d,      %p, %8d: %24s line %6d: %s\r\n", i, block->ptr, block->size, block->file, block->line, block->label);
00308         } //end else
00309 #endif //MEMDEBUG
00310         i++;
00311     } //end for
00312 } //end of the function PrintMemoryLabels
00313 //===========================================================================
00314 //
00315 // Parameter:           -
00316 // Returns:             -
00317 // Changes Globals:     -
00318 //===========================================================================
00319 void DumpMemory(void)
00320 {
00321     memoryblock_t *block;
00322 
00323     for (block = memory; block; block = memory)
00324     {
00325         FreeMemory(block->ptr);
00326     } //end for
00327     totalmemorysize = 0;
00328     allocatedmemory = 0;
00329 } //end of the function DumpMemory
00330 
00331 #else
00332 
00333 //===========================================================================
00334 //
00335 // Parameter:           -
00336 // Returns:             -
00337 // Changes Globals:     -
00338 //===========================================================================
00339 #ifdef MEMDEBUG
00340 void *GetMemoryDebug(unsigned long size, char *label, char *file, int line)
00341 #else
00342 void *GetMemory(unsigned long size)
00343 #endif //MEMDEBUG
00344 {
00345     void *ptr;
00346     unsigned long int *memid;
00347 
00348     ptr = botimport.GetMemory(size + sizeof(unsigned long int));
00349     if (!ptr) return NULL;
00350     memid = (unsigned long int *) ptr;
00351     *memid = MEM_ID;
00352     return (unsigned long int *) ((char *) ptr + sizeof(unsigned long int));
00353 } //end of the function GetMemory
00354 //===========================================================================
00355 //
00356 // Parameter:           -
00357 // Returns:             -
00358 // Changes Globals:     -
00359 //===========================================================================
00360 #ifdef MEMDEBUG
00361 void *GetClearedMemoryDebug(unsigned long size, char *label, char *file, int line)
00362 #else
00363 void *GetClearedMemory(unsigned long size)
00364 #endif //MEMDEBUG
00365 {
00366     void *ptr;
00367 #ifdef MEMDEBUG
00368     ptr = GetMemoryDebug(size, label, file, line);
00369 #else
00370     ptr = GetMemory(size);
00371 #endif //MEMDEBUG
00372     Com_Memset(ptr, 0, size);
00373     return ptr;
00374 } //end of the function GetClearedMemory
00375 //===========================================================================
00376 //
00377 // Parameter:           -
00378 // Returns:             -
00379 // Changes Globals:     -
00380 //===========================================================================
00381 #ifdef MEMDEBUG
00382 void *GetHunkMemoryDebug(unsigned long size, char *label, char *file, int line)
00383 #else
00384 void *GetHunkMemory(unsigned long size)
00385 #endif //MEMDEBUG
00386 {
00387     void *ptr;
00388     unsigned long int *memid;
00389 
00390     ptr = botimport.HunkAlloc(size + sizeof(unsigned long int));
00391     if (!ptr) return NULL;
00392     memid = (unsigned long int *) ptr;
00393     *memid = HUNK_ID;
00394     return (unsigned long int *) ((char *) ptr + sizeof(unsigned long int));
00395 } //end of the function GetHunkMemory
00396 //===========================================================================
00397 //
00398 // Parameter:           -
00399 // Returns:             -
00400 // Changes Globals:     -
00401 //===========================================================================
00402 #ifdef MEMDEBUG
00403 void *GetClearedHunkMemoryDebug(unsigned long size, char *label, char *file, int line)
00404 #else
00405 void *GetClearedHunkMemory(unsigned long size)
00406 #endif //MEMDEBUG
00407 {
00408     void *ptr;
00409 #ifdef MEMDEBUG
00410     ptr = GetHunkMemoryDebug(size, label, file, line);
00411 #else
00412     ptr = GetHunkMemory(size);
00413 #endif //MEMDEBUG
00414     Com_Memset(ptr, 0, size);
00415     return ptr;
00416 } //end of the function GetClearedHunkMemory
00417 //===========================================================================
00418 //
00419 // Parameter:           -
00420 // Returns:             -
00421 // Changes Globals:     -
00422 //===========================================================================
00423 void FreeMemory(void *ptr)
00424 {
00425     unsigned long int *memid;
00426 
00427     memid = (unsigned long int *) ((char *) ptr - sizeof(unsigned long int));
00428 
00429     if (*memid == MEM_ID)
00430     {
00431         botimport.FreeMemory(memid);
00432     } //end if
00433 } //end of the function FreeMemory
00434 //===========================================================================
00435 //
00436 // Parameter:           -
00437 // Returns:             -
00438 // Changes Globals:     -
00439 //===========================================================================
00440 int AvailableMemory(void)
00441 {
00442     return botimport.AvailableMemory();
00443 } //end of the function AvailableMemory
00444 //===========================================================================
00445 //
00446 // Parameter:           -
00447 // Returns:             -
00448 // Changes Globals:     -
00449 //===========================================================================
00450 void PrintUsedMemorySize(void)
00451 {
00452 } //end of the function PrintUsedMemorySize
00453 //===========================================================================
00454 //
00455 // Parameter:           -
00456 // Returns:             -
00457 // Changes Globals:     -
00458 //===========================================================================
00459 void PrintMemoryLabels(void)
00460 {
00461 } //end of the function PrintMemoryLabels
00462 
00463 #endif

Generated on Thu Aug 25 12:37:12 2005 for Quake III Arena by  doxygen 1.3.9.1