X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=zone.c;h=585c10396d03db32e726ccaef168d1eb32b52043;hb=9b73f5e152089c02f4157b4f3cddcc884e3648cd;hp=d61def1a021559333501f7d60432131eca9dfe55;hpb=95ed6d481f1ccbd2d39372acf2a38e2fc0b1782c;p=xonotic%2Fdarkplaces.git diff --git a/zone.c b/zone.c index d61def1a..585c1039 100644 --- a/zone.c +++ b/zone.c @@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifdef WIN32 #include +#include #else #include #endif @@ -81,6 +82,8 @@ static memclump_t *clumpchain = NULL; cvar_t developer_memory = {0, "developer_memory", "0", "prints debugging information about memory allocations"}; cvar_t developer_memorydebug = {0, "developer_memorydebug", "0", "enables memory corruption checks (very slow)"}; +cvar_t sys_memsize_physical = {CVAR_READONLY, "sys_memsize_physical", "", "physical memory size in MB (or empty if unknown)"}; +cvar_t sys_memsize_virtual = {CVAR_READONLY, "sys_memsize_virtual", "", "virtual memory size in MB (or empty if unknown)"}; static mempool_t *poolchain = NULL; @@ -327,9 +330,9 @@ void *_Mem_Alloc(mempool_t *pool, void *olddata, size_t size, size_t alignment, } 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.integer && developer_memorydebug.integer) + 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 > 0 && developer_memorydebug.integer) // _Mem_CheckSentinelsGlobal(filename, fileline); pool->totalsize += size; realsize = alignment + sizeof(memheader_t) + size + sizeof(sentinel2); @@ -392,13 +395,13 @@ static void _Mem_FreeBlock(memheader_t *mem, const char *filename, int fileline) sentinel1 = MEMHEADER_SENTINEL_FOR_ADDRESS(&mem->sentinel); sentinel2 = MEMHEADER_SENTINEL_FOR_ADDRESS((unsigned char *) mem + sizeof(memheader_t) + mem->size); if (mem->sentinel != sentinel1) - Sys_Error("Mem_Free: trashed header sentinel 1 (alloc at %s:%i, free at %s:%i)", mem->filename, mem->fileline, filename, fileline); + Sys_Error("Mem_Free: trashed head sentinel (alloc at %s:%i, free at %s:%i)", mem->filename, mem->fileline, filename, fileline); if (memcmp((unsigned char *) mem + sizeof(memheader_t) + mem->size, &sentinel2, sizeof(sentinel2))) - Sys_Error("Mem_Free: trashed header sentinel 2 (alloc at %s:%i, free at %s:%i)", mem->filename, mem->fileline, filename, fileline); + Sys_Error("Mem_Free: trashed tail sentinel (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); @@ -424,7 +427,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)) @@ -437,8 +440,8 @@ 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) { @@ -469,8 +472,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 @@ -503,7 +506,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 @@ -516,9 +519,9 @@ void _Mem_EmptyPool(mempool_t *pool, const char *filename, int fileline) if (pool == NULL) Sys_Error("Mem_EmptyPool: pool == NULL (emptypool at %s:%i)", filename, fileline); if (pool->sentinel1 != MEMHEADER_SENTINEL_FOR_ADDRESS(&pool->sentinel1)) - Sys_Error("Mem_EmptyPool: trashed pool sentinel 2 (allocpool at %s:%i, emptypool at %s:%i)", pool->filename, pool->fileline, filename, fileline); - if (pool->sentinel2 != MEMHEADER_SENTINEL_FOR_ADDRESS(&pool->sentinel2)) Sys_Error("Mem_EmptyPool: trashed pool sentinel 1 (allocpool at %s:%i, emptypool at %s:%i)", pool->filename, pool->fileline, filename, fileline); + if (pool->sentinel2 != MEMHEADER_SENTINEL_FOR_ADDRESS(&pool->sentinel2)) + Sys_Error("Mem_EmptyPool: trashed pool sentinel 2 (allocpool at %s:%i, emptypool at %s:%i)", pool->filename, pool->fileline, filename, fileline); // free memory owned by the pool while (pool->chain) @@ -544,9 +547,9 @@ void _Mem_CheckSentinels(void *data, const char *filename, int fileline) sentinel1 = MEMHEADER_SENTINEL_FOR_ADDRESS(&mem->sentinel); sentinel2 = MEMHEADER_SENTINEL_FOR_ADDRESS((unsigned char *) mem + sizeof(memheader_t) + mem->size); if (mem->sentinel != sentinel1) - Sys_Error("Mem_Free: trashed header sentinel 1 (alloc at %s:%i, sentinel check at %s:%i)", mem->filename, mem->fileline, filename, fileline); + Sys_Error("Mem_Free: trashed head sentinel (alloc at %s:%i, sentinel check at %s:%i)", mem->filename, mem->fileline, filename, fileline); if (memcmp((unsigned char *) mem + sizeof(memheader_t) + mem->size, &sentinel2, sizeof(sentinel2))) - Sys_Error("Mem_Free: trashed header sentinel 2 (alloc at %s:%i, sentinel check at %s:%i)", mem->filename, mem->fileline, filename, fileline); + Sys_Error("Mem_Free: trashed tail sentinel (alloc at %s:%i, sentinel check at %s:%i)", mem->filename, mem->fileline, filename, fileline); } #if MEMCLUMPING @@ -627,6 +630,44 @@ void Mem_ExpandableArray_FreeArray(memexpandablearray_t *l) memset(l, 0, sizeof(*l)); } +// VorteX: hacked Mem_ExpandableArray_AllocRecord, it does allocate record at certain index +void *Mem_ExpandableArray_AllocRecordAtIndex(memexpandablearray_t *l, size_t index) +{ + size_t j; + if (index == l->numarrays) + { + if (l->numarrays == l->maxarrays) + { + memexpandablearray_array_t *oldarrays = l->arrays; + l->maxarrays = max(l->maxarrays * 2, 128); + l->arrays = (memexpandablearray_array_t*) Mem_Alloc(l->mempool, l->maxarrays * sizeof(*l->arrays)); + if (oldarrays) + { + memcpy(l->arrays, oldarrays, l->numarrays * sizeof(*l->arrays)); + Mem_Free(oldarrays); + } + } + l->arrays[index].numflaggedrecords = 0; + l->arrays[index].data = (unsigned char *) Mem_Alloc(l->mempool, (l->recordsize + 1) * l->numrecordsperarray); + l->arrays[index].allocflags = l->arrays[index].data + l->recordsize * l->numrecordsperarray; + l->numarrays++; + } + if (l->arrays[index].numflaggedrecords < l->numrecordsperarray) + { + for (j = 0;j < l->numrecordsperarray;j++) + { + if (!l->arrays[index].allocflags[j]) + { + l->arrays[index].allocflags[j] = true; + l->arrays[index].numflaggedrecords++; + memset(l->arrays[index].data + l->recordsize * j, 0, l->recordsize); + return (void *)(l->arrays[index].data + l->recordsize * j); + } + } + } + return NULL; +} + void *Mem_ExpandableArray_AllocRecord(memexpandablearray_t *l) { size_t i, j; @@ -803,8 +844,10 @@ void MemStats_f(void) char* Mem_strdup (mempool_t *pool, const char* s) { char* p; - size_t sz = strlen (s) + 1; - if (s == NULL) return NULL; + size_t sz; + if (s == NULL) + return NULL; + sz = strlen (s) + 1; p = (char*)Mem_Alloc (pool, sz); strlcpy (p, s, sz); return p; @@ -819,7 +862,7 @@ void Memory_Init (void) { static union {unsigned short s;unsigned char b[2];} u; u.s = 0x100; - mem_bigendian = u.b[0]; + mem_bigendian = u.b[0] != 0; sentinel_seed = rand(); poolchain = NULL; @@ -839,5 +882,68 @@ void Memory_Init_Commands (void) Cmd_AddCommand ("memlist", MemList_f, "prints memory pool information (or if used as memlist 5 lists individual allocations of 5K or larger, 0 lists all allocations)"); Cvar_RegisterVariable (&developer_memory); Cvar_RegisterVariable (&developer_memorydebug); + Cvar_RegisterVariable (&sys_memsize_physical); + Cvar_RegisterVariable (&sys_memsize_virtual); + +#if defined(WIN32) +#ifdef _WIN64 + { + MEMORYSTATUSEX status; + // first guess + Cvar_SetValueQuick(&sys_memsize_virtual, 8388608); + // then improve + status.dwLength = sizeof(status); + if(GlobalMemoryStatusEx(&status)) + { + Cvar_SetValueQuick(&sys_memsize_physical, status.ullTotalPhys / 1048576.0); + Cvar_SetValueQuick(&sys_memsize_virtual, min(sys_memsize_virtual.value, status.ullTotalVirtual / 1048576.0)); + } + } +#else + { + MEMORYSTATUS status; + // first guess + Cvar_SetValueQuick(&sys_memsize_virtual, 2048); + // then improve + status.dwLength = sizeof(status); + GlobalMemoryStatus(&status); + Cvar_SetValueQuick(&sys_memsize_physical, status.dwTotalPhys / 1048576.0); + Cvar_SetValueQuick(&sys_memsize_virtual, min(sys_memsize_virtual.value, status.dwTotalVirtual / 1048576.0)); + } +#endif +#else + { + // first guess + Cvar_SetValueQuick(&sys_memsize_virtual, (sizeof(void*) == 4) ? 2048 : 268435456); + // then improve + { + // Linux, and BSD with linprocfs mounted + FILE *f = fopen("/proc/meminfo", "r"); + if(f) + { + static char buf[1024]; + while(fgets(buf, sizeof(buf), f)) + { + const char *p = buf; + if(!COM_ParseToken_Console(&p)) + continue; + if(!strcmp(com_token, "MemTotal:")) + { + if(!COM_ParseToken_Console(&p)) + continue; + Cvar_SetValueQuick(&sys_memsize_physical, atof(com_token) / 1024.0); + } + if(!strcmp(com_token, "SwapTotal:")) + { + if(!COM_ParseToken_Console(&p)) + continue; + Cvar_SetValueQuick(&sys_memsize_virtual, min(sys_memsize_virtual.value , atof(com_token) / 1024.0 + sys_memsize_physical.value)); + } + } + fclose(f); + } + } + } +#endif }