From: havoc Date: Sun, 29 Nov 2009 11:16:25 +0000 (+0000) Subject: added Mem_Memalign function X-Git-Tag: xonotic-v0.1.0preview~1118 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=dbd8404191be9296fe8701d8a178db3de6b69eb1;p=xonotic%2Fdarkplaces.git added Mem_Memalign function added Mem_Realloc function git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9528 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/prvm_edict.c b/prvm_edict.c index 6ba12f52..b01b35ca 100644 --- a/prvm_edict.c +++ b/prvm_edict.c @@ -2376,7 +2376,7 @@ int PRVM_GetProgNr(void) void *_PRVM_Alloc(size_t buffersize, const char *filename, int fileline) { - return _Mem_Alloc(prog->progs_mempool, buffersize, filename, fileline); + return _Mem_Alloc(prog->progs_mempool, NULL, buffersize, 16, filename, fileline); } void _PRVM_Free(void *buffer, const char *filename, int fileline) diff --git a/zone.c b/zone.c index 17e788ab..5627097a 100644 --- a/zone.c +++ b/zone.c @@ -95,11 +95,7 @@ static void *attempt_malloc(size_t size) base = (void *)malloc(size); if (base) return base; -#ifdef WIN32 - Sleep(1); -#else - usleep(1000); -#endif + Sys_Sleep(1000); } return NULL; } @@ -307,14 +303,23 @@ static void Clump_FreeBlock(void *base, size_t size) #endif } -void *_Mem_Alloc(mempool_t *pool, size_t size, const char *filename, int fileline) +void *_Mem_Alloc(mempool_t *pool, void *olddata, size_t size, size_t alignment, const char *filename, int fileline) { unsigned int sentinel1; unsigned int sentinel2; size_t realsize; + size_t sharedsize; + size_t remainsize; memheader_t *mem; + memheader_t *oldmem; + unsigned char *base; + if (size <= 0) + { + if (olddata) + _Mem_Free(olddata, filename, fileline); return NULL; + } if (pool == NULL) Sys_Error("Mem_Alloc: pool == NULL (alloc at %s:%i)", filename, fileline); if (developer.integer && developer_memory.integer) @@ -322,11 +327,14 @@ void *_Mem_Alloc(mempool_t *pool, size_t size, const char *filename, int filelin //if (developer.integer && developer_memorydebug.integer) // _Mem_CheckSentinelsGlobal(filename, fileline); pool->totalsize += size; - realsize = sizeof(memheader_t) + size + sizeof(sentinel2); + realsize = alignment + sizeof(memheader_t) + size + sizeof(sentinel2); pool->realsize += realsize; - mem = (memheader_t *)Clump_AllocBlock(realsize); - if (mem == NULL) + base = (unsigned char *)Clump_AllocBlock(realsize); + if (base== NULL) Sys_Error("Mem_Alloc: out of memory (alloc at %s:%i)", filename, fileline); + // calculate address that aligns the end of the memheader_t to the specified alignment + mem = (memheader_t*)((((size_t)base + sizeof(memheader_t) + (alignment-1)) & ~(alignment-1)) - sizeof(memheader_t)); + mem->baseaddress = (void*)base; mem->filename = filename; mem->fileline = fileline; mem->size = size; @@ -344,7 +352,19 @@ void *_Mem_Alloc(mempool_t *pool, size_t size, const char *filename, int filelin pool->chain = mem; if (mem->next) mem->next->prev = mem; - memset((void *)((unsigned char *) mem + sizeof(memheader_t)), 0, mem->size); + + // copy the shared portion in the case of a realloc, then memset the rest + sharedsize = 0; + remainsize = size; + if (olddata) + { + oldmem = (memheader_t*)olddata - 1; + sharedsize = min(oldmem->size, size); + memcpy((void *)((unsigned char *) mem + sizeof(memheader_t)), olddata, sharedsize); + remainsize -= sharedsize; + _Mem_Free(olddata, filename, fileline); + } + memset((void *)((unsigned char *) mem + sizeof(memheader_t) + sharedsize), 0, remainsize); return (void *)((unsigned char *) mem + sizeof(memheader_t)); } @@ -382,7 +402,7 @@ static void _Mem_FreeBlock(memheader_t *mem, const char *filename, int fileline) realsize = sizeof(memheader_t) + size + sizeof(sentinel2); pool->totalsize -= size; pool->realsize -= realsize; - Clump_FreeBlock(mem, realsize); + Clump_FreeBlock(mem->baseaddress, realsize); } void _Mem_Free(void *data, const char *filename, int fileline) diff --git a/zone.h b/zone.h index c2f11907..40f32298 100644 --- a/zone.h +++ b/zone.h @@ -30,6 +30,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. typedef struct memheader_s { + // address returned by Chunk_Alloc (may be significantly before this header to satisify alignment) + void *baseaddress; // next and previous memheaders in chain belonging to pool struct memheader_s *next; struct memheader_s *prev; @@ -74,7 +76,9 @@ typedef struct mempool_s } mempool_t; -#define Mem_Alloc(pool,size) _Mem_Alloc(pool, size, __FILE__, __LINE__) +#define Mem_Alloc(pool,size) _Mem_Alloc(pool, NULL, size, 16, __FILE__, __LINE__) +#define Mem_Memalign(pool,alignment,size) _Mem_Alloc(pool, NULL, size, alignment, __FILE__, __LINE__) +#define Mem_Realloc(pool,data,size) _Mem_Alloc(pool, data, size, 16, __FILE__, __LINE__) #define Mem_Free(mem) _Mem_Free(mem, __FILE__, __LINE__) #define Mem_CheckSentinels(data) _Mem_CheckSentinels(data, __FILE__, __LINE__) #define Mem_CheckSentinelsGlobal() _Mem_CheckSentinelsGlobal(__FILE__, __LINE__) @@ -82,7 +86,7 @@ mempool_t; #define Mem_FreePool(pool) _Mem_FreePool(pool, __FILE__, __LINE__) #define Mem_EmptyPool(pool) _Mem_EmptyPool(pool, __FILE__, __LINE__) -void *_Mem_Alloc(mempool_t *pool, size_t size, const char *filename, int fileline); +void *_Mem_Alloc(mempool_t *pool, void *data, size_t size, size_t alignment, const char *filename, int fileline); void _Mem_Free(void *data, const char *filename, int fileline); mempool_t *_Mem_AllocPool(const char *name, int flags, mempool_t *parent, const char *filename, int fileline); void _Mem_FreePool(mempool_t **pool, const char *filename, int fileline);