Allows hs_free_fun_ptr() to be called by a separate thread
extern void gcStablePtrTable ( void );
extern void updateStablePtrTable ( rtsBool full );
extern void gcStablePtrTable ( void );
extern void updateStablePtrTable ( rtsBool full );
+extern void stablePtrPreGC ( void );
+extern void stablePtrPostGC ( 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
* Treat stable pointers as roots for the garbage collector.
*
* A stable pointer is any stable name entry with a ref > 0. We'll
// tell the STM to discard any cached closures it's hoping to re-use
stmPreGCHook();
// 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;
#ifdef DEBUG
mutlist_MUTVARS = 0;
mutlist_MUTARRS = 0;
slop = calcLiveBlocks() * BLOCK_SIZE_W - live;
stat_endGC(allocated, live, copied, N, max_copied, avg_copied, slop);
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);
// Guess which generation we'll collect *next* time
initialise_N(force_major_gc);