/* -----------------------------------------------------------------------------
- * $Id: BlockAlloc.c,v 1.2 1998/12/02 13:28:12 simonm Exp $
+ * $Id: BlockAlloc.c,v 1.7 2000/01/30 10:17:44 simonmar Exp $
*
+ * (c) The GHC Team 1998-2000
+ *
* The block allocator and free list manager.
*
* This is the architecture independent part of the block allocator.
*last = bd->link;
/* no initialisation necessary - this is already a
* self-contained block group. */
+#ifdef DEBUG
+ bd->free = bd->start; /* block isn't free now */
+#endif
return bd;
}
if (bd->blocks > n) { /* block too big... */
initMBlock(mblock); /* initialise the start fields */
bd = FIRST_BDESCR(mblock);
initGroup(n,bd); /* we know the group will fit */
- initGroup(BLOCKS_PER_MBLOCK-n, bd+n);
- freeGroup(bd+n); /* add the rest on to the free list */
+ if (n < BLOCKS_PER_MBLOCK) {
+ initGroup(BLOCKS_PER_MBLOCK-n, bd+n);
+ freeGroup(bd+n); /* add the rest on to the free list */
+ }
return bd;
}
if (bd->blocks == BLOCKS_PER_MBLOCK) { /* whole megablock found */
- if (grp_start == NULL) { /* is it the first one we've found? */
+ /* is it the first one we've found or a non-contiguous megablock? */
+ if (grp_start == NULL ||
+ bd->start != last->start + MBLOCK_SIZE/sizeof(W_)) {
grp_start = bd;
grp_prev = last;
mbs_found = 1;
return;
}
+#ifdef DEBUG
+ p->free = (void *)-1; /* indicates that this block is free */
+ p->step = NULL;
+ p->gen = NULL;
+ /* fill the block group with garbage if sanity checking is on */
+ IF_DEBUG(sanity,memset(p->start, 0xaa, p->blocks * BLOCK_SIZE));
+#endif
+
/* find correct place in free list to place new group */
last = NULL;
for (bd = free_list; bd != NULL && bd->start < p->start;
bdescr *next_bd;
while (bd != NULL) {
next_bd = bd->link;
-#ifdef DEBUG
- bd->free = (void *)-1; /* indicates that this block is free */
-#endif
freeGroup(bd);
bd = next_bd;
}
}
}
}
+
+nat /* BLOCKS */
+countFreeList(void)
+{
+ bdescr *bd;
+ lnat total_blocks = 0;
+
+ for (bd = free_list; bd != NULL; bd = bd->link) {
+ total_blocks += bd->blocks;
+ }
+ return total_blocks;
+}
#endif