mirror of
https://github.com/YGGverse/xash3d-fwgs.git
synced 2025-01-11 15:47:55 +00:00
engine: zone: implement Mem_Realloc through standard realloc
This commit is contained in:
parent
05ff0d6020
commit
3d5173f257
@ -98,8 +98,14 @@ void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char
|
|||||||
memheader_t *mem;
|
memheader_t *mem;
|
||||||
mempool_t *pool;
|
mempool_t *pool;
|
||||||
|
|
||||||
if( size <= 0 ) return NULL;
|
if( size <= 0 )
|
||||||
if( !poolptr ) Sys_Error( "Mem_Alloc: pool == NULL (alloc at %s:%i)\n", filename, fileline );
|
return NULL;
|
||||||
|
|
||||||
|
if( !poolptr )
|
||||||
|
{
|
||||||
|
Sys_Error( "Mem_Alloc: pool == NULL (alloc at %s:%i)\n", filename, fileline );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
pool = Mem_FindPool( poolptr );
|
pool = Mem_FindPool( poolptr );
|
||||||
|
|
||||||
@ -108,7 +114,11 @@ void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char
|
|||||||
// big allocations are not clumped
|
// big allocations are not clumped
|
||||||
pool->realsize += sizeof( memheader_t ) + size + sizeof( size_t );
|
pool->realsize += sizeof( memheader_t ) + size + sizeof( size_t );
|
||||||
mem = (memheader_t *)Q_malloc( sizeof( memheader_t ) + size + sizeof( size_t ));
|
mem = (memheader_t *)Q_malloc( sizeof( memheader_t ) + size + sizeof( size_t ));
|
||||||
if( mem == NULL ) Sys_Error( "Mem_Alloc: out of memory (alloc at %s:%i)\n", filename, fileline );
|
if( mem == NULL )
|
||||||
|
{
|
||||||
|
Sys_Error( "Mem_Realloc: out of memory (alloc size %s at %s:%i)\n", Q_memprint( size ), filename, fileline );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
mem->filename = filename;
|
mem->filename = filename;
|
||||||
mem->fileline = fileline;
|
mem->fileline = fileline;
|
||||||
@ -187,29 +197,114 @@ void _Mem_Free( void *data, const char *filename, int fileline )
|
|||||||
Mem_FreeBlock((memheader_t *)((byte *)data - sizeof( memheader_t )), filename, fileline );
|
Mem_FreeBlock((memheader_t *)((byte *)data - sizeof( memheader_t )), filename, fileline );
|
||||||
}
|
}
|
||||||
|
|
||||||
void *_Mem_Realloc( poolhandle_t poolptr, void *memptr, size_t size, qboolean clear, const char *filename, int fileline )
|
void *_Mem_Realloc( poolhandle_t poolptr, void *data, size_t size, qboolean clear, const char *filename, int fileline )
|
||||||
{
|
{
|
||||||
memheader_t *memhdr = NULL;
|
memheader_t *mem;
|
||||||
char *nb;
|
mempool_t *pool, *oldpool;
|
||||||
|
size_t newsize, oldsize;
|
||||||
|
char *nb;
|
||||||
|
|
||||||
if( size <= 0 ) return memptr; // no need to reallocate
|
if( size <= 0 )
|
||||||
|
return data; // no need to reallocate
|
||||||
|
|
||||||
if( memptr )
|
if( !poolptr )
|
||||||
{
|
{
|
||||||
memhdr = (memheader_t *)((byte *)memptr - sizeof( memheader_t ));
|
Sys_Error( "Mem_Realloc: pool == NULL (alloc at %s:%i)\n", filename, fileline );
|
||||||
if( size == memhdr->size ) return memptr;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( !data )
|
||||||
|
return _Mem_Alloc( poolptr, size, clear, filename, fileline );
|
||||||
|
|
||||||
|
mem = (memheader_t *)((byte *)data - sizeof( memheader_t ));
|
||||||
|
|
||||||
|
if( mem->sentinel1 != MEMHEADER_SENTINEL1 )
|
||||||
|
{
|
||||||
|
mem->filename = Mem_CheckFilename( mem->filename ); // make sure what we don't crash var_args
|
||||||
|
Sys_Error( "Mem_Realloc: trashed header sentinel 1 (alloc at %s:%i, realloc at %s:%i)\n", mem->filename, mem->fileline, filename, fileline );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( *((byte *)mem + sizeof( memheader_t ) + mem->size ) != MEMHEADER_SENTINEL2 )
|
||||||
|
{
|
||||||
|
mem->filename = Mem_CheckFilename( mem->filename ); // make sure what we don't crash var_args
|
||||||
|
Sys_Error( "Mem_Realloc: trashed header sentinel 2 (alloc at %s:%i, realloc at %s:%i)\n", mem->filename, mem->fileline, filename, fileline );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
oldsize = mem->size;
|
||||||
|
oldpool = mem->pool;
|
||||||
|
if( size == oldsize )
|
||||||
|
return data;
|
||||||
|
|
||||||
|
#if XASH_CUSTOM_SWAP
|
||||||
nb = _Mem_Alloc( poolptr, size, clear, filename, fileline );
|
nb = _Mem_Alloc( poolptr, size, clear, filename, fileline );
|
||||||
|
|
||||||
if( memptr ) // first allocate?
|
newsize = mem->size < size ? mem->size : size; // upper data can be trucnated!
|
||||||
|
memcpy( nb, data, newsize );
|
||||||
|
_Mem_Free( data, filename, fileline ); // free unused old block
|
||||||
|
|
||||||
|
return nb;
|
||||||
|
#else // XASH_CUSTOM_SWAP
|
||||||
|
pool = Mem_FindPool( poolptr );
|
||||||
|
|
||||||
|
mem = realloc( mem, sizeof( memheader_t ) + size + sizeof( size_t ));
|
||||||
|
if( mem == NULL )
|
||||||
{
|
{
|
||||||
size_t newsize = memhdr->size < size ? memhdr->size : size; // upper data can be trucnated!
|
Sys_Error( "Mem_Realloc: out of memory (alloc size %s at %s:%i)\n", Q_memprint( size ), filename, fileline );
|
||||||
memcpy( nb, memptr, newsize );
|
return NULL;
|
||||||
_Mem_Free( memptr, filename, fileline ); // free unused old block
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (void *)nb;
|
pool->totalsize -= oldsize;
|
||||||
|
pool->realsize -= sizeof( memheader_t ) + oldsize + sizeof( size_t );
|
||||||
|
pool->totalsize += size;
|
||||||
|
pool->realsize += sizeof( memheader_t ) + size + sizeof( size_t );
|
||||||
|
|
||||||
|
mem->filename = filename;
|
||||||
|
mem->fileline = fileline;
|
||||||
|
mem->size = size;
|
||||||
|
|
||||||
|
// if allocation was migrated from one pool to another
|
||||||
|
// (this is possible with original Mem_Realloc func)
|
||||||
|
if( oldpool != pool )
|
||||||
|
{
|
||||||
|
// unlink from old pool
|
||||||
|
if( mem->prev )
|
||||||
|
mem->prev->next = mem->next;
|
||||||
|
else pool->chain = mem->next;
|
||||||
|
|
||||||
|
if( mem->next )
|
||||||
|
mem->next->prev = mem->prev;
|
||||||
|
|
||||||
|
// attach to new
|
||||||
|
mem->next = pool->chain;
|
||||||
|
mem->prev = NULL;
|
||||||
|
pool->chain = mem;
|
||||||
|
if( mem->next )
|
||||||
|
mem->next->prev = mem;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// simply update pointers
|
||||||
|
if( mem->prev )
|
||||||
|
mem->prev->next = mem;
|
||||||
|
else pool->chain = mem;
|
||||||
|
|
||||||
|
if( mem->next )
|
||||||
|
mem->next->prev = mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
mem->sentinel1 = MEMHEADER_SENTINEL1;
|
||||||
|
// we have to use only a single byte for this sentinel, because it may not be aligned
|
||||||
|
// and some platforms can't use unaligned accesses
|
||||||
|
*((byte *)mem + sizeof( memheader_t ) + mem->size ) = MEMHEADER_SENTINEL2;
|
||||||
|
|
||||||
|
// clear new memory
|
||||||
|
if( clear && size > oldsize )
|
||||||
|
memset((byte *)mem + sizeof( memheader_t ) + oldsize, 0, size - oldsize );
|
||||||
|
|
||||||
|
return (void *)((byte *)mem + sizeof( memheader_t ));
|
||||||
|
#endif // XASH_CUSTOM_SWAP
|
||||||
}
|
}
|
||||||
|
|
||||||
poolhandle_t _Mem_AllocPool( const char *name, const char *filename, int fileline )
|
poolhandle_t _Mem_AllocPool( const char *name, const char *filename, int fileline )
|
||||||
|
Loading…
Reference in New Issue
Block a user