added Mem_Memalign function
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 29 Nov 2009 11:16:25 +0000 (11:16 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 29 Nov 2009 11:16:25 +0000 (11:16 +0000)
added Mem_Realloc function

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9528 d7cf8633-e32d-0410-b094-e92efae38249

prvm_edict.c
zone.c
zone.h

index 6ba12f5..b01b35c 100644 (file)
@@ -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 17e788a..5627097 100644 (file)
--- 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 c2f1190..40f3229 100644 (file)
--- 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);