/*
===========================================================================
Return to Castle Wolfenstein single player GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
RTCW SP Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
RTCW SP Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with RTCW SP Source Code. If not, see .
In addition, the RTCW SP 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 SP
Source Code. If not, please request a copy in writing from id Software at the address below.
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.
===========================================================================
*/
/*****************************************************************************
* name: l_memory.c
*
* desc: memory allocation
*
*
*****************************************************************************/
//#include "q_shared.h"
//#include "../game/botlib.h"
//#include "../../src/botlib/be_interface.h"
#include
#include
#include
#include
#include
#include
#include
#include "l_log.h"
//#define MEMDEBUG
//#define MEMORYMANEGER
#define MEM_ID 0x12345678l
#define HUNK_ID 0x87654321l
int allocatedmemory;
int totalmemorysize;
int numblocks;
#ifdef MEMORYMANEGER
typedef struct memoryblock_s
{
unsigned long int id;
void *ptr;
int size;
#ifdef MEMDEBUG
char *label;
char *file;
int line;
#endif //MEMDEBUG
struct memoryblock_s *prev, *next;
} memoryblock_t;
memoryblock_t *memory;
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void LinkMemoryBlock( memoryblock_t *block ) {
block->prev = NULL;
block->next = memory;
if ( memory ) {
memory->prev = block;
}
memory = block;
} //end of the function LinkMemoryBlock
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void UnlinkMemoryBlock( memoryblock_t *block ) {
if ( block->prev ) {
block->prev->next = block->next;
} else { memory = block->next;}
if ( block->next ) {
block->next->prev = block->prev;
}
} //end of the function UnlinkMemoryBlock
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetMemoryDebug( unsigned long size, char *label, char *file, int line )
#else
void *GetMemory( unsigned long size )
#endif //MEMDEBUG
{
void *ptr;
memoryblock_t *block;
ptr = malloc( size + sizeof( memoryblock_t ) );
block = (memoryblock_t *) ptr;
block->id = MEM_ID;
block->ptr = (char *) ptr + sizeof( memoryblock_t );
block->size = size + sizeof( memoryblock_t );
#ifdef MEMDEBUG
block->label = label;
block->file = file;
block->line = line;
#endif //MEMDEBUG
LinkMemoryBlock( block );
allocatedmemory += block->size;
totalmemorysize += block->size + sizeof( memoryblock_t );
numblocks++;
return block->ptr;
} //end of the function GetMemoryDebug
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetClearedMemoryDebug( unsigned long size, char *label, char *file, int line )
#else
void *GetClearedMemory( unsigned long size )
#endif //MEMDEBUG
{
void *ptr;
#ifdef MEMDEBUG
ptr = GetMemoryDebug( size, label, file, line );
#else
ptr = GetMemory( size );
#endif //MEMDEBUG
memset( ptr, 0, size );
return ptr;
} //end of the function GetClearedMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetHunkMemoryDebug( unsigned long size, char *label, char *file, int line )
#else
void *GetHunkMemory( unsigned long size )
#endif //MEMDEBUG
{
void *ptr;
memoryblock_t *block;
ptr = malloc( size + sizeof( memoryblock_t ) );
block = (memoryblock_t *) ptr;
block->id = HUNK_ID;
block->ptr = (char *) ptr + sizeof( memoryblock_t );
block->size = size + sizeof( memoryblock_t );
#ifdef MEMDEBUG
block->label = label;
block->file = file;
block->line = line;
#endif //MEMDEBUG
LinkMemoryBlock( block );
allocatedmemory += block->size;
totalmemorysize += block->size + sizeof( memoryblock_t );
numblocks++;
return block->ptr;
} //end of the function GetHunkMemoryDebug
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetClearedHunkMemoryDebug( unsigned long size, char *label, char *file, int line )
#else
void *GetClearedHunkMemory( unsigned long size )
#endif //MEMDEBUG
{
void *ptr;
#ifdef MEMDEBUG
ptr = GetHunkMemoryDebug( size, label, file, line );
#else
ptr = GetHunkMemory( size );
#endif //MEMDEBUG
memset( ptr, 0, size );
return ptr;
} //end of the function GetClearedHunkMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
memoryblock_t *BlockFromPointer( void *ptr, char *str ) {
memoryblock_t *block;
if ( !ptr ) {
#ifdef MEMDEBUG
//char *crash = (char *) NULL;
//crash[0] = 1;
printf( PRT_FATAL, "%s: NULL pointer\n", str );
#endif MEMDEBUG
return NULL;
} //end if
block = ( memoryblock_t * )( (char *) ptr - sizeof( memoryblock_t ) );
if ( block->id != MEM_ID && block->id != HUNK_ID ) {
printf( PRT_FATAL, "%s: invalid memory block\n", str );
return NULL;
} //end if
if ( block->ptr != ptr ) {
printf( PRT_FATAL, "%s: memory block pointer invalid\n", str );
return NULL;
} //end if
return block;
} //end of the function BlockFromPointer
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void FreeMemory( void *ptr ) {
memoryblock_t *block;
block = BlockFromPointer( ptr, "FreeMemory" );
if ( !block ) {
return;
}
UnlinkMemoryBlock( block );
allocatedmemory -= block->size;
totalmemorysize -= block->size + sizeof( memoryblock_t );
numblocks--;
//
if ( block->id == MEM_ID ) {
free( block );
} //end if
} //end of the function FreeMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int MemoryByteSize( void *ptr ) {
memoryblock_t *block;
block = BlockFromPointer( ptr, "MemoryByteSize" );
if ( !block ) {
return 0;
}
return block->size;
} //end of the function MemoryByteSize
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void PrintUsedMemorySize( void ) {
printf( PRT_MESSAGE, "total allocated memory: %d KB\n", allocatedmemory >> 10 );
printf( PRT_MESSAGE, "total botlib memory: %d KB\n", totalmemorysize >> 10 );
printf( PRT_MESSAGE, "total memory blocks: %d\n", numblocks );
} //end of the function PrintUsedMemorySize
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void PrintMemoryLabels( void ) {
memoryblock_t *block;
int i;
PrintUsedMemorySize();
i = 0;
Log_Write( "\r\n" );
for ( block = memory; block; block = block->next )
{
#ifdef MEMDEBUG
if ( block->id == HUNK_ID ) {
Log_Write( "%6d, hunk %p, %8d: %24s line %6d: %s\r\n", i, block->ptr, block->size, block->file, block->line, block->label );
} //end if
else
{
Log_Write( "%6d, %p, %8d: %24s line %6d: %s\r\n", i, block->ptr, block->size, block->file, block->line, block->label );
} //end else
#endif //MEMDEBUG
i++;
} //end for
} //end of the function PrintMemoryLabels
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void DumpMemory( void ) {
memoryblock_t *block;
for ( block = memory; block; block = memory )
{
FreeMemory( block->ptr );
} //end for
totalmemorysize = 0;
allocatedmemory = 0;
} //end of the function DumpMemory
#else
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetMemoryDebug( unsigned long size, char *label, char *file, int line )
#else
void *GetMemory( unsigned long size )
#endif //MEMDEBUG
{
void *ptr;
unsigned long int *memid;
ptr = malloc( size + sizeof( unsigned long int ) );
if ( !ptr ) {
return NULL;
}
memid = (unsigned long int *) ptr;
*memid = MEM_ID;
return (unsigned long int *) ( (char *) ptr + sizeof( unsigned long int ) );
} //end of the function GetMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetClearedMemoryDebug( unsigned long size, char *label, char *file, int line )
#else
void *GetClearedMemory( unsigned long size )
#endif //MEMDEBUG
{
void *ptr;
#ifdef MEMDEBUG
ptr = GetMemoryDebug( size, label, file, line );
#else
ptr = GetMemory( size );
#endif //MEMDEBUG
memset( ptr, 0, size );
return ptr;
} //end of the function GetClearedMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetHunkMemoryDebug( unsigned long size, char *label, char *file, int line )
#else
void *GetHunkMemory( unsigned long size )
#endif //MEMDEBUG
{
void *ptr;
unsigned long int *memid;
ptr = malloc( size + sizeof( unsigned long int ) );
if ( !ptr ) {
return NULL;
}
memid = (unsigned long int *) ptr;
*memid = HUNK_ID;
return (unsigned long int *) ( (char *) ptr + sizeof( unsigned long int ) );
} //end of the function GetHunkMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetClearedHunkMemoryDebug( unsigned long size, char *label, char *file, int line )
#else
void *GetClearedHunkMemory( unsigned long size )
#endif //MEMDEBUG
{
void *ptr;
#ifdef MEMDEBUG
ptr = GetHunkMemoryDebug( size, label, file, line );
#else
ptr = GetHunkMemory( size );
#endif //MEMDEBUG
memset( ptr, 0, size );
return ptr;
} //end of the function GetClearedHunkMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void FreeMemory( void *ptr ) {
unsigned long int *memid;
memid = (unsigned long int *) ( (char *) ptr - sizeof( unsigned long int ) );
if ( *memid == MEM_ID ) {
free( memid );
} //end if
} //end of the function FreeMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void PrintUsedMemorySize( void ) {
} //end of the function PrintUsedMemorySize
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void PrintMemoryLabels( void ) {
} //end of the function PrintMemoryLabels
#endif