/* ----------------------------------------------------------------------------
*
- * (c) The GHC Team 1998-2006
+ * (c) The GHC Team 1998-2008
*
* Generational garbage collector: utilities
*
+ * Documentation on the architecture of the Garbage Collector can be
+ * found in the online commentary:
+ *
+ * http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Storage/GC
+ *
* --------------------------------------------------------------------------*/
-bdescr *gc_alloc_block(step *stp);
-bdescr *gc_alloc_scavd_block(step *stp);
+#include "SMP.h"
+
+bdescr *allocBlock_sync(void);
+void freeChain_sync(bdescr *bd);
+
+void push_scanned_block (bdescr *bd, step_workspace *ws);
+StgPtr todo_block_full (nat size, step_workspace *ws);
+StgPtr alloc_todo_block (step_workspace *ws, nat size);
+
+bdescr *grab_local_todo_block (step_workspace *ws);
+bdescr *steal_todo_block (nat s);
+
+// Returns true if a block is partially full. This predicate is used to try
+// to re-use partial blocks wherever possible, and to reduce wastage.
+// We might need to tweak the actual value.
+INLINE_HEADER rtsBool
+isPartiallyFull(bdescr *bd)
+{
+ return (bd->free + WORK_UNIT_WORDS < bd->start + BLOCK_SIZE_W);
+}
+
+
+#if DEBUG
+void printMutableList (generation *gen);
+#endif
+
+// Version of recordMutableGen for use during GC. This uses the
+// mutable lists attached to the current gc_thread structure, which
+// are the same as the mutable lists on the Capability.
+INLINE_HEADER void
+recordMutableGen_GC (StgClosure *p, nat gen_no)
+{
+ bdescr *bd;
+
+ bd = gct->mut_lists[gen_no];
+ if (bd->free >= bd->start + BLOCK_SIZE_W) {
+ bdescr *new_bd;
+ new_bd = allocBlock_sync();
+ new_bd->link = bd;
+ bd = new_bd;
+ gct->mut_lists[gen_no] = bd;
+ }
+ *bd->free++ = (StgWord)p;
+}