Rollback: use cas() to claim the closure in copyPart(), to match copy_tag()
authorSimon Marlow <marlowsd@gmail.com>
Thu, 20 Aug 2009 15:58:33 +0000 (15:58 +0000)
committerSimon Marlow <marlowsd@gmail.com>
Thu, 20 Aug 2009 15:58:33 +0000 (15:58 +0000)
rolling back:

  * use cas() to claim the closure in copyPart(), to match copy_tag()
  * rename whitehole_spin to evac_collision, and update it properly

This introduced a new failure in parallel GC.  I'll rollback for now
until I've fixed it.

rts/Stats.c
rts/sm/Evac.c
rts/sm/GC.h
rts/sm/Storage.c

index 4acddda..6029745 100644 (file)
@@ -15,7 +15,7 @@
 #include "Profiling.h"
 #include "GetTime.h"
 #include "sm/Storage.h"
-#include "sm/GC.h" // gc_alloc_block_sync, evac_collision
+#include "sm/GC.h" // gc_alloc_block_sync, whitehole_spin
 
 #if USE_PAPI
 #include "Papi.h"
@@ -704,7 +704,7 @@ stat_exit(int alloc)
                 nat g, s;
                 
                 statsPrintf("gc_alloc_block_sync: %"FMT_Word64"\n", gc_alloc_block_sync.spin);
-                statsPrintf("evac_collision: %"FMT_Word64"\n", evac_collision);
+                statsPrintf("whitehole_spin: %"FMT_Word64"\n", whitehole_spin);
                 for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
                     for (s = 0; s < generations[g].n_steps; s++) {
                         statsPrintf("gen[%d].steps[%d].sync_large_objects: %"FMT_Word64"\n", g, s, generations[g].steps[s].sync_large_objects.spin);
index c40d18b..ae843bd 100644 (file)
@@ -25,7 +25,7 @@
 #include "LdvProfile.h"
 
 #if defined(PROF_SPIN) && defined(THREADED_RTS) && defined(PARALLEL_GC)
-StgWord64 evac_collision = 0;
+StgWord64 whitehole_spin = 0;
 #endif
 
 #if defined(THREADED_RTS) && !defined(PARALLEL_GC)
@@ -112,13 +112,9 @@ copy_tag(StgClosure **p, const StgInfoTable *info,
 #if defined(PARALLEL_GC)
     {
         const StgInfoTable *new_info;
-        new_info = (const StgInfoTable *)cas((StgPtr)&src->header.info,
-                                             (W_)info, MK_FORWARDING_PTR(to));
+        new_info = (const StgInfoTable *)cas((StgPtr)&src->header.info, (W_)info, MK_FORWARDING_PTR(to));
         if (new_info != info) {
-#if defined(PROF_SPIN)
-            evac_collision++;
-#endif
-            evacuate(p); // does the failed_to_evac stuff
+            return evacuate(p); // does the failed_to_evac stuff
         } else {
             *p = TAG_CLOSURE(tag,(StgClosure*)to);
         }
@@ -172,42 +168,46 @@ copy_tag_nolock(StgClosure **p, const StgInfoTable *info,
  * used to optimise evacuation of BLACKHOLEs.
  */
 static rtsBool
-copyPart(StgClosure **p, const StgInfoTable *info, StgClosure *src, 
-         nat size_to_reserve, nat size_to_copy, step *stp)
+copyPart(StgClosure **p, StgClosure *src, nat size_to_reserve, nat size_to_copy, step *stp)
 {
     StgPtr to, from;
     nat i;
+    StgWord info;
     
+#if defined(PARALLEL_GC)
+spin:
+       info = xchg((StgPtr)&src->header.info, (W_)&stg_WHITEHOLE_info);
+       if (info == (W_)&stg_WHITEHOLE_info) {
+#ifdef PROF_SPIN
+           whitehole_spin++;
+#endif
+           goto spin;
+       }
+    if (IS_FORWARDING_PTR(info)) {
+       src->header.info = (const StgInfoTable *)info;
+       evacuate(p); // does the failed_to_evac stuff
+       return rtsFalse;
+    }
+#else
+    info = (W_)src->header.info;
+#endif
+
     to = alloc_for_copy(size_to_reserve, stp);
+    *p = (StgClosure *)to;
 
     TICK_GC_WORDS_COPIED(size_to_copy);
 
     from = (StgPtr)src;
-    to[0] = (W_)info;
+    to[0] = info;
     for (i = 1; i < size_to_copy; i++) { // unroll for small i
        to[i] = from[i];
     }
     
 #if defined(PARALLEL_GC)
-    {
-        const StgInfoTable *new_info;
-        new_info = (const StgInfoTable *)cas((StgPtr)&src->header.info, 
-                                             (W_)info, MK_FORWARDING_PTR(to));
-        if (new_info != info) {
-#if defined(PROF_SPIN)
-            evac_collision++;
-#endif
-            evacuate(p); // does the failed_to_evac stuff
-            return rtsFalse;
-        } else {
-            *p = (StgClosure*)to;
-        }
-    }
-#else
-    src->header.info = (const StgInfoTable *)MK_FORWARDING_PTR(to);
-    *p = (StgClosure*)to;
+    write_barrier();
 #endif
-
+    src->header.info = (const StgInfoTable*)MK_FORWARDING_PTR(to);
+    
 #ifdef PROFILING
     // We store the size of the just evacuated object in the LDV word so that
     // the profiler can guess the position of the next object later.
@@ -639,7 +639,7 @@ loop:
 
   case CAF_BLACKHOLE:
   case BLACKHOLE:
-      copyPart(p,info,q,BLACKHOLE_sizeW(),sizeofW(StgHeader),stp);
+      copyPart(p,q,BLACKHOLE_sizeW(),sizeofW(StgHeader),stp);
       return;
 
   case THUNK_SELECTOR:
@@ -711,7 +711,7 @@ loop:
          StgPtr r, s;
           rtsBool mine;
 
-         mine = copyPart(p,info,(StgClosure *)tso, tso_sizeW(tso), 
+         mine = copyPart(p,(StgClosure *)tso, tso_sizeW(tso), 
                           sizeofW(StgTSO), stp);
           if (mine) {
               new_tso = (StgTSO *)*p;
index 675d323..e746f09 100644 (file)
@@ -42,7 +42,7 @@ extern nat mutlist_MUTVARS, mutlist_MUTARRS, mutlist_MVARS, mutlist_OTHERS;
 #endif
 
 #if defined(PROF_SPIN) && defined(THREADED_RTS)
-extern StgWord64 evac_collision;
+extern StgWord64 whitehole_spin;
 #endif
 
 void gcWorkerThread (Capability *cap);
index 19ccdfb..59a41b0 100644 (file)
@@ -253,7 +253,7 @@ initStorage( void )
 
 #ifdef THREADED_RTS
   initSpinLock(&gc_alloc_block_sync);
-  evac_collision = 0;
+  whitehole_spin = 0;
 #endif
 
   N = 0;