summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2009-06-04 09:05:53 +0000
committerSimon Marlow <marlowsd@gmail.com>2009-06-04 09:05:53 +0000
commitd9275dd06ee24575ff50a6696fe7fe1e1fa91ac7 (patch)
tree28b1a6efcbb9dfe6a18b5f6d8b1fa95f905d38a1
parent1d6d8bc152fdcabea6d26525f269d8ade8b75dd6 (diff)
downloadhaskell-d9275dd06ee24575ff50a6696fe7fe1e1fa91ac7.tar.gz
Lock the StablePtr table during GC
Allows hs_free_fun_ptr() to be called by a separate thread
-rw-r--r--includes/Stable.h3
-rw-r--r--rts/Stable.c17
-rw-r--r--rts/sm/GC.c6
3 files changed, 26 insertions, 0 deletions
diff --git a/includes/Stable.h b/includes/Stable.h
index 5404bab46e..9752a534bb 100644
--- a/includes/Stable.h
+++ b/includes/Stable.h
@@ -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
diff --git a/rts/Stable.c b/rts/Stable.c
index 94a756a380..97796b89a7 100644
--- a/rts/Stable.c
+++ b/rts/Stable.c
@@ -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
diff --git a/rts/sm/GC.c b/rts/sm/GC.c
index e0c8b05436..cfe4c6bdb5 100644
--- a/rts/sm/GC.c
+++ b/rts/sm/GC.c
@@ -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);