📄 z_zone.c
字号:
// Emacs style mode select -*- C++ -*- //-----------------------------------------------------------------------------//// $Id: z_zone.c,v 1.15 2001/03/13 22:14:20 stroggonmeth Exp $//// Copyright (C) 1993-1996 by id Software, Inc.// Portions Copyright (C) 1998-2000 by DooM Legacy Team.//// This program is free software; you can redistribute it and/or// modify it under the terms of the GNU General Public License// as published by the Free Software Foundation; either version 2// of the License, or (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.////// $Log: z_zone.c,v $// Revision 1.15 2001/03/13 22:14:20 stroggonmeth// Long time no commit. 3D floors, FraggleScript, portals, ect.//// Revision 1.14 2001/01/25 22:15:44 bpereira// added heretic support//// Revision 1.13 2000/11/06 20:52:16 bpereira// no message//// Revision 1.12 2000/11/03 13:15:13 hurdler// Some debug comments, please verify this and change what is needed!//// Revision 1.11 2000/11/02 17:50:10 stroggonmeth// Big 3Dfloors & FraggleScript commit!!//// Revision 1.10 2000/10/14 18:33:34 hurdler// sorry, I forgot to put an #ifdef for hw memory report//// Revision 1.9 2000/10/14 18:32:16 hurdler// sorry, I forgot to put an #ifdef for hw memory report//// Revision 1.8 2000/10/04 16:33:54 hurdler// Implement hardware texture memory stats//// Revision 1.7 2000/10/02 18:25:45 bpereira// no message//// Revision 1.6 2000/08/31 14:30:56 bpereira// no message//// Revision 1.5 2000/07/01 09:23:49 bpereira// no message//// Revision 1.4 2000/04/30 10:30:10 bpereira// no message//// Revision 1.3 2000/04/24 20:24:38 bpereira// no message//// Revision 1.2 2000/02/27 00:42:11 hurdler// fix CR+LF problem//// Revision 1.1.1.1 2000/02/22 20:32:32 hurdler// Initial import into CVS (v1.29 pr3)////// DESCRIPTION:// Zone Memory Allocation. Neat.////-----------------------------------------------------------------------------#include "doomdef.h"#include "z_zone.h"#include "i_system.h"#include "command.h"#include "m_argv.h"#include "i_video.h"#include "doomstat.h"#ifdef HWRENDER#include "hardware/hw_drv.h" // for hardware memory stats#endif// =========================================================================// ZONE MEMORY ALLOCATION// =========================================================================//// There is never any space between memblocks,// and there will never be two contiguous free memblocks.// The rover can be left pointing at a non-empty block.//// It is of no value to free a cachable block,// because it will get overwritten automatically if needed.//#define ZONEID 0x1d4a11// use malloc so when go over malloced region do a sigsegv//#define DEBUGMEMCLACHtypedef struct{ // total bytes malloced, including header int size; // start / end cap for linked list memblock_t blocklist; memblock_t* rover;} memzone_t;static memzone_t* mainzone;void Command_Memfree_f( void );//// Z_ClearZone//// UNUSE at this time 14 nov 98void Z_ClearZone (memzone_t* zone){ memblock_t* block; // set the entire zone to one free block zone->blocklist.next = zone->blocklist.prev = block = (memblock_t *)( (byte *)zone + sizeof(memzone_t) ); zone->blocklist.user = (void *)zone; zone->blocklist.tag = PU_STATIC; zone->rover = block; block->prev = block->next = &zone->blocklist; // NULL indicates a free block. block->user = NULL; block->size = zone->size - sizeof(memzone_t);}static byte mb_used = 6;//// Z_Init//void Z_Init (void){#ifndef DEBUGMEMCLACH memblock_t* block; int size; ULONG free,total; if( M_CheckParm ("-mb") ) { if( M_IsNextParm() ) mb_used = atoi (M_GetNextParm()); else I_Error("usage : -mb <numbers of megabyte fot the heap>"); } else { free = I_GetFreeMem(&total)>>20; CONS_Printf("system memory %dMb free %dMb\n",total>>20,free); // we assume that systeme use a lot of memory for disk cache if( free<6 ) free=total>>21; mb_used = min(max(free, mb_used), 20); // min 6Mb max 20Mb } CONS_Printf ("%d megabytes requested for Z_Init.\n", mb_used); size = mb_used<<20; mainzone = (memzone_t *)malloc(size); if( !mainzone ) I_Error("Could not allocate %d megabytes.\n" "Please use -mb parameter and specify a lower value.\n", mb_used); // tuch memory to stop swaping memset(mainzone, 0, size);// if( M_checkParm("-lock") )// I_LockMemory(mainzone); mainzone->size = size; // set the entire zone to one free block // block is the only free block in the zone mainzone->blocklist.next = mainzone->blocklist.prev = block = (memblock_t *)( (byte *)mainzone + sizeof(memzone_t) ); mainzone->blocklist.user = (void *)mainzone; mainzone->blocklist.tag = PU_STATIC; mainzone->rover = block; block->prev = block->next = &mainzone->blocklist; // NULL indicates a free block. block->user = NULL; block->size = mainzone->size - sizeof(memzone_t); COM_AddCommand ("memfree", Command_Memfree_f);#endif}//// Z_Free//#ifdef ZDEBUGvoid Z_Free2(void* ptr ,char *file,int line)#elsevoid Z_Free (void* ptr)#endif{ memblock_t* block; memblock_t* other; block = (memblock_t *) ( (byte *)ptr - sizeof(memblock_t));#ifdef DEBUGMEMCLACH if (block->user > (void **)0x100) *block->user = 0; free(block); return;#endif#ifdef ZDEBUG // SoM: HARDERCORE debuging // Write all Z_Free's to a debug file if(debugfile) fprintf(debugfile, "ZFREE@File: %s, line: %i\n", file, line); //BP: hardcore debuging // check if there is not a user in this zonefor (other = mainzone->blocklist.next ; other->next != &mainzone->blocklist; other = other->next){ if((other!=block) && (other->user>(void **)0x100) && ((other->user)>=(void **)block) && ((other->user)<=(void **)((byte *)block)+block->size) ) { //I_Error("Z_Free: Pointer in zone\n"); I_Error("Z_Free: Pointer %s:%d in zone at %s:%i",other->ownerfile,other->ownerline,file,line); }}#endif if (block->id != ZONEID) I_Error ("Z_Free: freed a pointer without ZONEID");#ifdef PARANOIA // get direct a segv when using a pointer that isn't right memset(ptr,0,block->size-sizeof(memblock_t));#endif if (block->user > (void **)0x100) { // smaller values are not pointers // Note: OS-dependend? // clear the user's mark *block->user = 0; } // mark as free block->user = NULL; block->tag = 0; block->id = 0; other = block->prev; if (!other->user) { // merge with previous free block other->size += block->size; other->next = block->next; other->next->prev = other; if (block == mainzone->rover) mainzone->rover = other; block = other; } other = block->next; if (!other->user) { // merge the next free block onto the end block->size += other->size; block->next = other->next; block->next->prev = block; if (other == mainzone->rover) mainzone->rover = block; }}//// Z_Malloc// You can pass a NULL user if the tag is < PU_PURGELEVEL.//#define MINFRAGMENT sizeof(memblock_t)#ifdef ZDEBUGvoid* Z_Malloc2 (int size, int tag, void *user,int alignbits, char *file,int line)#elsevoid* Z_MallocAlign( int size, int tag, void* user, int alignbits)#endif{ ULONG alignmask=(1<<alignbits)-1;#define ALIGN(a) (((ULONG)a+alignmask) & ~alignmask) int extra; int basedata; memblock_t* start; memblock_t* rover; memblock_t* newblock; memblock_t* base; size = (size + 3) & ~3; // scan through the block list, // looking for the first free block // of sufficient size, // throwing out any purgable blocks along the way. // account for size of block header size += sizeof(memblock_t);#ifdef DEBUGMEMCLACH newblock=malloc(size); newblock->id=ZONEID; newblock->tag = tag; newblock->user = user; ((byte *)newblock) += sizeof(memblock_t); if(user) *(void **)user=newblock; return newblock;#endif // if there is a free block behind the rover, // back up over them // added comment : base is used to point at the begin of a region in case // when there is two (or more) adjacent purgable block base = mainzone->rover; if (!base->prev->user) base = base->prev; rover = base; start = base->prev; do { if (rover == start) { // scanned all the way around the list //faB: debug to see if problems of memory fragmentation.. Command_Memfree_f(); I_Error ("Z_Malloc: failed on allocation of %i bytes\n" "Try to increase heap size using -mb parameter (actual heap size : %d Mb)\n", size, mb_used); } if (rover->user) { if (rover->tag < PU_PURGELEVEL) { // hit a block that can't be purged, // so move base past it base = rover = rover->next; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -