[project @ 2001-02-12 12:22:01 by simonmar]
[ghc-hetmet.git] / ghc / rts / BlockAlloc.c
index e0ded8e..6819463 100644 (file)
@@ -1,6 +1,8 @@
 /* -----------------------------------------------------------------------------
- * $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.
@@ -71,6 +73,9 @@ allocGroup(nat n)
       *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... */
@@ -86,8 +91,10 @@ allocGroup(nat n)
   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;
 }
 
@@ -124,7 +131,9 @@ allocMegaGroup(nat n)
 
     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;
@@ -210,6 +219,14 @@ freeGroup(bdescr *p)
     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; 
@@ -252,9 +269,6 @@ freeChain(bdescr *bd)
   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;
   }
@@ -301,4 +315,16 @@ checkFreeListSanity(void)
     }
   }
 }
+
+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