- if (block->next == &mainzone->blocklist)
- break; // all blocks have been hit
- if ( (byte *)block + block->size != (byte *)block->next)
- Sys_Error ("Z_CheckHeap: block size does not touch the next block\n");
- if ( block->next->prev != block)
- Sys_Error ("Z_CheckHeap: next block doesn't have proper back link\n");
- if (!block->tag && !block->next->tag)
- Sys_Error ("Z_CheckHeap: two consecutive free blocks\n");
+ 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 (mem_mutex)
+ Thread_LockMutex(mem_mutex);
+ 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);
+ 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 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;
+ 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);