UFO: Alien Invasion
Doxygen documentation generating
mem.cpp
Go to the documentation of this file.
1 
6 /*
7 All original material Copyright (C) 2002-2023 UFO: Alien Invasion.
8 
9 Original file from Quake 2 v3.21: quake2-2.31/game/q_shared.c
10 Copyright (C) 1997-2001 Id Software, Inc.
11 
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License
14 as published by the Free Software Foundation; either version 2
15 of the License, or (at your option) any later version.
16 
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20 
21 See the GNU General Public License for more details.
22 
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 
27 */
28 
29 #include "common.h"
30 #include <SDL_thread.h>
31 
32 #define MEM_MAX_POOLNAME 64
33 #define MEM_HASH 11
34 
36  uint32_t sentinel;
37 };
38 
39 struct memBlock_t {
41 
42  uint32_t topSentinel;
45  int tagNum;
47  char const* allocFile;
48  int allocLine;
50  size_t memSize;
52  uint32_t botSentinel;
53 };
54 
55 struct memPool_t {
57  bool inUse;
61  uint32_t blockCount;
62  uint32_t byteCount;
64  char const* createFile;
65  int createLine;
66 };
67 
68 #define MEM_HEAD_SENTINEL_TOP 0xFEBDFAED
69 #define MEM_HEAD_SENTINEL_BOT 0xD0BAF0FF
70 #define MEM_FOOT_SENTINEL 0xF00DF00D
71 
72 static SDL_mutex* z_lock;
73 
74 #define MEM_MAX_POOLCOUNT 32
75 
77 static uint32_t m_numPools;
78 
79 /*==============================================================================
80 POOL MANAGEMENT
81 ==============================================================================*/
82 
83 static memPool_t* Mem_FindPool (const char* name)
84 {
85  memPool_t* pool;
86  uint32_t i;
87 
88  for (i = 0, pool = &m_poolList[0]; i < m_numPools; pool++, i++) {
89  if (!pool->inUse)
90  continue;
91  if (!Q_streq(name, pool->name))
92  continue;
93 
94  return pool;
95  }
96 
97  return nullptr;
98 }
99 
103 memPool_t* _Mem_CreatePool (const char* name, const char* fileName, const int fileLine)
104 {
105  /* Check name */
106  if (!name || !name[0])
107  Sys_Error("Mem_CreatePool: nullptr name %s:#%i", fileName, fileLine);
108  if (strlen(name) + 1 >= MEM_MAX_POOLNAME)
109  Com_Printf("Mem_CreatePoole: name '%s' too long, truncating!\n", name);
110 
111  /* See if it already exists */
112  memPool_t* pool = Mem_FindPool(name);
113  if (pool)
114  return pool;
115 
116  /* Nope, create a slot */
117  uint32_t i;
118  for (i = 0, pool = &m_poolList[0]; i < m_numPools; pool++, i++) {
119  if (!pool->inUse)
120  break;
121  }
122  if (i == m_numPools) {
123  if (m_numPools + 1 >= MEM_MAX_POOLCOUNT)
124  Sys_Error("Mem_CreatePool: MEM_MAX_POOLCOUNT");
125  pool = &m_poolList[m_numPools++];
126  }
127 
128  /* Store values */
129  for (i = 0; i < MEM_HASH; i++)
130  pool->blocks[i] = nullptr;
131  pool->blockCount = 0;
132  pool->byteCount = 0;
133  pool->createFile = fileName;
134  pool->createLine = fileLine;
135  pool->inUse = true;
136  Q_strncpyz(pool->name, name, sizeof(pool->name));
137 
138  return pool;
139 }
140 
146 void _Mem_DeletePool (memPool_t* pool, const char* fileName, const int fileLine)
147 {
148  if (!pool)
149  return;
150 
151  /* Release all allocated memory */
152  _Mem_FreePool(pool, fileName, fileLine);
153 
154  /* Simple, yes? */
155  pool->inUse = false;
156  pool->name[0] = '\0';
157 }
158 
159 /*==============================================================================
160 POOL AND TAG MEMORY ALLOCATION
161 ==============================================================================*/
162 
163 static memBlock_t* Mem_PtrToBlock(void* const ptr)
164 {
165  return static_cast<memBlock_t*>(ptr) - 1;
166 }
167 
168 static void* Mem_BlockToPtr(memBlock_t* const mem)
169 {
170  return mem + 1;
171 }
172 
174 {
175  return reinterpret_cast<memBlockFoot_t*>(reinterpret_cast<byte*>(Mem_BlockToPtr(mem)) + mem->memSize);
176 }
177 
178 static size_t Mem_BlockRawSize(memBlock_t const* const mem)
179 {
180  return mem->memSize + sizeof(memBlock_t) + sizeof(memBlockFoot_t);
181 }
182 
183 static void _Mem_CheckSentinels (memBlock_t* const mem, const char* fileName, const int fileLine)
184 {
185  /* Check sentinels */
186  if (mem->topSentinel != MEM_HEAD_SENTINEL_TOP) {
187  Sys_Error("Mem_CheckSentinels: bad memory header top sentinel [buffer underflow]\n"
188  "free: %s:#%i", fileName, fileLine);
189  } else if (mem->botSentinel != MEM_HEAD_SENTINEL_BOT) {
190  Sys_Error("Mem_CheckSentinels: bad memory header bottom sentinel [buffer underflow]\n"
191  "free: %s:#%i", fileName, fileLine);
192  } else if (Mem_BlockToFooter(mem)->sentinel != MEM_FOOT_SENTINEL) {
193  Sys_Error("Mem_CheckSentinels: bad memory footer sentinel [buffer overflow]\n"
194  "pool: %s\n"
195  "alloc: %s:#%i\n"
196  "free: %s:#%i",
197  mem->pool ? mem->pool->name : "UNKNOWN", mem->allocFile, mem->allocLine, fileName, fileLine);
198  }
199 }
200 
204 void _Mem_Free (void* ptr, const char* fileName, const int fileLine)
205 {
206  if (!ptr)
207  return;
208 
209  memBlock_t* const mem = Mem_PtrToBlock(ptr);
210  _Mem_CheckSentinels(mem, fileName, fileLine);
211 
212  if (z_lock != nullptr)
213  SDL_LockMutex(z_lock);
214 
215  /* Decrement counters */
216  mem->pool->blockCount--;
217  mem->pool->byteCount -= Mem_BlockRawSize(mem);
218 
219  /* De-link it */
220  memBlock_t** prev = &mem->pool->blocks[(uintptr_t)mem % MEM_HASH];
221  for (;;) {
222  memBlock_t* search = *prev;
223  if (!search)
224  break;
225 
226  if (search == mem) {
227  *prev = search->next;
228  break;
229  }
230  prev = &search->next;
231  }
232 
233  if (z_lock != nullptr)
234  SDL_UnlockMutex(z_lock);
235 
236  /* Free it */
237  free(mem);
238 }
239 
243 void _Mem_FreeTag (memPool_t* pool, const int tagNum, const char* fileName, const int fileLine)
244 {
245  if (!pool)
246  return;
247 
248  for (int j = 0; j < MEM_HASH; j++) {
249  for (memBlock_t* mem = pool->blocks[j], *next = nullptr; mem; mem = next) {
250  next = mem->next;
251  if (mem->tagNum == tagNum)
252  _Mem_Free(Mem_BlockToPtr(mem), fileName, fileLine);
253  }
254  }
255 }
256 
262 void _Mem_FreePool (memPool_t* pool, const char* fileName, const int fileLine)
263 {
264  if (!pool)
265  return;
266 
267  for (int j = 0; j < MEM_HASH; j++) {
268  for (memBlock_t* mem = pool->blocks[j], *next = nullptr; mem; mem = next) {
269  next = mem->next;
270  _Mem_Free(Mem_BlockToPtr(mem), fileName, fileLine);
271  }
272  }
273 
274  assert(pool->blockCount == 0);
275  assert(pool->byteCount == 0);
276 }
277 
281 void* _Mem_Alloc (size_t size, bool zeroFill, memPool_t* pool, const int tagNum, const char* fileName, const int fileLine)
282 {
283  /* Check pool */
284  if (!pool)
285  Sys_Error("Mem_Alloc: Error - no pool given\n" "alloc: %s:#%i", fileName, fileLine);
286 
287  /* Check size */
288  if (size <= 0)
289  Sys_Error("Mem_Alloc: Attempted allocation of '" UFO_SIZE_T "' memory ignored\n" "alloc: %s:#%i", size, fileName, fileLine);
290 
291  if (size > 0x40000000)
292  Sys_Error("Mem_Alloc: Attempted allocation of '" UFO_SIZE_T "' bytes!\n" "alloc: %s:#%i", size, fileName, fileLine);
293 
294  /* Add header and round to cacheline */
295  size = (size + sizeof(memBlock_t) + sizeof(memBlockFoot_t) + 31) & ~31;
296  memBlock_t* mem = static_cast<memBlock_t* >(malloc(size));
297  if (!mem)
298  Sys_Error("Mem_Alloc: failed on allocation of '" UFO_SIZE_T "' bytes\n" "alloc: %s:#%i", size, fileName, fileLine);
299 
300  /* Zero fill */
301  if (zeroFill)
302  memset(mem, 0, size);
303 
304  /* Fill in the header */
306  mem->tagNum = tagNum;
307  mem->memSize = size - sizeof(memBlock_t) - sizeof(memBlockFoot_t);
308  mem->pool = pool;
309  mem->allocFile = fileName;
310  mem->allocLine = fileLine;
312 
313  /* Fill in the footer */
315 
316  if (z_lock != nullptr)
317  SDL_LockMutex(z_lock);
318 
319  /* For integrity checking and stats */
320  pool->blockCount++;
321  pool->byteCount += size;
322 
323  /* Link it in to the appropriate pool */
324  mem->next = pool->blocks[(uintptr_t)mem % MEM_HASH];
325  pool->blocks[(uintptr_t)mem % MEM_HASH] = mem;
326 
327  if (z_lock != nullptr)
328  SDL_UnlockMutex(z_lock);
329 
330  return Mem_BlockToPtr(mem);
331 }
332 
333 void* _Mem_ReAlloc (void* ptr, size_t size, const char* fileName, const int fileLine)
334 {
335  if (!size)
336  Sys_Error("Use Mem_Free instead");
337 
338  if (!ptr)
339  Sys_Error("Use Mem_Alloc instead");
340 
341  memBlock_t* const mem = Mem_PtrToBlock(ptr);
342  _Mem_CheckSentinels(mem, fileName, fileLine);
343 
344  /* if size matches, do nothing */
345  if (mem->memSize == size)
346  return ptr;
347 
348  memPool_t* pool = mem->pool;
349 
350  /* allocate memory for the new size */
351  void* newPtr = _Mem_Alloc(size, false, pool, mem->tagNum, fileName, fileLine);
352 
353  /* copy old data */
354  memcpy(newPtr, ptr, std::min(mem->memSize, size));
355  if (mem->memSize < size) {
356  const size_t delta = size - mem->memSize;
357  memset((byte*)newPtr + mem->memSize, 0, delta);
358  }
359 
360  /* if there was old data, free it */
361  _Mem_Free(ptr, fileName, fileLine);
362 
363  _Mem_CheckSentinels(Mem_PtrToBlock(newPtr), fileName, fileLine);
364 
365  return newPtr;
366 }
367 
368 /*==============================================================================
369 MISC FUNCTIONS
370 ==============================================================================*/
371 
381 char* _Mem_PoolStrDupTo (const char* in, char** out, memPool_t* pool, const int tagNum, const char* fileName, const int fileLine)
382 {
383  if (!out)
384  return nullptr;
385  *out = _Mem_PoolStrDup(in, pool, tagNum, fileName, fileLine);
386  return *out;
387 }
388 
389 void* _Mem_PoolDup (const void* in, size_t size, memPool_t* pool, const int tagNum, const char* fileName, const int fileLine)
390 {
391  assert(in != nullptr);
392  assert(size > 0);
393 
394  void* copy = _Mem_Alloc(size, false, pool, tagNum, fileName, fileLine);
395  memcpy(copy, in, size);
396  return copy;
397 }
398 
407 char* _Mem_PoolStrDup (const char* in, memPool_t* pool, const int tagNum, const char* fileName, const int fileLine)
408 {
409  char* out = (char*)_Mem_Alloc((size_t)(strlen(in) + 1), true, pool, tagNum, fileName, fileLine);
410  strcpy(out, in);
411 
412  return out;
413 }
414 
418 uint32_t _Mem_PoolSize (memPool_t* pool)
419 {
420  if (!pool)
421  return 0;
422 
423  return pool->byteCount;
424 }
425 
426 uint32_t _Mem_ChangeTag (memPool_t* pool, const int tagFrom, const int tagTo)
427 {
428  if (!pool)
429  return 0;
430 
431  uint32_t numChanged = 0;
432 
433  for (int j = 0; j < MEM_HASH; j++) {
434  for (memBlock_t* mem = pool->blocks[j]; mem; mem = mem->next) {
435  if (mem->tagNum == tagFrom) {
436  mem->tagNum = tagTo;
437  numChanged++;
438  }
439  }
440  }
441 
442  return numChanged;
443 }
444 
445 static void _Mem_CheckPoolIntegrity (memPool_t* pool, const char* fileName, const int fileLine)
446 {
447  uint32_t blocks;
448  uint32_t size;
449  int j = 0;
450 
451  assert(pool);
452  if (!pool)
453  return;
454 
455  /* Check sentinels */
456  for (j = 0, blocks = 0, size = 0; j < MEM_HASH; j++) {
457  for (memBlock_t* mem = pool->blocks[j]; mem; blocks++, mem = mem->next) {
458  size += Mem_BlockRawSize(mem);
459  _Mem_CheckSentinels(mem, fileName, fileLine);
460  }
461  }
462 
463  /* Check block/byte counts */
464  if (pool->blockCount != blocks)
465  Sys_Error("Mem_CheckPoolIntegrity: bad block count\n" "check: %s:#%i", fileName, fileLine);
466  if (pool->byteCount != size)
467  Sys_Error("Mem_CheckPoolIntegrity: bad pool size\n" "check: %s:#%i", fileName, fileLine);
468 }
469 
470 void _Mem_CheckGlobalIntegrity (const char* fileName, const int fileLine)
471 {
472  memPool_t* pool;
473  uint32_t i;
474 
475  for (i = 0, pool = &m_poolList[0]; i < m_numPools; pool++, i++) {
476  if (pool->inUse)
477  _Mem_CheckPoolIntegrity(pool, fileName, fileLine);
478  }
479 }
480 
486 bool _Mem_AllocatedInPool (memPool_t* pool, const void* pointer)
487 {
488  if (!pool)
489  return false;
490 
491  /* if it's in the pool, it must be in THIS block */
492  memBlock_t* mem = pool->blocks[(uintptr_t)pointer % MEM_HASH];
493  /* Cycle through the blocks */
494  for ( ; mem; mem = mem->next) {
495  if (Mem_BlockToPtr(mem) == pointer)
496  return true;
497  }
498 
499  return false;
500 }
501 
506 void Mem_Init (void)
507 {
508  z_lock = SDL_CreateMutex();
509  if (z_lock == nullptr)
510  Sys_Error("Mem_Init: Cannot create mutex for memory management: %s", SDL_GetError());
511 }
512 
518 void Mem_Shutdown (void)
519 {
520  memPool_t* pool;
521  int i;
522 
523  /* don't use cvars, debug print or anything else inside of this loop
524  * the mem you are trying to use here might already be wiped away */
525  for (i = 0, pool = &m_poolList[0]; i < m_numPools; pool++, i++) {
526  if (!pool->inUse)
527  continue;
528  Mem_DeletePool(pool);
529  }
530 
531  if (z_lock != nullptr)
532  SDL_DestroyMutex(z_lock);
533  z_lock = nullptr;
534 }
535 
536 #ifdef COMPILE_UFO
537 /*==============================================================================
538 CONSOLE COMMANDS
539 ==============================================================================*/
540 
541 static void Mem_Check_f (void)
542 {
544 }
545 
546 static void Mem_Stats_f (void)
547 {
548  uint32_t totalBytes, i;
549  memPool_t* pool;
550 
551  if (Cmd_Argc() > 1) {
552  memPool_t* best;
553  memBlock_t* mem;
554 
555  best = nullptr;
556  for (i = 0, pool = &m_poolList[0]; i < m_numPools; pool++, i++) {
557  if (!pool->inUse)
558  continue;
559  if (strstr(pool->name, Cmd_Args())) {
560  if (best) {
561  Com_Printf("Too many matches for '%s'...\n", Cmd_Args());
562  return;
563  }
564  best = pool;
565  }
566  }
567  if (!best) {
568  Com_Printf("No matches for '%s'...\n", Cmd_Args());
569  return;
570  }
571 
572  Com_Printf("Pool stats for '%s':\n", best->name);
573  Com_Printf("block line file size \n");
574  Com_Printf("----- ----- -------------------- ---------- \n");
575 
576  uint32_t totalBytes = 0;
577  int j = 0;
578  for (j = 0; j < MEM_HASH; j++) {
579  for (i = 0, mem = best->blocks[j]; mem; mem = mem->next, i++) {
580  if (i & 1)
582 
583  size_t const size = Mem_BlockRawSize(mem);
584 
585  Com_Printf("%5i %5i %20s " UFO_SIZE_T "B\n", i + 1, mem->allocLine, mem->allocFile, size);
586 
587  totalBytes += size;
588  }
589  }
590 
591  Com_Printf("----------------------------------------\n");
592  Com_Printf("Total: %i blocks, %i bytes (%6.3fMB)\n", i, totalBytes, totalBytes/1048576.0f);
593  return;
594  }
595 
596  Com_Printf("Memory stats:\n");
597  Com_Printf(" blocks size name\n");
598  Com_Printf("--- ------ ---------- ---------- --------\n");
599 
600  uint32_t totalBlocks = 0;
601  totalBytes = 0;
602  uint32_t poolNum = 0;
603  for (i = 0, pool = &m_poolList[0]; i < m_numPools; pool++, i++) {
604  if (!pool->inUse)
605  continue;
606 
607  poolNum++;
608  if (poolNum & 1)
610 
611  Com_Printf("#%2i %6i %9iB (%6.3fMB) %s\n", poolNum, pool->blockCount, pool->byteCount, pool->byteCount/1048576.0f, pool->name);
612 
613  totalBlocks += pool->blockCount;
614  totalBytes += pool->byteCount;
615  }
616 
617  Com_Printf("----------------------------------------\n");
618  Com_Printf("Total: %i pools, %i blocks, %i bytes (%6.3fMB)\n", i, totalBlocks, totalBytes, totalBytes/1048576.0f);
619 }
620 
624 static const cmdList_t memCallbacks[] = {
625  {"mem_stats", Mem_Stats_f, "Prints out current internal memory statistics"},
626  {"mem_check", Mem_Check_f, "Checks global memory integrity"},
627  {nullptr, nullptr, nullptr}
628 };
629 
633 void Mem_InitCallbacks (void)
634 {
635  Cmd_TableAddList(memCallbacks);
636 }
637 
641 void Mem_ShutdownCallbacks (void)
642 {
643  Cmd_TableRemoveList(memCallbacks);
644 }
645 #endif
int tagNum
Definition: mem.cpp:45
int createLine
Definition: mem.cpp:65
void Sys_Error(const char *error,...)
Definition: g_main.cpp:421
#define MEM_HEAD_SENTINEL_BOT
Definition: mem.cpp:69
static void * Mem_BlockToPtr(memBlock_t *const mem)
Definition: mem.cpp:168
void Mem_Shutdown(void)
Definition: mem.cpp:518
void * _Mem_PoolDup(const void *in, size_t size, memPool_t *pool, const int tagNum, const char *fileName, const int fileLine)
Definition: mem.cpp:389
char const * allocFile
Definition: mem.cpp:47
uint32_t topSentinel
Definition: mem.cpp:42
static uint32_t m_numPools
Definition: mem.cpp:77
void * _Mem_Alloc(size_t size, bool zeroFill, memPool_t *pool, const int tagNum, const char *fileName, const int fileLine)
Optionally returns 0 filled memory allocated in a pool with a tag.
Definition: mem.cpp:281
QGL_EXTERN GLint GLenum GLboolean GLsizei const GLvoid * pointer
Definition: r_gl.h:94
static memPool_t * Mem_FindPool(const char *name)
Definition: mem.cpp:83
voidpf void uLong size
Definition: ioapi.h:42
#define MEM_MAX_POOLCOUNT
Definition: mem.cpp:74
#define MEM_FOOT_SENTINEL
Definition: mem.cpp:70
void Com_Printf(const char *const fmt,...)
Definition: common.cpp:386
uint32_t _Mem_PoolSize(memPool_t *pool)
Definition: mem.cpp:418
#define MEM_MAX_POOLNAME
Definition: mem.cpp:32
void Cmd_TableRemoveList(const cmdList_t *cmdList)
Definition: cmd.cpp:859
uint32_t _Mem_ChangeTag(memPool_t *pool, const int tagFrom, const int tagTo)
Definition: mem.cpp:426
char * _Mem_PoolStrDupTo(const char *in, char **out, memPool_t *pool, const int tagNum, const char *fileName, const int fileLine)
Saves a string to client hunk.
Definition: mem.cpp:381
#define Mem_CheckGlobalIntegrity()
Definition: mem.h:54
static memBlockFoot_t * Mem_BlockToFooter(memBlock_t *const mem)
Definition: mem.cpp:173
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
Definition: shared.cpp:457
bool _Mem_AllocatedInPool(memPool_t *pool, const void *pointer)
Definition: mem.cpp:486
void _Mem_Free(void *ptr, const char *fileName, const int fileLine)
Definition: mem.cpp:204
void _Mem_CheckGlobalIntegrity(const char *fileName, const int fileLine)
Definition: mem.cpp:470
static void _Mem_CheckSentinels(memBlock_t *const mem, const char *fileName, const int fileLine)
Definition: mem.cpp:183
void _Mem_FreePool(memPool_t *pool, const char *fileName, const int fileLine)
Free all items within a pool.
Definition: mem.cpp:262
int allocLine
Definition: mem.cpp:48
static size_t Mem_BlockRawSize(memBlock_t const *const mem)
Definition: mem.cpp:178
uint32_t botSentinel
Definition: mem.cpp:52
int Cmd_Argc(void)
Return the number of arguments of the current command. "command parameter" will result in a argc of 2...
Definition: cmd.cpp:505
char const * createFile
Definition: mem.cpp:64
uint32_t blockCount
Definition: mem.cpp:61
static void _Mem_CheckPoolIntegrity(memPool_t *pool, const char *fileName, const int fileLine)
Definition: mem.cpp:445
memPool_t * pool
Definition: mem.cpp:44
#define Mem_DeletePool(pool)
Definition: mem.h:33
#define MEM_HEAD_SENTINEL_TOP
Definition: mem.cpp:68
void * _Mem_ReAlloc(void *ptr, size_t size, const char *fileName, const int fileLine)
Definition: mem.cpp:333
#define S_COLOR_GREEN
Definition: common.h:219
static memBlock_t * Mem_PtrToBlock(void *const ptr)
Definition: mem.cpp:163
memPool_t * _Mem_CreatePool(const char *name, const char *fileName, const int fileLine)
Definition: mem.cpp:103
QGL_EXTERN GLfloat f
Definition: r_gl.h:114
static SDL_mutex * z_lock
Definition: mem.cpp:72
char * _Mem_PoolStrDup(const char *in, memPool_t *pool, const int tagNum, const char *fileName, const int fileLine)
No need to null terminate the extra spot because Mem_Alloc returns zero-filled memory.
Definition: mem.cpp:407
QGL_EXTERN GLint i
Definition: r_gl.h:113
void Mem_Init(void)
Definition: mem.cpp:506
#define MEM_HASH
Definition: mem.cpp:33
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
Definition: r_gl.h:110
memBlock_t * next
Definition: mem.cpp:40
#define UFO_SIZE_T
Definition: ufotypes.h:89
definitions common between client and server, but not game lib
memBlock_t * blocks[MEM_HASH]
Definition: mem.cpp:59
#define Q_streq(a, b)
Definition: shared.h:136
char name[MEM_MAX_POOLNAME]
Definition: mem.cpp:56
void _Mem_FreeTag(memPool_t *pool, const int tagNum, const char *fileName, const int fileLine)
Free memory blocks assigned to a specified tag within a pool.
Definition: mem.cpp:243
uint8_t byte
Definition: ufotypes.h:34
uint32_t byteCount
Definition: mem.cpp:62
size_t memSize
Definition: mem.cpp:50
bool inUse
Definition: mem.cpp:57
const char * Cmd_Args(void)
Returns a single string containing argv(1) to argv(argc()-1)
Definition: cmd.cpp:526
void _Mem_DeletePool(memPool_t *pool, const char *fileName, const int fileLine)
Definition: mem.cpp:146
void Cmd_TableAddList(const cmdList_t *cmdList)
Definition: cmd.cpp:853
static memPool_t m_poolList[MEM_MAX_POOLCOUNT]
Definition: mem.cpp:76
uint32_t sentinel
Definition: mem.cpp:36
Definition: cmd.h:86