+ if (pool == NULL)
+ {
+ if(olddata)
+ pool = ((memheader_t *)((unsigned char *) olddata - sizeof(memheader_t)))->pool;
+ else
+ Sys_Error("Mem_Alloc: pool == NULL (alloc at %s:%i)", filename, fileline);
+ }
+ if (mem_mutex)
+ Thread_LockMutex(mem_mutex);
+ if (developer_memory.integer || size >= developer_memoryreportlargerthanmb.value * 1048576)
+ Con_DPrintf("Mem_Alloc: pool %s, file %s:%i, size %f bytes (%f MB)\n", pool->name, filename, fileline, (double)size, (double)size / 1048576.0f);
+ //if (developer.integer > 0 && developer_memorydebug.integer)
+ // _Mem_CheckSentinelsGlobal(filename, fileline);
+ pool->totalsize += size;
+ realsize = alignment + sizeof(memheader_t) + size + sizeof(sentinel2);
+ pool->realsize += realsize;
+ 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 of size %f (%.3fMB) at %s:%i)", (double)realsize, (double)realsize / (1 << 20), 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;
+ mem->pool = pool;
+
+ // calculate sentinels (detects buffer overruns, in a way that is hard to exploit)
+ sentinel1 = MEMHEADER_SENTINEL_FOR_ADDRESS(&mem->sentinel);
+ sentinel2 = MEMHEADER_SENTINEL_FOR_ADDRESS((unsigned char *) mem + sizeof(memheader_t) + mem->size);
+ mem->sentinel = sentinel1;
+ memcpy((unsigned char *) mem + sizeof(memheader_t) + mem->size, &sentinel2, sizeof(sentinel2));
+
+ // append to head of list
+ mem->next = pool->chain;
+ mem->prev = NULL;
+ pool->chain = mem;
+ if (mem->next)
+ mem->next->prev = mem;
+
+ if (mem_mutex)
+ Thread_UnlockMutex(mem_mutex);
+
+ // 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));