summaryrefslogtreecommitdiff
path: root/src/z_zone.c
diff options
context:
space:
mode:
authorSimon Howard2005-09-22 12:58:46 +0000
committerSimon Howard2005-09-22 12:58:46 +0000
commitd29e73f05afa62a514e1156afa2fb40abae6346e (patch)
treeef05840ea72877942144b05f0d6873e52d5c0ff6 /src/z_zone.c
parent53a7ee34035f3d6cf151c87f54f1bf15f04a2460 (diff)
downloadchocolate-doom-d29e73f05afa62a514e1156afa2fb40abae6346e.tar.gz
chocolate-doom-d29e73f05afa62a514e1156afa2fb40abae6346e.tar.bz2
chocolate-doom-d29e73f05afa62a514e1156afa2fb40abae6346e.zip
Use a new PU_FREE tag to mark free blocks, rather than the 'user' field
(avoids using magic numbers to mark allocated blocks with no user) Subversion-branch: /trunk/chocolate-doom Subversion-revision: 119
Diffstat (limited to 'src/z_zone.c')
-rw-r--r--src/z_zone.c191
1 files changed, 97 insertions, 94 deletions
diff --git a/src/z_zone.c b/src/z_zone.c
index 1922a62a..3739a289 100644
--- a/src/z_zone.c
+++ b/src/z_zone.c
@@ -1,7 +1,7 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
-// $Id: z_zone.c 8 2005-07-23 16:44:57Z fraggle $
+// $Id: z_zone.c 119 2005-09-22 12:58:46Z fraggle $
//
// Copyright(C) 1993-1996 Id Software, Inc.
// Copyright(C) 2005 Simon Howard
@@ -22,6 +22,10 @@
// 02111-1307, USA.
//
// $Log$
+// Revision 1.3 2005/09/22 12:58:46 fraggle
+// Use a new PU_FREE tag to mark free blocks, rather than the 'user' field
+// (avoids using magic numbers to mark allocated blocks with no user)
+//
// Revision 1.2 2005/07/23 16:44:57 fraggle
// Update copyright to GNU GPL
//
@@ -35,7 +39,7 @@
//-----------------------------------------------------------------------------
static const char
-rcsid[] = "$Id: z_zone.c 8 2005-07-23 16:44:57Z fraggle $";
+rcsid[] = "$Id: z_zone.c 119 2005-09-22 12:58:46Z fraggle $";
#include "z_zone.h"
#include "i_system.h"
@@ -92,8 +96,8 @@ void Z_ClearZone (memzone_t* zone)
block->prev = block->next = &zone->blocklist;
- // NULL indicates a free block.
- block->user = NULL;
+ // a free block.
+ block->tag = PU_FREE;
block->size = zone->size - sizeof(memzone_t);
}
@@ -122,8 +126,8 @@ void Z_Init (void)
block->prev = block->next = &mainzone->blocklist;
- // NULL indicates a free block.
- block->user = NULL;
+ // free block
+ block->tag = PU_FREE;
block->size = mainzone->size - sizeof(memzone_t);
}
@@ -142,45 +146,42 @@ void Z_Free (void* ptr)
if (block->id != ZONEID)
I_Error ("Z_Free: freed a pointer without ZONEID");
- if (block->user > (void **)0x100)
+ if (block->tag != PU_FREE && block->user != NULL)
{
- // smaller values are not pointers
- // Note: OS-dependend?
-
- // clear the user's mark
- *block->user = 0;
+ // clear the user's mark
+ *block->user = 0;
}
// mark as free
- block->user = NULL;
- block->tag = 0;
+ block->tag = PU_FREE;
+ block->user = NULL;
block->id = 0;
other = block->prev;
- if (!other->user)
+ if (other->tag == PU_FREE)
{
- // merge with previous free block
- other->size += block->size;
- other->next = block->next;
- other->next->prev = other;
+ // merge with previous free block
+ other->size += block->size;
+ other->next = block->next;
+ other->next->prev = other;
- if (block == mainzone->rover)
- mainzone->rover = other;
+ if (block == mainzone->rover)
+ mainzone->rover = other;
- block = other;
+ block = other;
}
other = block->next;
- if (!other->user)
+ if (other->tag == PU_FREE)
{
- // merge the next free block onto the end
- block->size += other->size;
- block->next = other->next;
- block->next->prev = block;
+ // 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;
+ if (other == mainzone->rover)
+ mainzone->rover = block;
}
}
@@ -204,6 +205,7 @@ Z_Malloc
memblock_t* rover;
memblock_t* newblock;
memblock_t* base;
+ void *result;
size = (size + 3) & ~3;
@@ -219,42 +221,46 @@ Z_Malloc
// back up over them
base = mainzone->rover;
- if (!base->prev->user)
- base = base->prev;
+ if (base->prev->tag == PU_FREE)
+ base = base->prev;
rover = base;
start = base->prev;
do
{
- if (rover == start)
- {
- // scanned all the way around the list
- I_Error ("Z_Malloc: failed on allocation of %i bytes", size);
- }
+ if (rover == start)
+ {
+ // scanned all the way around the list
+ Z_FileDumpHeap(stdout);
+ I_Error ("Z_Malloc: failed on allocation of %i bytes", size);
+ }
- 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;
- }
- 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;
- } while (base->user || base->size < size);
+ if (rover->tag != PU_FREE)
+ {
+ if (rover->tag < PU_PURGELEVEL)
+ {
+ // hit a block that can't be purged,
+ // so move base past it
+ base = rover = rover->next;
+ }
+ 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;
+ }
+
+ } while (base->tag != PU_FREE || base->size < size);
// found a block big enough
@@ -262,43 +268,39 @@ Z_Malloc
if (extra > MINFRAGMENT)
{
- // there will be a free fragment after the allocated block
- newblock = (memblock_t *) ((byte *)base + size );
- newblock->size = extra;
+ // 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->prev = base;
- newblock->next = base->next;
- newblock->next->prev = newblock;
-
- base->next = newblock;
- base->size = size;
+ newblock->tag = PU_FREE;
+ newblock->user = NULL;
+ 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)
+ if (user == NULL && 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->user = user;
base->tag = tag;
+ result = (void *) ((byte *)base + sizeof(memblock_t));
+
+ if (base->user)
+ {
+ *base->user = result;
+ }
+
// next allocation will start looking here
mainzone->rover = base->next;
base->id = ZONEID;
- return (void *) ((byte *)base + sizeof(memblock_t));
+ return result;
}
@@ -322,7 +324,7 @@ Z_FreeTags
next = block->next;
// free block?
- if (!block->user)
+ if (block->tag == PU_FREE)
continue;
if (block->tag >= lowtag && block->tag <= hightag)
@@ -367,7 +369,7 @@ Z_DumpHeap
if ( block->next->prev != block)
printf ("ERROR: next block doesn't have proper back link\n");
- if (!block->user && !block->next->user)
+ if (block->tag == PU_FREE && block->next->tag == PU_FREE)
printf ("ERROR: two consecutive free blocks\n");
}
}
@@ -399,7 +401,7 @@ void Z_FileDumpHeap (FILE* f)
if ( block->next->prev != block)
fprintf (f,"ERROR: next block doesn't have proper back link\n");
- if (!block->user && !block->next->user)
+ if (block->tag == PU_FREE && block->next->tag == PU_FREE)
fprintf (f,"ERROR: two consecutive free blocks\n");
}
}
@@ -427,7 +429,7 @@ void Z_CheckHeap (void)
if ( block->next->prev != block)
I_Error ("Z_CheckHeap: next block doesn't have proper back link\n");
- if (!block->user && !block->next->user)
+ if (block->tag == PU_FREE && block->next->tag == PU_FREE)
I_Error ("Z_CheckHeap: two consecutive free blocks\n");
}
}
@@ -448,10 +450,10 @@ Z_ChangeTag2
block = (memblock_t *) ( (byte *)ptr - sizeof(memblock_t));
if (block->id != ZONEID)
- I_Error ("Z_ChangeTag: freed a pointer without 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");
+ if (tag >= PU_PURGELEVEL && block->user == NULL)
+ I_Error ("Z_ChangeTag: an owner is required for purgable blocks");
block->tag = tag;
}
@@ -469,12 +471,13 @@ int Z_FreeMemory (void)
free = 0;
for (block = mainzone->blocklist.next ;
- block != &mainzone->blocklist;
- block = block->next)
+ block != &mainzone->blocklist;
+ block = block->next)
{
- if (!block->user || block->tag >= PU_PURGELEVEL)
- free += block->size;
+ if (block->tag == PU_FREE || block->tag >= PU_PURGELEVEL)
+ free += block->size;
}
+
return free;
}