Repository : ssh://darcs.haskell.org//srv/darcs/ghc

On branch  : ghc-7.6

http://hackage.haskell.org/trac/ghc/changeset/4709d3e1c493536e6e3058ae15de0d86c01e417a

>---------------------------------------------------------------

commit 4709d3e1c493536e6e3058ae15de0d86c01e417a
Author: Simon Marlow <[email protected]>
Date:   Mon Aug 20 13:52:07 2012 +0100

    Retain ordering of finalizers during GC (#7160)
    
    This came up since the addition of C finalizers, since Haskell
    finalizers are already stored in an explicit list.  C finalizers on
    the other hand get a WEAK object each, so in order to run them in the
    right order we have to make sure that list stays in the correct
    order.  I hate adding new invariants, but this is the quickest way to
    fix the bug for now.  A better way to fix it would be to have a single
    WEAK object with a list of finaliers attached to it, and a primop
    for adding finalizers to the list.
    
    MERGED from commit cec899d9fb668d4adccf731a63902e5be49f0660

>---------------------------------------------------------------

 rts/sm/MarkWeak.c |   19 ++++++++++++++-----
 1 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/rts/sm/MarkWeak.c b/rts/sm/MarkWeak.c
index f9275ec..b7d6226 100644
--- a/rts/sm/MarkWeak.c
+++ b/rts/sm/MarkWeak.c
@@ -78,6 +78,7 @@ static WeakStage weak_stage;
 /* Weak pointers
  */
 StgWeak *old_weak_ptr_list; // also pending finaliser list
+StgWeak *weak_ptr_list_tail;
 
 // List of threads found to be unreachable
 StgTSO *resurrected_threads;
@@ -90,6 +91,7 @@ initWeakForGC(void)
 {
     old_weak_ptr_list = weak_ptr_list;
     weak_ptr_list = NULL;
+    weak_ptr_list_tail = NULL;
     weak_stage = WeakPtrs;
     resurrected_threads = END_TSO_QUEUE;
 }
@@ -139,11 +141,18 @@ traverseWeakPtrList(void)
                  evacuate(&w->finalizer);
                  // remove this weak ptr from the old_weak_ptr list 
                  *last_w = w->link;
-                 // and put it on the new weak ptr list 
-                 next_w  = w->link;
-                 w->link = weak_ptr_list;
-                 weak_ptr_list = w;
-                 flag = rtsTrue;
+                  next_w  = w->link;
+
+                  // and put it on the new weak ptr list.
+                  // NB. we must retain the order of the weak_ptr_list (#7160)
+                  if (weak_ptr_list == NULL) {
+                      weak_ptr_list = w;
+                  } else {
+                      weak_ptr_list_tail->link = w;
+                  }
+                  weak_ptr_list_tail = w;
+                  w->link = NULL;
+                  flag = rtsTrue;
 
                  debugTrace(DEBUG_weak, 
                             "weak pointer still alive at %p -> %p",



_______________________________________________
Cvs-ghc mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/cvs-ghc

Reply via email to