Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add mod mem to ref gl #310

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions source/client/cl_vid.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "cin.h"
#include "ftlib.h"
#include "xpm.h"
#include "../qcommon/mod_mem.h"

cvar_t *vid_ref;
cvar_t *vid_width, *vid_height;
Expand Down Expand Up @@ -317,6 +318,9 @@ static bool VID_LoadRefresh( const char *name )

VID_UnloadRefresh();

struct mem_import_s memImport = DECLARE_MEM_STRUCT(vid_ref_mempool);

import.memImport = &memImport;
import.fsImport = &default_fs_imports_s;
import.Com_Error = &Com_Error;
import.Com_Printf = &Com_Printf;
Expand Down
99 changes: 51 additions & 48 deletions source/qcommon/mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mem.h"

#define POOLNAMESIZE 128

#define MEMHEADER_SENTINEL1 0xDEADF00D
#define MEMHEADER_SENTINEL2 0xDF

#define MEMALIGNMENT_DEFAULT 16
#define MIN_MEM_ALIGNMENT sizeof(void*)

#define AllocHashSize ( 1u << 12u )

Expand All @@ -74,6 +71,7 @@ static const unsigned int releasedPattern = 0xdeadbeef; // Fill pattern for d
static bool memory_initialized = false;
static bool commands_initialized = false;


#if defined( _DEBUG )
static const bool AlwaysWipeAll = true;
static const size_t PaddingSize = 8;
Expand Down Expand Up @@ -211,23 +209,23 @@ static void __wipeWithPattern( void *reportedAddress, size_t reportedSize, size_
// pattern = 0;

// This part of the operation is optional
if( AlwaysWipeAll && reportedSize > originalReportedSize ) {
// Fill the bulk
if( AlwaysWipeAll && reportedSize > originalReportedSize ) {
// Fill the bulk

uint32_t *lptr = (uint32_t *)( ( (char *)reportedAddress ) + originalReportedSize );
size_t length = reportedSize - originalReportedSize;
for( size_t i = 0; i < ( length >> 2 ); i++, lptr++ ) {
*lptr = pattern;
}
uint32_t *lptr = (uint32_t *)( ( (char *)reportedAddress ) + originalReportedSize );
size_t length = reportedSize - originalReportedSize;
for( size_t i = 0; i < ( length >> 2 ); i++, lptr++ ) {
*lptr = pattern;
}

// Fill the remainder
// Fill the remainder

unsigned int shiftCount = 0;
char *cptr = (char *)( lptr );
for( size_t i = 0; i < ( length & 0x3 ); i++, cptr++, shiftCount += 8 ) {
*cptr = (char)( ( pattern & ( 0xff << shiftCount ) ) >> shiftCount );
}
}
unsigned int shiftCount = 0;
char *cptr = (char *)( lptr );
for( size_t i = 0; i < ( length & 0x3 ); i++, cptr++, shiftCount += 8 ) {
*cptr = (char)( ( pattern & ( 0xff << shiftCount ) ) >> shiftCount );
}
}

// Write in the prefix/postfix bytes

Expand Down Expand Up @@ -326,12 +324,6 @@ static inline void __unlinkMemory( struct memheader_s *mem )
assert( mem );
assert( mem->reportedAddress );
const size_t hashIndex = __resolveUnitHashIndex( mem->reportedAddress );

// we are linked to a pool so unlink
__unlinkPool(mem);

mem->realsize = 0;
mem->size = 0;
if( hashTable[hashIndex] == mem ) {
hashTable[hashIndex] = mem->hnext;
} else {
Expand Down Expand Up @@ -458,7 +450,7 @@ static void _Mem_Error( const char *format, ... )
}

void *__Q_MallocAligned(size_t align, size_t size, const char* sourceFilename, const char* functionName, int sourceLine) {
const size_t alignment = align < sizeof(void*) ? sizeof(void*) : align;
const size_t alignment = align < MIN_MEM_ALIGNMENT ? MIN_MEM_ALIGNMENT : align;
const size_t realsize = size + ( CANARY_SIZE * 2 ) + alignment;
void *baseAddress = malloc( realsize );
if( baseAddress == NULL )
Expand Down Expand Up @@ -520,21 +512,27 @@ void *__Q_Malloc(size_t size, const char* sourceFilename, const char* functionNa

void *__Q_Realloc( void *ptr, size_t size, const char *sourceFilename, const char *functionName, int sourceLine )
{
if( ptr == NULL )
return __Q_Malloc( size, sourceFilename, functionName, sourceLine );

QMutex_Lock( memMutex );
struct memheader_s *mem = __findLinkMemory( ptr );
if( mem == NULL ) {
assert( false );
_Mem_Error( "Mem_Free: Request to deallocate RAM that was naver allocated (alloc at %s:%i)", mem->sourceFilename, mem->sourceline );
}
__unlinkMemory(mem); // unlink the memory because the address may change

// realloc can't guarantee alignment so will just use min platform alignment
const size_t alignmentReq = MIN_MEM_ALIGNMENT;
const ptrdiff_t oldPtrDiff = ( (uint8_t*)mem->reportedAddress - (uint8_t*)mem->baseAddress ) - CANARY_SIZE;
const size_t realsize = size + ( CANARY_SIZE * 2 ) + mem->alignment;
const size_t realsize = size + ( CANARY_SIZE * 2 ) + alignmentReq;
const size_t oldReportedSize = mem->size;
void *baseAddress = realloc( mem->baseAddress, realsize );
void *reportedAddress = ( (uint8_t*)baseAddress + CANARY_SIZE );
const size_t offset = ( (size_t)reportedAddress ) % mem->alignment;
const size_t offset = ( (size_t)reportedAddress ) % alignmentReq;
if( offset ) {
reportedAddress = (uint8_t *)reportedAddress + ( mem->alignment - offset );
reportedAddress = (uint8_t *)reportedAddress + ( alignmentReq - offset );
}
const ptrdiff_t newPtrDiff = ( (uint8_t*)reportedAddress - (uint8_t*)baseAddress ) - CANARY_SIZE;
if(mem->pool) {
Expand All @@ -543,25 +541,28 @@ void *__Q_Realloc( void *ptr, size_t size, const char *sourceFilename, const cha
mem->pool->realsize += realsize;
mem->pool->totalsize += size;
}

// the offset from the base address is different so we need to adjust the memory to be re-aligned when the memory was allocated
if( newPtrDiff != oldPtrDiff ) {
memmove( (uint8_t*)reportedAddress - CANARY_SIZE, (uint8_t*)reportedAddress - CANARY_SIZE + ( oldPtrDiff - newPtrDiff ), mem->size + ( CANARY_SIZE * 2 ) );
}

// wipe the pattern and wipe in unused porition
__wipeWithPattern( reportedAddress, size, oldReportedSize, unusedPattern );

mem->realsize = realsize;
mem->size = size;
mem->alignment = alignmentReq;
mem->reportedAddress = reportedAddress;
mem->baseAddress = baseAddress;
mem->sourceline = sourceLine;
mem->sourceFilename = sourceFilename;
mem->functionName = functionName;
__linkMemory(mem);
__validateAllocationHeader( mem );

QMutex_Unlock( memMutex );

// the offset from the base address is different so we need to adjust the memory to be re-aligned when the memory was allocated
if( newPtrDiff != oldPtrDiff ) {
memmove( (uint8_t*)reportedAddress - CANARY_SIZE, (uint8_t*)reportedAddress - CANARY_SIZE + ( newPtrDiff - oldPtrDiff ), mem->size + ( CANARY_SIZE * 2 ) );
}

// validate the reported address
__wipeWithPattern( reportedAddress, size, oldReportedSize, unusedPattern );

return mem->reportedAddress;
}

Expand Down Expand Up @@ -600,6 +601,7 @@ void Q_EmptyPool( struct mempool_s *pool )
free( current->baseAddress );
chain = current->next;
__unlinkMemory( current );
__unlinkPool(current);
__returnMemHeaderToReserve( current );
}

Expand All @@ -621,18 +623,16 @@ void Q_FreePool( struct mempool_s *pool )
{
assert( pool );
QMutex_Lock( memMutex );
do {
struct mempool_s **current = pool->parent ? &( pool->parent->child ) : &rootChain;
while( *current ) {
if( ( *current )->next == pool) {
( *current )->next = pool->next;
pool->parent = NULL;
break;
}
current = &( *current )->next;
struct mempool_s **current = pool->parent ? &( pool->parent->child ) : &rootChain;
while( *current ) {
if( ( *current )->next == pool) {
( *current )->next = pool->next;
pool->parent = NULL;
break;
}
assert(false);
} while(0);
current = &( *current )->next;
}
assert(current != NULL);

size_t capacity = 16;
size_t len = 0;
Expand All @@ -648,6 +648,7 @@ void Q_FreePool( struct mempool_s *pool )
free( current->baseAddress );
chain = current->next;
__unlinkMemory( current );
__unlinkPool(current);
__returnMemHeaderToReserve( current );
}
struct mempool_s *child = pool->child;
Expand Down Expand Up @@ -676,6 +677,7 @@ void Q_Free( void *ptr )
__validateAllocationHeader( mem);
free( mem->baseAddress );
__unlinkMemory( mem );
__unlinkPool(mem);
__returnMemHeaderToReserve( mem );
QMutex_Unlock( memMutex );
}
Expand All @@ -687,7 +689,7 @@ void *_Mem_AllocExt( mempool_t *pool, size_t size, size_t alignment, int z, int
return NULL;

// default to 16-bytes alignment
alignment = alignment < sizeof(void*) ? sizeof(void*) : alignment;
alignment = alignment < MIN_MEM_ALIGNMENT ? MIN_MEM_ALIGNMENT : alignment;

assert( pool != NULL );

Expand Down Expand Up @@ -812,6 +814,7 @@ void _Mem_Free( void *data, int musthave, int canthave, const char *filename, in

// unlink the memory
__unlinkMemory(mem);
__unlinkPool(mem);

// wipe with closing pattern
__wipeWithPattern(mem->reportedAddress, mem->size, 0, releasedPattern);
Expand Down
19 changes: 17 additions & 2 deletions source/qcommon/mod_mem.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ DECLARE_TYPEDEF_METHOD( void, Q_EmptyPool, mempool_t *pool );
#undef DECLARE_TYPEDEF_METHOD

struct mem_import_s {
mempool_t* parent;
mempool_t* parent; // the parent pool to link to by default if NULL is passed into a pool
__Q_MallocFn __Q_Malloc;
__Q_ReallocFn __Q_Realloc;
__Q_MallocAlignedFn __Q_MallocAligned;
Expand All @@ -37,16 +37,31 @@ struct mem_import_s {
Q_EmptyPoolFn Q_EmptyPool;
};

#define DECLARE_MEM_STRUCT(PARENT) { \
PARENT, \
__Q_Malloc, \
__Q_Realloc, \
__Q_MallocAligned, \
Q_Free, \
Q_CreatePool, \
Q_LinkToPool, \
Q_FreePool, \
Q_EmptyPool \
};

#if MEM_DEFINE_INTERFACE_IMPL
static struct mem_import_s mem_import;
void *__Q_Malloc( size_t size, const char *sourceFilename, const char *functionName, int sourceLine ) { return mem_import.__Q_Malloc(size, sourceFilename, functionName, sourceLine); }
void *__Q_Realloc( void *ptr, size_t size, const char *sourceFilename, const char *functionName, int sourceLine ) { return mem_import.__Q_Realloc(ptr, size, sourceFilename, functionName, sourceLine); }
void *__Q_MallocAligned( size_t alignment, size_t size, const char *sourceFilename, const char *functionName, int sourceLine ) { return mem_import.__Q_MallocAligned(alignment, size, sourceFilename, functionName, sourceLine); }
void Q_Free( void *ptr ) { return mem_import.Q_Free(ptr); }
mempool_t *Q_CreatePool( mempool_t *parent, const char *name ) { return mem_import.Q_CreatePool(parent ? parent : mem_import.parent , name);}
void Q_LinkToPool( void *ptr, mempool_t *pool ) {return mem_import.Q_LinkToPool(ptr, parent ? parent : mem_import.parent);}
void Q_LinkToPool( void *ptr, mempool_t *pool ) { return mem_import.Q_LinkToPool(ptr, pool);}
void Q_FreePool( mempool_t *pool ) {mem_import.Q_FreePool(pool);}
void Q_EmptyPool( mempool_t *pool ) {mem_import.Q_EmptyPool(pool);}
static inline void Q_ImportMemModule(const struct mem_import_s* mem) {
mem_import = *mem;
}
#endif

#endif
4 changes: 3 additions & 1 deletion source/ref_base/r_public.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

#include "../cgame/ref.h"

#include "../qcommon/mod_mem.h"

#define REF_API_VERSION 21

struct mempool_s;
Expand Down Expand Up @@ -103,7 +105,7 @@ typedef struct
unsigned (**cmdHandlers)( const void * ), unsigned timeout_msec );

const struct fs_import_s* fsImport;

const struct mem_import_s* memImport;
} ref_import_t;


Expand Down
13 changes: 9 additions & 4 deletions source/ref_gl/r_alias.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,11 @@ static void Mod_AliasBuildMeshesForFrame0( model_t *mod )
size += sizeof( vec4_t ); // s-vectors
size *= mesh->numverts;

mesh->xyzArray = ( vec4_t * )Mod_Malloc( mod, size );
mesh->xyzArray = (vec4_t *)Q_MallocAligned( 16, size );
memset( mesh->xyzArray, 0, size );
mesh->normalsArray = ( vec4_t * )( ( uint8_t * )mesh->xyzArray + mesh->numverts * sizeof( vec4_t ) );
mesh->sVectorsArray = ( vec4_t * )( ( uint8_t * )mesh->normalsArray + mesh->numverts * sizeof( vec4_t ) );
Q_LinkToPool( mesh->xyzArray, mod->mempool );

for( i = 0; i < mesh->numverts; i++ )
{
Expand Down Expand Up @@ -173,7 +175,8 @@ void Mod_LoadAliasMD3Model( model_t *mod, model_t *parent, void *buffer, bspForm
mod->name, version, MD3_ALIAS_VERSION );

mod->type = mod_alias;
mod->extradata = poutmodel = ( maliasmodel_t * )Mod_Malloc( mod, sizeof( maliasmodel_t ) );
mod->extradata = poutmodel = Q_MallocAligned(16, sizeof( maliasmodel_t ));
Q_LinkToPool(mod->extradata, mod->mempool);
mod->radius = 0;
mod->registrationSequence = rsh.registrationSequence;
mod->touch = &Mod_TouchAliasModel;
Expand Down Expand Up @@ -208,7 +211,8 @@ void Mod_LoadAliasMD3Model( model_t *mod, model_t *parent, void *buffer, bspForm
bufsize = poutmodel->numframes * ( sizeof( maliasframe_t ) + sizeof( maliastag_t ) * poutmodel->numtags ) +
poutmodel->nummeshes * sizeof( maliasmesh_t ) +
poutmodel->nummeshes * sizeof( drawSurfaceAlias_t );
buf = ( uint8_t * )Mod_Malloc( mod, bufsize );
buf = Q_MallocAligned(16, bufsize);
Q_LinkToPool(buf, mod->mempool);

//
// load the frames
Expand Down Expand Up @@ -310,7 +314,8 @@ void Mod_LoadAliasMD3Model( model_t *mod, model_t *parent, void *buffer, bspForm
bufsize = ALIGN( sizeof( maliasskin_t ) * poutmesh->numskins, sizeof( vec_t ) ) +
numverts * ( sizeof( vec2_t ) + sizeof( maliasvertex_t ) * poutmodel->numframes ) +
poutmesh->numtris * sizeof( elem_t ) * 3;
buf = ( uint8_t * )Mod_Malloc( mod, bufsize );
buf = Q_MallocAligned( 16, bufsize );
Q_LinkToPool( buf, mod->mempool );

//
// load the skins
Expand Down
9 changes: 5 additions & 4 deletions source/ref_gl/r_light.c
Original file line number Diff line number Diff line change
Expand Up @@ -719,9 +719,9 @@ void R_BuildLightmaps( model_t *mod, int numLightmaps, int w, int h, const uint8
if( r_lightmapBuffer )
R_Free( r_lightmapBuffer );

loadbmodel->lightmapImages = Mod_Malloc( mod, sizeof( *loadbmodel->lightmapImages ) * r_numUploadedLightmaps );
memcpy( loadbmodel->lightmapImages, r_lightmapTextures,
sizeof( *loadbmodel->lightmapImages ) * r_numUploadedLightmaps );
loadbmodel->lightmapImages = Q_MallocAligned( 16, sizeof( *loadbmodel->lightmapImages ) * r_numUploadedLightmaps );
Q_LinkToPool(loadbmodel->lightmapImages, mod->mempool);
memcpy( loadbmodel->lightmapImages, r_lightmapTextures, sizeof( *loadbmodel->lightmapImages ) * r_numUploadedLightmaps );
loadbmodel->numLightmapImages = r_numUploadedLightmaps;

ri.Com_DPrintf( "Packed %i lightmap blocks into %i texture(s)\n", numBlocks, r_numUploadedLightmaps );
Expand Down Expand Up @@ -763,7 +763,8 @@ void R_InitLightStyles( model_t *mod )
assert( mod );

loadbmodel = (( mbrushmodel_t * )mod->extradata);
loadbmodel->superLightStyles = Mod_Malloc( mod, sizeof( *loadbmodel->superLightStyles ) * MAX_LIGHTSTYLES );
loadbmodel->superLightStyles = Q_MallocAligned(16, sizeof( *loadbmodel->superLightStyles ) * MAX_LIGHTSTYLES);
Q_LinkToPool(loadbmodel->superLightStyles, mod->mempool);
loadbmodel->numSuperLightStyles = 0;

for( i = 0; i < MAX_LIGHTSTYLES; i++ )
Expand Down
Loading
Loading