PageRenderTime 60ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/src/botlib/l_memory.c

http://bzzwolfmp.googlecode.com/
C | 446 lines | 271 code | 24 blank | 151 comment | 23 complexity | c060526a418c7c50ff4691f9ee505253 MD5 | raw file
Possible License(s): GPL-3.0
  1. /*
  2. ===========================================================================
  3. Return to Castle Wolfenstein multiplayer GPL Source Code
  4. Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Return to Castle Wolfenstein multiplayer GPL Source Code (?RTCW MP Source Code?).
  6. RTCW MP Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. RTCW MP Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with RTCW MP Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the RTCW MP Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the RTCW MP Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. /*****************************************************************************
  21. * name: l_memory.c
  22. *
  23. * desc: memory allocation
  24. *
  25. *
  26. *****************************************************************************/
  27. #include "../game/q_shared.h"
  28. #include "../game/botlib.h"
  29. #include "l_log.h"
  30. #include "be_interface.h"
  31. #ifdef _DEBUG
  32. #define MEMDEBUG
  33. #define MEMORYMANEGER
  34. #endif
  35. #define MEM_ID 0x12345678l
  36. #define HUNK_ID 0x87654321l
  37. int allocatedmemory;
  38. int totalmemorysize;
  39. int numblocks;
  40. #ifdef MEMORYMANEGER
  41. typedef struct memoryblock_s
  42. {
  43. unsigned long int id;
  44. void *ptr;
  45. int size;
  46. #ifdef MEMDEBUG
  47. char *label;
  48. char *file;
  49. int line;
  50. #endif //MEMDEBUG
  51. struct memoryblock_s *prev, *next;
  52. } memoryblock_t;
  53. memoryblock_t *memory;
  54. //===========================================================================
  55. //
  56. // Parameter: -
  57. // Returns: -
  58. // Changes Globals: -
  59. //===========================================================================
  60. void LinkMemoryBlock( memoryblock_t *block ) {
  61. block->prev = NULL;
  62. block->next = memory;
  63. if ( memory ) {
  64. memory->prev = block;
  65. }
  66. memory = block;
  67. } //end of the function LinkMemoryBlock
  68. //===========================================================================
  69. //
  70. // Parameter: -
  71. // Returns: -
  72. // Changes Globals: -
  73. //===========================================================================
  74. void UnlinkMemoryBlock( memoryblock_t *block ) {
  75. if ( block->prev ) {
  76. block->prev->next = block->next;
  77. } else { memory = block->next;}
  78. if ( block->next ) {
  79. block->next->prev = block->prev;
  80. }
  81. } //end of the function UnlinkMemoryBlock
  82. //===========================================================================
  83. //
  84. // Parameter: -
  85. // Returns: -
  86. // Changes Globals: -
  87. //===========================================================================
  88. #ifdef MEMDEBUG
  89. void *GetMemoryDebug( unsigned long size, char *label, char *file, int line )
  90. #else
  91. void *GetMemory( unsigned long size )
  92. #endif //MEMDEBUG
  93. {
  94. void *ptr;
  95. memoryblock_t *block;
  96. ptr = botimport.GetMemory( size + sizeof( memoryblock_t ) );
  97. block = (memoryblock_t *) ptr;
  98. block->id = MEM_ID;
  99. block->ptr = (char *) ptr + sizeof( memoryblock_t );
  100. block->size = size + sizeof( memoryblock_t );
  101. #ifdef MEMDEBUG
  102. block->label = label;
  103. block->file = file;
  104. block->line = line;
  105. #endif //MEMDEBUG
  106. LinkMemoryBlock( block );
  107. allocatedmemory += block->size;
  108. totalmemorysize += block->size + sizeof( memoryblock_t );
  109. numblocks++;
  110. return block->ptr;
  111. } //end of the function GetMemoryDebug
  112. //===========================================================================
  113. //
  114. // Parameter: -
  115. // Returns: -
  116. // Changes Globals: -
  117. //===========================================================================
  118. #ifdef MEMDEBUG
  119. void *GetClearedMemoryDebug( unsigned long size, char *label, char *file, int line )
  120. #else
  121. void *GetClearedMemory( unsigned long size )
  122. #endif //MEMDEBUG
  123. {
  124. void *ptr;
  125. #ifdef MEMDEBUG
  126. ptr = GetMemoryDebug( size, label, file, line );
  127. #else
  128. ptr = GetMemory( size );
  129. #endif //MEMDEBUG
  130. memset( ptr, 0, size );
  131. return ptr;
  132. } //end of the function GetClearedMemory
  133. //===========================================================================
  134. //
  135. // Parameter: -
  136. // Returns: -
  137. // Changes Globals: -
  138. //===========================================================================
  139. #ifdef MEMDEBUG
  140. void *GetHunkMemoryDebug( unsigned long size, char *label, char *file, int line )
  141. #else
  142. void *GetHunkMemory( unsigned long size )
  143. #endif //MEMDEBUG
  144. {
  145. void *ptr;
  146. memoryblock_t *block;
  147. ptr = botimport.HunkAlloc( size + sizeof( memoryblock_t ) );
  148. block = (memoryblock_t *) ptr;
  149. block->id = HUNK_ID;
  150. block->ptr = (char *) ptr + sizeof( memoryblock_t );
  151. block->size = size + sizeof( memoryblock_t );
  152. #ifdef MEMDEBUG
  153. block->label = label;
  154. block->file = file;
  155. block->line = line;
  156. #endif //MEMDEBUG
  157. LinkMemoryBlock( block );
  158. allocatedmemory += block->size;
  159. totalmemorysize += block->size + sizeof( memoryblock_t );
  160. numblocks++;
  161. return block->ptr;
  162. } //end of the function GetHunkMemoryDebug
  163. //===========================================================================
  164. //
  165. // Parameter: -
  166. // Returns: -
  167. // Changes Globals: -
  168. //===========================================================================
  169. #ifdef MEMDEBUG
  170. void *GetClearedHunkMemoryDebug( unsigned long size, char *label, char *file, int line )
  171. #else
  172. void *GetClearedHunkMemory( unsigned long size )
  173. #endif //MEMDEBUG
  174. {
  175. void *ptr;
  176. #ifdef MEMDEBUG
  177. ptr = GetHunkMemoryDebug( size, label, file, line );
  178. #else
  179. ptr = GetHunkMemory( size );
  180. #endif //MEMDEBUG
  181. memset( ptr, 0, size );
  182. return ptr;
  183. } //end of the function GetClearedHunkMemory
  184. //===========================================================================
  185. //
  186. // Parameter: -
  187. // Returns: -
  188. // Changes Globals: -
  189. //===========================================================================
  190. memoryblock_t *BlockFromPointer( void *ptr, char *str ) {
  191. memoryblock_t *block;
  192. if ( !ptr ) {
  193. #ifdef MEMDEBUG
  194. //char *crash = (char *) NULL;
  195. //crash[0] = 1;
  196. botimport.Print( PRT_FATAL, "%s: NULL pointer\n", str );
  197. #endif MEMDEBUG
  198. return NULL;
  199. } //end if
  200. block = ( memoryblock_t * )( (char *) ptr - sizeof( memoryblock_t ) );
  201. if ( block->id != MEM_ID && block->id != HUNK_ID ) {
  202. botimport.Print( PRT_FATAL, "%s: invalid memory block\n", str );
  203. return NULL;
  204. } //end if
  205. if ( block->ptr != ptr ) {
  206. botimport.Print( PRT_FATAL, "%s: memory block pointer invalid\n", str );
  207. return NULL;
  208. } //end if
  209. return block;
  210. } //end of the function BlockFromPointer
  211. //===========================================================================
  212. //
  213. // Parameter: -
  214. // Returns: -
  215. // Changes Globals: -
  216. //===========================================================================
  217. void FreeMemory( void *ptr ) {
  218. memoryblock_t *block;
  219. block = BlockFromPointer( ptr, "FreeMemory" );
  220. if ( !block ) {
  221. return;
  222. }
  223. UnlinkMemoryBlock( block );
  224. allocatedmemory -= block->size;
  225. totalmemorysize -= block->size + sizeof( memoryblock_t );
  226. numblocks--;
  227. //
  228. if ( block->id == MEM_ID ) {
  229. botimport.FreeMemory( block );
  230. } //end if
  231. } //end of the function FreeMemory
  232. //===========================================================================
  233. //
  234. // Parameter: -
  235. // Returns: -
  236. // Changes Globals: -
  237. //===========================================================================
  238. int MemoryByteSize( void *ptr ) {
  239. memoryblock_t *block;
  240. block = BlockFromPointer( ptr, "MemoryByteSize" );
  241. if ( !block ) {
  242. return 0;
  243. }
  244. return block->size;
  245. } //end of the function MemoryByteSize
  246. //===========================================================================
  247. //
  248. // Parameter: -
  249. // Returns: -
  250. // Changes Globals: -
  251. //===========================================================================
  252. void PrintUsedMemorySize( void ) {
  253. botimport.Print( PRT_MESSAGE, "total allocated memory: %d KB\n", allocatedmemory >> 10 );
  254. botimport.Print( PRT_MESSAGE, "total botlib memory: %d KB\n", totalmemorysize >> 10 );
  255. botimport.Print( PRT_MESSAGE, "total memory blocks: %d\n", numblocks );
  256. } //end of the function PrintUsedMemorySize
  257. //===========================================================================
  258. //
  259. // Parameter: -
  260. // Returns: -
  261. // Changes Globals: -
  262. //===========================================================================
  263. void PrintMemoryLabels( void ) {
  264. memoryblock_t *block;
  265. int i;
  266. PrintUsedMemorySize();
  267. i = 0;
  268. Log_Write( "\r\n" );
  269. for ( block = memory; block; block = block->next )
  270. {
  271. #ifdef MEMDEBUG
  272. if ( block->id == HUNK_ID ) {
  273. Log_Write( "%6d, hunk %p, %8d: %24s line %6d: %s\r\n", i, block->ptr, block->size, block->file, block->line, block->label );
  274. } //end if
  275. else
  276. {
  277. Log_Write( "%6d, %p, %8d: %24s line %6d: %s\r\n", i, block->ptr, block->size, block->file, block->line, block->label );
  278. } //end else
  279. #endif //MEMDEBUG
  280. i++;
  281. } //end for
  282. } //end of the function PrintMemoryLabels
  283. //===========================================================================
  284. //
  285. // Parameter: -
  286. // Returns: -
  287. // Changes Globals: -
  288. //===========================================================================
  289. void DumpMemory( void ) {
  290. memoryblock_t *block;
  291. for ( block = memory; block; block = memory )
  292. {
  293. FreeMemory( block->ptr );
  294. } //end for
  295. totalmemorysize = 0;
  296. allocatedmemory = 0;
  297. } //end of the function DumpMemory
  298. #else
  299. //===========================================================================
  300. //
  301. // Parameter: -
  302. // Returns: -
  303. // Changes Globals: -
  304. //===========================================================================
  305. #ifdef MEMDEBUG
  306. void *GetMemoryDebug( unsigned long size, char *label, char *file, int line )
  307. #else
  308. void *GetMemory( unsigned long size )
  309. #endif //MEMDEBUG
  310. {
  311. void *ptr;
  312. unsigned long int *memid;
  313. ptr = botimport.GetMemory( size + sizeof( unsigned long int ) );
  314. if ( !ptr ) {
  315. return NULL;
  316. }
  317. memid = (unsigned long int *) ptr;
  318. *memid = MEM_ID;
  319. return (unsigned long int *) ( (char *) ptr + sizeof( unsigned long int ) );
  320. } //end of the function GetMemory
  321. //===========================================================================
  322. //
  323. // Parameter: -
  324. // Returns: -
  325. // Changes Globals: -
  326. //===========================================================================
  327. #ifdef MEMDEBUG
  328. void *GetClearedMemoryDebug( unsigned long size, char *label, char *file, int line )
  329. #else
  330. void *GetClearedMemory( unsigned long size )
  331. #endif //MEMDEBUG
  332. {
  333. void *ptr;
  334. #ifdef MEMDEBUG
  335. ptr = GetMemoryDebug( size, label, file, line );
  336. #else
  337. ptr = GetMemory( size );
  338. #endif //MEMDEBUG
  339. memset( ptr, 0, size );
  340. return ptr;
  341. } //end of the function GetClearedMemory
  342. //===========================================================================
  343. //
  344. // Parameter: -
  345. // Returns: -
  346. // Changes Globals: -
  347. //===========================================================================
  348. #ifdef MEMDEBUG
  349. void *GetHunkMemoryDebug( unsigned long size, char *label, char *file, int line )
  350. #else
  351. void *GetHunkMemory( unsigned long size )
  352. #endif //MEMDEBUG
  353. {
  354. void *ptr;
  355. unsigned long int *memid;
  356. ptr = botimport.HunkAlloc( size + sizeof( unsigned long int ) );
  357. if ( !ptr ) {
  358. return NULL;
  359. }
  360. memid = (unsigned long int *) ptr;
  361. *memid = HUNK_ID;
  362. return (unsigned long int *) ( (char *) ptr + sizeof( unsigned long int ) );
  363. } //end of the function GetHunkMemory
  364. //===========================================================================
  365. //
  366. // Parameter: -
  367. // Returns: -
  368. // Changes Globals: -
  369. //===========================================================================
  370. #ifdef MEMDEBUG
  371. void *GetClearedHunkMemoryDebug( unsigned long size, char *label, char *file, int line )
  372. #else
  373. void *GetClearedHunkMemory( unsigned long size )
  374. #endif //MEMDEBUG
  375. {
  376. void *ptr;
  377. #ifdef MEMDEBUG
  378. ptr = GetHunkMemoryDebug( size, label, file, line );
  379. #else
  380. ptr = GetHunkMemory( size );
  381. #endif //MEMDEBUG
  382. memset( ptr, 0, size );
  383. return ptr;
  384. } //end of the function GetClearedHunkMemory
  385. //===========================================================================
  386. //
  387. // Parameter: -
  388. // Returns: -
  389. // Changes Globals: -
  390. //===========================================================================
  391. void FreeMemory( void *ptr ) {
  392. unsigned long int *memid;
  393. memid = (unsigned long int *) ( (char *) ptr - sizeof( unsigned long int ) );
  394. if ( *memid == MEM_ID ) {
  395. botimport.FreeMemory( memid );
  396. } //end if
  397. } //end of the function FreeMemory
  398. //===========================================================================
  399. //
  400. // Parameter: -
  401. // Returns: -
  402. // Changes Globals: -
  403. //===========================================================================
  404. void PrintUsedMemorySize( void ) {
  405. } //end of the function PrintUsedMemorySize
  406. //===========================================================================
  407. //
  408. // Parameter: -
  409. // Returns: -
  410. // Changes Globals: -
  411. //===========================================================================
  412. void PrintMemoryLabels( void ) {
  413. } //end of the function PrintMemoryLabels
  414. #endif