]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - zone.c
strip proquake QC messages if in Quake protocol
[xonotic/darkplaces.git] / zone.c
diff --git a/zone.c b/zone.c
index 17e788abe2a02212a55348c61baaa8daf040a8f9..889adc9d0c86bc54bb9c2eb97bb5451fa88452ad 100644 (file)
--- a/zone.c
+++ b/zone.c
@@ -35,6 +35,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #define MEMHEADER_SENTINEL_FOR_ADDRESS(p) ((sentinel_seed ^ (unsigned int) (uintptr_t) (p)) + sentinel_seed)
 unsigned int sentinel_seed;
 
+qboolean mem_bigendian = false;
+
 // LordHavoc: enables our own low-level allocator (instead of malloc)
 #define MEMCLUMPING 0
 #define MEMCLUMPING_FREECLUMPS 0
@@ -43,7 +45,7 @@ unsigned int sentinel_seed;
 // smallest unit we care about is this many bytes
 #define MEMUNIT 128
 // try to do 32MB clumps, but overhead eats into this
-#define MEMWANTCLUMPSIZE (1<<29)
+#define MEMWANTCLUMPSIZE (1<<27)
 // give malloc padding so we can't waste most of a page at the end
 #define MEMCLUMPSIZE (MEMWANTCLUMPSIZE - MEMWANTCLUMPSIZE/MEMUNIT/32 - 128)
 #define MEMBITS (MEMCLUMPSIZE / MEMUNIT)
@@ -82,6 +84,9 @@ cvar_t developer_memorydebug = {0, "developer_memorydebug", "0", "enables memory
 
 static mempool_t *poolchain = NULL;
 
+void Mem_PrintStats(void);
+void Mem_PrintList(size_t minallocationsize);
+
 #if MEMCLUMPING != 2
 // some platforms have a malloc that returns NULL but succeeds later
 // (Windows growing its swapfile for example)
@@ -95,11 +100,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,26 +308,44 @@ 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)
-               Con_Printf("Mem_Alloc: pool %s, file %s:%i, size %i bytes\n", pool->name, filename, fileline, (int)size);
+       if (developer_memory.integer)
+               Con_DPrintf("Mem_Alloc: pool %s, file %s:%i, size %i bytes\n", pool->name, filename, fileline, (int)size);
        //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)
+       {
+               Mem_PrintList(0);
+               Mem_PrintStats();
+               Mem_PrintList(1<<30);
+               Mem_PrintStats();
                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 +363,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));
 }
 
@@ -366,8 +397,8 @@ static void _Mem_FreeBlock(memheader_t *mem, const char *filename, int fileline)
                Sys_Error("Mem_Free: trashed header sentinel 2 (alloc at %s:%i, free at %s:%i)", mem->filename, mem->fileline, filename, fileline);
 
        pool = mem->pool;
-       if (developer.integer && developer_memory.integer)
-               Con_Printf("Mem_Free: pool %s, alloc %s:%i, free %s:%i, size %i bytes\n", pool->name, mem->filename, mem->fileline, filename, fileline, (int)(mem->size));
+       if (developer_memory.integer)
+               Con_DPrintf("Mem_Free: pool %s, alloc %s:%i, free %s:%i, size %i bytes\n", pool->name, mem->filename, mem->fileline, filename, fileline, (int)(mem->size));
        // unlink memheader from doubly linked list
        if ((mem->prev ? mem->prev->next != mem : pool->chain != mem) || (mem->next && mem->next->prev != mem))
                Sys_Error("Mem_Free: not allocated or double freed (free at %s:%i)", filename, fileline);
@@ -382,7 +413,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)
@@ -393,7 +424,7 @@ void _Mem_Free(void *data, const char *filename, int fileline)
                return;
        }
 
-       if (developer.integer && developer_memorydebug.integer)
+       if (developer_memorydebug.integer)
        {
                //_Mem_CheckSentinelsGlobal(filename, fileline);
                if (!Mem_IsAllocated(NULL, data))
@@ -406,11 +437,17 @@ 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)
 {
        mempool_t *pool;
-       //if (developer.integer && developer_memorydebug.integer)
-       //      _Mem_CheckSentinelsGlobal(filename, fileline);
+       if (developer_memorydebug.integer)
+               _Mem_CheckSentinelsGlobal(filename, fileline);
        pool = (mempool_t *)Clump_AllocBlock(sizeof(mempool_t));
        if (pool == NULL)
+       {
+               Mem_PrintList(0);
+               Mem_PrintStats();
+               Mem_PrintList(1<<30);
+               Mem_PrintStats();
                Sys_Error("Mem_AllocPool: out of memory (allocpool at %s:%i)", filename, fileline);
+       }
        memset(pool, 0, sizeof(mempool_t));
        pool->sentinel1 = MEMHEADER_SENTINEL_FOR_ADDRESS(&pool->sentinel1);
        pool->sentinel2 = MEMHEADER_SENTINEL_FOR_ADDRESS(&pool->sentinel2);
@@ -432,8 +469,8 @@ void _Mem_FreePool(mempool_t **poolpointer, const char *filename, int fileline)
        mempool_t *pool = *poolpointer;
        mempool_t **chainaddress, *iter, *temp;
 
-       //if (developer.integer && developer_memorydebug.integer)
-       //      _Mem_CheckSentinelsGlobal(filename, fileline);
+       if (developer_memorydebug.integer)
+               _Mem_CheckSentinelsGlobal(filename, fileline);
        if (pool)
        {
                // unlink pool from chain
@@ -466,7 +503,7 @@ void _Mem_EmptyPool(mempool_t *pool, const char *filename, int fileline)
 {
        mempool_t *chainaddress;
 
-       if (developer.integer && developer_memorydebug.integer)
+       if (developer_memorydebug.integer)
        {
                //_Mem_CheckSentinelsGlobal(filename, fileline);
                // check if this pool is in the poolchain
@@ -727,7 +764,7 @@ void Mem_PrintList(size_t minallocationsize)
                   "size    name\n");
        for (pool = poolchain;pool;pool = pool->next)
        {
-               Con_Printf("%10luk (%10luk actual) %s (%+li byte change) %s\n", (unsigned long) ((pool->totalsize + 1023) / 1024), (unsigned long)((pool->realsize + 1023) / 1024), pool->name, (long)pool->totalsize - pool->lastchecksize, (pool->flags & POOLFLAG_TEMP) ? "TEMP" : "");
+               Con_Printf("%10luk (%10luk actual) %s (%+li byte change) %s\n", (unsigned long) ((pool->totalsize + 1023) / 1024), (unsigned long)((pool->realsize + 1023) / 1024), pool->name, (long)(pool->totalsize - pool->lastchecksize), (pool->flags & POOLFLAG_TEMP) ? "TEMP" : "");
                pool->lastchecksize = pool->totalsize;
                for (mem = pool->chain;mem;mem = mem->next)
                        if (mem->size >= minallocationsize)
@@ -780,6 +817,10 @@ Memory_Init
 */
 void Memory_Init (void)
 {
+       static union {unsigned short s;unsigned char b[2];} u;
+       u.s = 0x100;
+       mem_bigendian = u.b[0];
+
        sentinel_seed = rand();
        poolchain = NULL;
        tempmempool = Mem_AllocPool("Temporary Memory", POOLFLAG_TEMP, NULL);