summaryrefslogtreecommitdiff
path: root/ghc/includes
diff options
context:
space:
mode:
authorsimonmar <unknown>2005-11-18 15:24:12 +0000
committersimonmar <unknown>2005-11-18 15:24:12 +0000
commitc5cd2343c5a86c8cb5349823a9699b30a269f3e8 (patch)
tree02929661d685c1b6cc53844338f54507fdfa80ce /ghc/includes
parent6c17d627e08e03f2b107bb9ab5d9259c7739c0d6 (diff)
downloadhaskell-c5cd2343c5a86c8cb5349823a9699b30a269f3e8.tar.gz
[project @ 2005-11-18 15:24:12 by simonmar]
Two improvements to the SMP runtime: - support for 'par', aka sparks. Load balancing is very primitive right now, but I have seen programs that go faster using par. - support for backing off when a thread is found to be duplicating a computation currently underway in another thread. This also fixes some instability in SMP, because it turned out that when an update frame points to an indirection, which can happen if a thunk is under evaluation in multiple threads, then after GC has shorted out the indirection the update will trash the value. Now we suspend the duplicate computation to the heap before this can happen. Additionally: - stack squeezing is separate from lazy blackholing, and now only happens if there's a reasonable amount of squeezing to be done in relation to the number of words of stack that have to be moved. This means we won't try to shift 10Mb of stack just to save 2 words at the bottom (it probably never happened, but still). - update frames are now marked when they have been visited by lazy blackholing, as per the SMP paper. - cleaned up raiseAsync() a bit.
Diffstat (limited to 'ghc/includes')
-rw-r--r--ghc/includes/Closures.h5
-rw-r--r--ghc/includes/Regs.h32
-rw-r--r--ghc/includes/RtsFlags.h1
-rw-r--r--ghc/includes/StgMiscClosures.h2
-rw-r--r--ghc/includes/Storage.h2
5 files changed, 33 insertions, 9 deletions
diff --git a/ghc/includes/Closures.h b/ghc/includes/Closures.h
index f9bfeb4dc1..df3bca32f7 100644
--- a/ghc/includes/Closures.h
+++ b/ghc/includes/Closures.h
@@ -339,6 +339,11 @@ typedef struct {
* - In StgTRecHeader, it might be worthwhile having separate chunks
* of read-only and read-write locations. This would save a
* new_value field in the read-only locations.
+ *
+ * - In StgAtomicallyFrame, we could combine the waiting bit into
+ * the header (maybe a different info tbl for a waiting transaction).
+ * This means we can specialise the code for the atomically frame
+ * (it immediately switches on frame->waiting anyway).
*/
typedef struct StgTVarWaitQueue_ {
diff --git a/ghc/includes/Regs.h b/ghc/includes/Regs.h
index f1b8597d60..def36c327d 100644
--- a/ghc/includes/Regs.h
+++ b/ghc/includes/Regs.h
@@ -24,15 +24,17 @@
#include "gmp.h" // Needs MP_INT definition
-/*
- * This is the table that holds shadow-locations for all the STG
- * registers. The shadow locations are used when:
- *
- * 1) the particular register isn't mapped to a real machine
- * register, probably because there's a shortage of real registers.
- * 2) caller-saves registers are saved across a CCall
+/*
+ * Spark pools: used to store pending sparks (SMP & PARALLEL_HASKELL only)
+ * This is a circular buffer. Invariants:
+ * - base <= hd < lim
+ * - base <= tl < lim
+ * - if hd==tl, then the pool is empty.
+ * - if hd == tl+1, then the pool is full.
+ * Adding to the pool is done by assigning to *tl++ (wrapping round as
+ * necessary). When adding to a full pool, we have the option of
+ * throwing away either the oldest (hd++) or the most recent (tl--) entry.
*/
-
typedef struct StgSparkPool_ {
StgClosure **base;
StgClosure **lim;
@@ -40,6 +42,12 @@ typedef struct StgSparkPool_ {
StgClosure **tl;
} StgSparkPool;
+#define ASSERT_SPARK_POOL_INVARIANTS(p) \
+ ASSERT((p)->base <= (p)->hd); \
+ ASSERT((p)->hd < (p)->lim); \
+ ASSERT((p)->base <= (p)->tl); \
+ ASSERT((p)->tl < (p)->lim);
+
typedef struct {
StgFunPtr stgGCEnter1;
StgFunPtr stgGCFun;
@@ -64,6 +72,14 @@ typedef union {
StgTSOPtr t;
} StgUnion;
+/*
+ * This is the table that holds shadow-locations for all the STG
+ * registers. The shadow locations are used when:
+ *
+ * 1) the particular register isn't mapped to a real machine
+ * register, probably because there's a shortage of real registers.
+ * 2) caller-saves registers are saved across a CCall
+ */
typedef struct StgRegTable_ {
StgUnion rR1;
StgUnion rR2;
diff --git a/ghc/includes/RtsFlags.h b/ghc/includes/RtsFlags.h
index a4c6d9ba58..4a37d48fd4 100644
--- a/ghc/includes/RtsFlags.h
+++ b/ghc/includes/RtsFlags.h
@@ -62,6 +62,7 @@ struct DEBUG_FLAGS {
rtsBool linker; /* 'l' the object linker */
rtsBool apply; /* 'a' */
rtsBool stm; /* 'm' */
+ rtsBool squeeze; /* 'z' stack squeezing & lazy blackholing */
};
struct COST_CENTRE_FLAGS {
diff --git a/ghc/includes/StgMiscClosures.h b/ghc/includes/StgMiscClosures.h
index 1d381e656e..a9938aa9f4 100644
--- a/ghc/includes/StgMiscClosures.h
+++ b/ghc/includes/StgMiscClosures.h
@@ -37,6 +37,7 @@
/* Stack frames */
RTS_RET_INFO(stg_upd_frame_info);
+RTS_RET_INFO(stg_marked_upd_frame_info);
RTS_RET_INFO(stg_noupd_frame_info);
RTS_RET_INFO(stg_seq_frame_info);
RTS_RET_INFO(stg_catch_frame_info);
@@ -45,6 +46,7 @@ RTS_RET_INFO(stg_atomically_frame_info);
RTS_RET_INFO(stg_catch_stm_frame_info);
RTS_ENTRY(stg_upd_frame_ret);
+RTS_ENTRY(stg_marked_upd_frame_ret);
RTS_ENTRY(stg_seq_frame_ret);
/* Entry code for constructors created by the bytecode interpreter */
diff --git a/ghc/includes/Storage.h b/ghc/includes/Storage.h
index 1f6ef3f5e7..e37c50d054 100644
--- a/ghc/includes/Storage.h
+++ b/ghc/includes/Storage.h
@@ -392,7 +392,7 @@ extern lnat countNurseryBlocks ( void );
Functions from GC.c
-------------------------------------------------------------------------- */
-extern void threadPaused ( StgTSO * );
+extern void threadPaused ( Capability *cap, StgTSO * );
extern StgClosure * isAlive ( StgClosure *p );
extern void markCAFs ( evac_fn evac );