Lock the StablePtr table during GC
authorSimon Marlow <marlowsd@gmail.com>
Thu, 4 Jun 2009 09:05:53 +0000 (09:05 +0000)
committerSimon Marlow <marlowsd@gmail.com>
Thu, 4 Jun 2009 09:05:53 +0000 (09:05 +0000)
Allows hs_free_fun_ptr() to be called by a separate thread

includes/Stable.h
rts/Stable.c
rts/sm/GC.c

index 5404bab..9752a53 100644 (file)
@@ -57,4 +57,7 @@ extern void    threadStablePtrTable  ( evac_fn evac, void *user );
 extern void    gcStablePtrTable      ( void );
 extern void    updateStablePtrTable  ( rtsBool full );
 
+extern void    stablePtrPreGC        ( void );
+extern void    stablePtrPostGC       ( void );
+
 #endif
index 94a756a..97796b8 100644 (file)
@@ -316,6 +316,23 @@ enlargeStablePtrTable(void)
 }
 
 /* -----------------------------------------------------------------------------
+ * We must lock the StablePtr table during GC, to prevent simultaneous
+ * calls to freeStablePtr().
+ * -------------------------------------------------------------------------- */
+
+void
+stablePtrPreGC(void)
+{
+    ACQUIRE_LOCK(&stable_mutex);
+}
+
+void
+stablePtrPostGC(void)
+{
+    RELEASE_LOCK(&stable_mutex);
+}
+
+/* -----------------------------------------------------------------------------
  * Treat stable pointers as roots for the garbage collector.
  *
  * A stable pointer is any stable name entry with a ref > 0.  We'll
index e0c8b05..cfe4c6b 100644 (file)
@@ -215,6 +215,9 @@ GarbageCollect (rtsBool force_major_gc,
   // tell the STM to discard any cached closures it's hoping to re-use
   stmPreGCHook();
 
+  // lock the StablePtr table
+  stablePtrPreGC();
+
 #ifdef DEBUG
   mutlist_MUTVARS = 0;
   mutlist_MUTARRS = 0;
@@ -794,6 +797,9 @@ SET_GCT(gc_threads[0]);
   slop = calcLiveBlocks() * BLOCK_SIZE_W - live;
   stat_endGC(allocated, live, copied, N, max_copied, avg_copied, slop);
 
+  // unlock the StablePtr table
+  stablePtrPostGC();
+
   // Guess which generation we'll collect *next* time
   initialise_N(force_major_gc);