📄 z_zone.c
字号:
else { // free the rover block (adding the size to base) // the rover can be the base block base = base->prev; Z_Free ((byte *)rover+sizeof(memblock_t)); base = base->next; rover = base->next; } } else rover = rover->next; basedata = ALIGN((ULONG)base + sizeof(memblock_t)); } while (base->user || //Hurdler: huh? it crashed on my system :( (with 777.wad and 777.deh, only software mode) ((ULONG)base)+base->size<basedata+size-sizeof(memblock_t)); // aligning can leave free space in current block so make it realy free if( alignbits ) { memblock_t *newbase=((memblock_t*)basedata) - 1; int sizediff = (byte*)newbase - (byte*)base; if( sizediff > MINFRAGMENT ) { newbase->prev = base; newbase->next = base->next; newbase->next->prev = newbase; newbase->size = base->size - sizediff; base->next = newbase; base->size = sizediff; } else { // ajuste size of preview block if adjacent (not cycling) if( base->prev<base ) base->prev->size += sizediff; base->prev->next = newbase; base->next->prev = newbase; base->size -= sizediff; memcpy(newbase,base,sizeof(memblock_t)); } base = newbase; } // found a block big enough extra = base->size - size; if (extra > MINFRAGMENT) { // there will be a free fragment after the allocated block newblock = (memblock_t *) ((byte *)base + size ); newblock->size = extra; // NULL indicates free block. newblock->user = NULL; newblock->tag = 0; newblock->id = 0; newblock->prev = base; newblock->next = base->next; newblock->next->prev = newblock; base->next = newblock; base->size = size; } if (user) { // mark as an in use block base->user = user; *(void **)user = (void *) ((byte *)base + sizeof(memblock_t)); } else { if (tag >= PU_PURGELEVEL) I_Error ("Z_Malloc: an owner is required for purgable blocks"); // mark as in use, but unowned base->user = (void *)2; } base->tag = tag;#ifdef ZDEBUG base->ownerfile = file; base->ownerline = line;#endif // next allocation will start looking here mainzone->rover = base->next; base->id = ZONEID; return (void *) ((byte *)base + sizeof(memblock_t));}//// Z_FreeTags//void Z_FreeTags( int lowtag, int hightag ){ memblock_t* block; memblock_t* next;#ifdef DEBUGMEMCLACH return;#endif for (block = mainzone->blocklist.next ; block != &mainzone->blocklist ; block = next) { // get link before freeing next = block->next; // free block? if (!block->user) continue; if (block->tag >= lowtag && block->tag <= hightag) Z_Free ( (byte *)block+sizeof(memblock_t)); }}//// Z_DumpHeap// Note: TFileDumpHeap( stdout ) ?//void Z_DumpHeap ( int lowtag, int hightag ){ memblock_t* block; CONS_Printf ("zone size: %i location: %p\n", mainzone->size,mainzone); CONS_Printf ("tag range: %i to %i\n", lowtag, hightag); for (block = mainzone->blocklist.next ; ; block = block->next) { if (block->tag >= lowtag && block->tag <= hightag) CONS_Printf ("block:%p size:%7i user:%p tag:%3i prev:%p next:%p\n", block, block->size, block->user, block->tag, block->next, block->prev); if (block->next == &mainzone->blocklist) { // all blocks have been hit break; } if ( (byte *)block + block->size != (byte *)block->next) CONS_Printf ("ERROR: block size does not touch the next block\n"); if ( block->next->prev != block) CONS_Printf ("ERROR: next block doesn't have proper back link\n"); if (!block->user && !block->next->user) CONS_Printf ("ERROR: two consecutive free blocks\n"); }}//// Z_FileDumpHeap//void Z_FileDumpHeap (FILE* f){ memblock_t* block; int i=0; fprintf (f, "zone size: %i location: %p\n",mainzone->size,mainzone); for (block = mainzone->blocklist.next ; ; block = block->next) { i++; fprintf (f,"block:%p size:%7i user:%7x tag:%3i prev:%p next:%p id:%7i\n", block, block->size, (int)block->user, block->tag, block->prev, block->next, block->id); if (block->next == &mainzone->blocklist) { // all blocks have been hit break; } if ( (block->user > (void **)0x100) && ((int)(*(block->user))!=((int)block)+(int)sizeof(memblock_t))) fprintf (f,"ERROR: block don't have a proper user\n"); if ( (byte *)block + block->size != (byte *)block->next) fprintf (f,"ERROR: block size does not touch the next block\n"); if ( block->next->prev != block) fprintf (f,"ERROR: next block doesn't have proper back link\n"); if (!block->user && !block->next->user) fprintf (f,"ERROR: two consecutive free blocks\n"); } fprintf (f,"Total : %d blocks\n" "===============================================================================\n\n",i);}//// Z_CheckHeap//void Z_CheckHeap (int i){ memblock_t* block;#ifdef DEBUGMEMCLACH return;#endif for (block = mainzone->blocklist.next ; ; block = block->next) { if (block->next == &mainzone->blocklist) { // all blocks have been hit break; } if ( (block->user > (void **)0x100) && ((int)(*(block->user))!=((int)block)+(int)sizeof(memblock_t))) I_Error ("Z_CheckHeap: block don't have a proper user %d\n",i); if ( (byte *)block + block->size != (byte *)block->next) I_Error ("Z_CheckHeap: block size does not touch the next block %d\n",i); if ( block->next->prev != block) I_Error ("Z_CheckHeap: next block doesn't have proper back link %d\n",i); if (!block->user && !block->next->user) I_Error ("Z_CheckHeap: two consecutive free blocks %d\n",i); }}//// Z_ChangeTag//void Z_ChangeTag2 ( void* ptr, int tag ){ memblock_t* block;#ifdef DEBUGMEMCLACH// can't free because the most pu_cache allocated is to use juste after// if(tag>=PU_PURGELEVEL)// Z_Free(ptr); return;#endif block = (memblock_t *) ( (byte *)ptr - sizeof(memblock_t)); if (block->id != ZONEID) I_Error ("Z_ChangeTag: freed a pointer without ZONEID"); if (tag >= PU_PURGELEVEL && (unsigned)block->user < 0x100) I_Error ("Z_ChangeTag: an owner is required for purgable blocks"); block->tag = tag;}//// Z_FreeMemory//void Z_FreeMemory (int *realfree,int *cachemem,int *usedmem,int *largefreeblock){ memblock_t* block; int freeblock=0;#ifdef DEBUGMEMCLACH return;#endif *realfree = 0; *cachemem = 0; *usedmem = 0; *largefreeblock = 0; for (block = mainzone->blocklist.next ; block != &mainzone->blocklist; block = block->next) { if (block->user==0) { // free memory *realfree += block->size; freeblock += block->size; if(freeblock>*largefreeblock) *largefreeblock = freeblock; } else if(block->tag >= PU_PURGELEVEL) { // purgable memory (cache) *cachemem += block->size; freeblock += block->size; if(freeblock>*largefreeblock) *largefreeblock = freeblock; } else { // used block *usedmem += block->size; freeblock=0; } }}//// Z_TagUsage// - return number of bytes currently allocated in the heap for the given tagint Z_TagUsage (int tagnum){ memblock_t* block; int bytes = 0; for (block = mainzone->blocklist.next ; block != &mainzone->blocklist; block = block->next) { if (block->user!=0 && block->tag == tagnum) bytes += block->size; } return bytes;}void Command_Memfree_f( void ){ int free,cache,used,largefreeblock; ULONG freebytes, totalbytes; Z_CheckHeap (-1); Z_FreeMemory(&free,&cache,&used,&largefreeblock); CONS_Printf("\2Memory Heap Info\n"); CONS_Printf("Total heap size : %7d kb\n", mb_used<<10); CONS_Printf("used memory : %7d kb\n", used>>10); CONS_Printf("free memory : %7d kb\n", free>>10); CONS_Printf("cache memory : %7d kb\n", cache>>10); CONS_Printf("largest free block : %7d kb\n", largefreeblock>>10);#ifdef HWRENDER if( rendermode != render_soft ) { CONS_Printf("Patch info headers : %7d kb\n", Z_TagUsage(PU_HWRPATCHINFO)>>10); CONS_Printf("HW Texture cache : %7d kb\n", Z_TagUsage(PU_HWRCACHE)>>10); CONS_Printf("Plane polygone : %7d kb\n", Z_TagUsage(PU_HWRPLANE)>>10); CONS_Printf("HW Texture used : %7d kb\n", HWD.pfnGetTextureUsed()>>10); }#endif CONS_Printf("\2System Memory Info\n"); freebytes = I_GetFreeMem(&totalbytes); CONS_Printf("Total physical memory: %6d kb\n", totalbytes>>10); CONS_Printf("Available physical memory: %6d kb\n", freebytes>>10);}char *Z_Strdup(const char *s, int tag, void **user){ return strcpy(Z_Malloc(strlen(s)+1, tag, user), s);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -