static void crypto_free (void *ptr) { dmalloc_free (__FILE__, __LINE__, ptr, DMALLOC_FUNC_FREE); }
void *(Z_Malloc)(size_t size, int tag, void **user #ifdef INSTRUMENTED , const char *file, int line #endif ) { memblock_t *block = NULL; #ifdef INSTRUMENTED #ifdef CHECKHEAP Z_CheckHeap(); #endif file_history[malloc_history][history_index[malloc_history]] = file; line_history[malloc_history][history_index[malloc_history]++] = line; history_index[malloc_history] &= ZONE_HISTORY-1; #endif #ifdef ZONEIDCHECK if (tag >= PU_PURGELEVEL && !user) I_Error ("Z_Malloc: An owner is required for purgable blocks" #ifdef INSTRUMENTED "Source: %s:%d", file, line #endif ); #endif if (!size) return user ? *user = NULL : NULL; // malloc(0) returns NULL size = (size+CHUNK_SIZE-1) & ~(CHUNK_SIZE-1); // round to chunk size if (memory_size > 0 && ((free_memory + memory_size) < (int)(size + HEADER_SIZE))) { memblock_t *end_block; block = blockbytag[PU_CACHE]; if (block) { end_block = block->prev; while (1) { memblock_t *next = block->next; #ifdef INSTRUMENTED (Z_Free)((char *) block + HEADER_SIZE, file, line); #else (Z_Free)((char *) block + HEADER_SIZE); #endif if (((free_memory + memory_size) >= (int)(size + HEADER_SIZE)) || (block == end_block)) break; block = next; // Advance to next block } } block = NULL; } #ifdef HAVE_LIBDMALLOC while (!(block = dmalloc_malloc(file,line,size + HEADER_SIZE,DMALLOC_FUNC_MALLOC,0,0))) { #else while (!(block = (malloc)(size + HEADER_SIZE))) { #endif if (!blockbytag[PU_CACHE]) I_Error ("Z_Malloc: Failure trying to allocate %lu bytes" #ifdef INSTRUMENTED "\nSource: %s:%d" #endif ,(unsigned long) size #ifdef INSTRUMENTED , file, line #endif ); Z_FreeTags(PU_CACHE,PU_CACHE); } if (!blockbytag[tag]) { blockbytag[tag] = block; block->next = block->prev = block; } else { blockbytag[tag]->prev->next = block; block->prev = blockbytag[tag]->prev; block->next = blockbytag[tag]; blockbytag[tag]->prev = block; } block->size = size; #ifdef INSTRUMENTED if (tag >= PU_PURGELEVEL) purgable_memory += block->size; else active_memory += block->size; #endif free_memory -= block->size; #ifdef INSTRUMENTED block->file = file; block->line = line; #endif #ifdef ZONEIDCHECK block->id = ZONEID; // signature required in block header #endif block->tag = tag; // tag block->user = user; // user block = (memblock_t *)((char *) block + HEADER_SIZE); if (user) // if there is a user *user = block; // set user to point to new block #ifdef INSTRUMENTED Z_DrawStats(); // print memory allocation stats // scramble memory -- weed out any bugs memset(block, gametic & 0xff, size); #endif return block; } void (Z_Free)(void *p #ifdef INSTRUMENTED , const char *file, int line #endif ) { memblock_t *block = (memblock_t *)((char *) p - HEADER_SIZE); #ifdef INSTRUMENTED #ifdef CHECKHEAP Z_CheckHeap(); #endif file_history[free_history][history_index[free_history]] = file; line_history[free_history][history_index[free_history]++] = line; history_index[free_history] &= ZONE_HISTORY-1; #endif if (!p) return; #ifdef ZONEIDCHECK if (block->id != ZONEID) I_Error("Z_Free: freed a pointer without ZONEID" #ifdef INSTRUMENTED "\nSource: %s:%d" "\nSource of malloc: %s:%d" , file, line, block->file, block->line #endif ); block->id = 0; // Nullify id so another free fails #endif if (block->user) // Nullify user if one exists *block->user = NULL; if (block == block->next) blockbytag[block->tag] = NULL; else if (blockbytag[block->tag] == block) blockbytag[block->tag] = block->next; block->prev->next = block->next; block->next->prev = block->prev; free_memory += block->size; #ifdef INSTRUMENTED if (block->tag >= PU_PURGELEVEL) purgable_memory -= block->size; else active_memory -= block->size; /* scramble memory -- weed out any bugs */ memset(block, gametic & 0xff, block->size + HEADER_SIZE); #endif #ifdef HAVE_LIBDMALLOC dmalloc_free(file,line,block,DMALLOC_FUNC_MALLOC); #else (free)(block); #endif #ifdef INSTRUMENTED Z_DrawStats(); // print memory allocation stats #endif }