2
===========================================================================
3
Copyright (C) 1999-2005 Id Software, Inc.
5
This file is part of Quake III Arena source code.
7
Quake III Arena source code is free software; you can redistribute it
8
and/or modify it under the terms of the GNU General Public License as
9
published by the Free Software Foundation; either version 2 of the License,
10
or (at your option) any later version.
12
Quake III Arena source code is distributed in the hope that it will be
13
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with Quake III Arena source code; if not, write to the Free Software
19
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
===========================================================================
23
/*****************************************************************************
26
* desc: memory allocation
28
* $Archive: /MissionPack/code/botlib/l_memory.c $
30
*****************************************************************************/
32
#include "../qcommon/q_shared.h"
35
#include "be_interface.h"
38
//#define MEMORYMANEGER
40
#define MEM_ID 0x12345678l
41
#define HUNK_ID 0x87654321l
49
typedef struct memoryblock_s
59
struct memoryblock_s *prev, *next;
62
memoryblock_t *memory;
64
//===========================================================================
69
//===========================================================================
70
void LinkMemoryBlock(memoryblock_t *block)
74
if (memory) memory->prev = block;
76
} //end of the function LinkMemoryBlock
77
//===========================================================================
82
//===========================================================================
83
void UnlinkMemoryBlock(memoryblock_t *block)
85
if (block->prev) block->prev->next = block->next;
86
else memory = block->next;
87
if (block->next) block->next->prev = block->prev;
88
} //end of the function UnlinkMemoryBlock
89
//===========================================================================
94
//===========================================================================
96
void *GetMemoryDebug(unsigned long size, char *label, char *file, int line)
98
void *GetMemory(unsigned long size)
102
memoryblock_t *block;
103
assert(botimport.GetMemory); // bk001129 - was NULL'ed
104
ptr = botimport.GetMemory(size + sizeof(memoryblock_t));
105
block = (memoryblock_t *) ptr;
107
block->ptr = (char *) ptr + sizeof(memoryblock_t);
108
block->size = size + sizeof(memoryblock_t);
110
block->label = label;
114
LinkMemoryBlock(block);
115
allocatedmemory += block->size;
116
totalmemorysize += block->size + sizeof(memoryblock_t);
119
} //end of the function GetMemoryDebug
120
//===========================================================================
124
// Changes Globals: -
125
//===========================================================================
127
void *GetClearedMemoryDebug(unsigned long size, char *label, char *file, int line)
129
void *GetClearedMemory(unsigned long size)
134
ptr = GetMemoryDebug(size, label, file, line);
136
ptr = GetMemory(size);
138
Com_Memset(ptr, 0, size);
140
} //end of the function GetClearedMemory
141
//===========================================================================
145
// Changes Globals: -
146
//===========================================================================
148
void *GetHunkMemoryDebug(unsigned long size, char *label, char *file, int line)
150
void *GetHunkMemory(unsigned long size)
154
memoryblock_t *block;
156
ptr = botimport.HunkAlloc(size + sizeof(memoryblock_t));
157
block = (memoryblock_t *) ptr;
159
block->ptr = (char *) ptr + sizeof(memoryblock_t);
160
block->size = size + sizeof(memoryblock_t);
162
block->label = label;
166
LinkMemoryBlock(block);
167
allocatedmemory += block->size;
168
totalmemorysize += block->size + sizeof(memoryblock_t);
171
} //end of the function GetHunkMemoryDebug
172
//===========================================================================
176
// Changes Globals: -
177
//===========================================================================
179
void *GetClearedHunkMemoryDebug(unsigned long size, char *label, char *file, int line)
181
void *GetClearedHunkMemory(unsigned long size)
186
ptr = GetHunkMemoryDebug(size, label, file, line);
188
ptr = GetHunkMemory(size);
190
Com_Memset(ptr, 0, size);
192
} //end of the function GetClearedHunkMemory
193
//===========================================================================
197
// Changes Globals: -
198
//===========================================================================
199
memoryblock_t *BlockFromPointer(void *ptr, char *str)
201
memoryblock_t *block;
206
//char *crash = (char *) NULL;
208
botimport.Print(PRT_FATAL, "%s: NULL pointer\n", str);
212
block = (memoryblock_t *) ((char *) ptr - sizeof(memoryblock_t));
213
if (block->id != MEM_ID && block->id != HUNK_ID)
215
botimport.Print(PRT_FATAL, "%s: invalid memory block\n", str);
218
if (block->ptr != ptr)
220
botimport.Print(PRT_FATAL, "%s: memory block pointer invalid\n", str);
224
} //end of the function BlockFromPointer
225
//===========================================================================
229
// Changes Globals: -
230
//===========================================================================
231
void FreeMemory(void *ptr)
233
memoryblock_t *block;
235
block = BlockFromPointer(ptr, "FreeMemory");
237
UnlinkMemoryBlock(block);
238
allocatedmemory -= block->size;
239
totalmemorysize -= block->size + sizeof(memoryblock_t);
242
if (block->id == MEM_ID)
244
botimport.FreeMemory(block);
246
} //end of the function FreeMemory
247
//===========================================================================
251
// Changes Globals: -
252
//===========================================================================
253
int AvailableMemory(void)
255
return botimport.AvailableMemory();
256
} //end of the function AvailableMemory
257
//===========================================================================
261
// Changes Globals: -
262
//===========================================================================
263
int MemoryByteSize(void *ptr)
265
memoryblock_t *block;
267
block = BlockFromPointer(ptr, "MemoryByteSize");
268
if (!block) return 0;
270
} //end of the function MemoryByteSize
271
//===========================================================================
275
// Changes Globals: -
276
//===========================================================================
277
void PrintUsedMemorySize(void)
279
botimport.Print(PRT_MESSAGE, "total allocated memory: %d KB\n", allocatedmemory >> 10);
280
botimport.Print(PRT_MESSAGE, "total botlib memory: %d KB\n", totalmemorysize >> 10);
281
botimport.Print(PRT_MESSAGE, "total memory blocks: %d\n", numblocks);
282
} //end of the function PrintUsedMemorySize
283
//===========================================================================
287
// Changes Globals: -
288
//===========================================================================
289
void PrintMemoryLabels(void)
291
memoryblock_t *block;
294
PrintUsedMemorySize();
296
Log_Write("============= Botlib memory log ==============\r\n");
298
for (block = memory; block; block = block->next)
301
if (block->id == HUNK_ID)
303
Log_Write("%6d, hunk %p, %8d: %24s line %6d: %s\r\n", i, block->ptr, block->size, block->file, block->line, block->label);
307
Log_Write("%6d, %p, %8d: %24s line %6d: %s\r\n", i, block->ptr, block->size, block->file, block->line, block->label);
312
} //end of the function PrintMemoryLabels
313
//===========================================================================
317
// Changes Globals: -
318
//===========================================================================
319
void DumpMemory(void)
321
memoryblock_t *block;
323
for (block = memory; block; block = memory)
325
FreeMemory(block->ptr);
329
} //end of the function DumpMemory
333
//===========================================================================
337
// Changes Globals: -
338
//===========================================================================
340
void *GetMemoryDebug(unsigned long size, char *label, char *file, int line)
342
void *GetMemory(unsigned long size)
346
unsigned long int *memid;
348
ptr = botimport.GetMemory(size + sizeof(unsigned long int));
349
if (!ptr) return NULL;
350
memid = (unsigned long int *) ptr;
352
return (unsigned long int *) ((char *) ptr + sizeof(unsigned long int));
353
} //end of the function GetMemory
354
//===========================================================================
358
// Changes Globals: -
359
//===========================================================================
361
void *GetClearedMemoryDebug(unsigned long size, char *label, char *file, int line)
363
void *GetClearedMemory(unsigned long size)
368
ptr = GetMemoryDebug(size, label, file, line);
370
ptr = GetMemory(size);
372
Com_Memset(ptr, 0, size);
374
} //end of the function GetClearedMemory
375
//===========================================================================
379
// Changes Globals: -
380
//===========================================================================
382
void *GetHunkMemoryDebug(unsigned long size, char *label, char *file, int line)
384
void *GetHunkMemory(unsigned long size)
388
unsigned long int *memid;
390
ptr = botimport.HunkAlloc(size + sizeof(unsigned long int));
391
if (!ptr) return NULL;
392
memid = (unsigned long int *) ptr;
394
return (unsigned long int *) ((char *) ptr + sizeof(unsigned long int));
395
} //end of the function GetHunkMemory
396
//===========================================================================
400
// Changes Globals: -
401
//===========================================================================
403
void *GetClearedHunkMemoryDebug(unsigned long size, char *label, char *file, int line)
405
void *GetClearedHunkMemory(unsigned long size)
410
ptr = GetHunkMemoryDebug(size, label, file, line);
412
ptr = GetHunkMemory(size);
414
Com_Memset(ptr, 0, size);
416
} //end of the function GetClearedHunkMemory
417
//===========================================================================
421
// Changes Globals: -
422
//===========================================================================
423
void FreeMemory(void *ptr)
425
unsigned long int *memid;
427
memid = (unsigned long int *) ((char *) ptr - sizeof(unsigned long int));
429
if (*memid == MEM_ID)
431
botimport.FreeMemory(memid);
433
} //end of the function FreeMemory
434
//===========================================================================
438
// Changes Globals: -
439
//===========================================================================
440
int AvailableMemory(void)
442
return botimport.AvailableMemory();
443
} //end of the function AvailableMemory
444
//===========================================================================
448
// Changes Globals: -
449
//===========================================================================
450
void PrintUsedMemorySize(void)
452
} //end of the function PrintUsedMemorySize
453
//===========================================================================
457
// Changes Globals: -
458
//===========================================================================
459
void PrintMemoryLabels(void)
461
} //end of the function PrintMemoryLabels