summaryrefslogtreecommitdiff
path: root/rts
diff options
context:
space:
mode:
Diffstat (limited to 'rts')
-rw-r--r--rts/Schedule.c4
-rw-r--r--rts/StgMiscClosures.cmm10
-rw-r--r--rts/StgStartup.cmm16
-rw-r--r--rts/include/rts/storage/Closures.h7
-rw-r--r--rts/include/stg/MiscClosures.h1
5 files changed, 29 insertions, 9 deletions
diff --git a/rts/Schedule.c b/rts/Schedule.c
index fa48bef1a7..9b1e98ea17 100644
--- a/rts/Schedule.c
+++ b/rts/Schedule.c
@@ -1315,7 +1315,9 @@ scheduleHandleThreadFinished (Capability *cap, Task *task, StgTSO *t)
if (t->what_next == ThreadComplete) {
if (task->incall->ret) {
// NOTE: return val is stack->sp[1] (see StgStartup.cmm)
- *(task->incall->ret) = (StgClosure *)task->incall->tso->stackobj->sp[1];
+ StgDeadThreadFrame *dead = (StgDeadThreadFrame *) &task->incall->tso->stackobj->sp[0];
+ ASSERT(dead->header.info == &stg_dead_thread_info);
+ *(task->incall->ret) = (StgClosure *) dead->result;
}
task->incall->rstat = Success;
} else {
diff --git a/rts/StgMiscClosures.cmm b/rts/StgMiscClosures.cmm
index e9186e3500..c2e4071ddf 100644
--- a/rts/StgMiscClosures.cmm
+++ b/rts/StgMiscClosures.cmm
@@ -409,6 +409,16 @@ INFO_TABLE_RET( stg_apply_interp, RET_BCO )
jump stg_yield_to_interpreter [];
}
+/*
+ * Dummy info table pushed on the top of the stack when the stack's
+ * owning thread has finished.
+ */
+INFO_TABLE_RET( stg_dead_thread, RET_SMALL,
+ W_ info_ptr,
+ PROF_HDR_FIELDS(W_,p1,p2)
+ P_ result )
+{ foreign "C" barf("stg_dead_thread entered!") never returns; }
+
/* ----------------------------------------------------------------------------
Entry code for a BCO
------------------------------------------------------------------------- */
diff --git a/rts/StgStartup.cmm b/rts/StgStartup.cmm
index 122eace1f3..6d3d47f54f 100644
--- a/rts/StgStartup.cmm
+++ b/rts/StgStartup.cmm
@@ -51,13 +51,13 @@ INFO_TABLE_RET(stg_stop_thread, STOP_FRAME,
We Leave the stack looking like this:
- +----------------+
- | -------------------> return value
- +----------------+
- | stg_enter_info |
- +----------------+
+ +----------------------+
+ | -----------------------> return value
+ +----------------------+
+ | stg_dead_thread_info |
+ +----------------------+
- The stg_enter_info is just a dummy info table so that the
+ The stg_dead_thread_info is just a dummy info table so that the
garbage collector can understand the stack (there must always
be an info table on top of the stack).
*/
@@ -70,9 +70,9 @@ INFO_TABLE_RET(stg_stop_thread, STOP_FRAME,
unwind UnwindReturnReg = return;
#endif
- Sp = Sp + SIZEOF_StgStopFrame - WDS(2);
+ Sp = Sp + SIZEOF_StgStopFrame - SIZEOF_StgDeadThreadFrame;
+ Sp(0) = stg_dead_thread_info;
Sp(1) = R1;
- Sp(0) = stg_enter_info;
StgTSO_what_next(CurrentTSO) = ThreadComplete::I16;
diff --git a/rts/include/rts/storage/Closures.h b/rts/include/rts/storage/Closures.h
index 41861abac9..8634c1a5fc 100644
--- a/rts/include/rts/storage/Closures.h
+++ b/rts/include/rts/storage/Closures.h
@@ -282,6 +282,13 @@ typedef struct {
StgHeader header;
} StgStopFrame;
+// Stack frame indicating that the stack's owning thread has finished.
+//
+// Closure types: RET_SMALL
+typedef struct {
+ StgHeader header;
+ StgClosure *result;
+} StgDeadThreadFrame;
// A function return stack frame: used when saving the state for a
// garbage collection at a function entry point. The function
diff --git a/rts/include/stg/MiscClosures.h b/rts/include/stg/MiscClosures.h
index e87eba0931..b5efd9636b 100644
--- a/rts/include/stg/MiscClosures.h
+++ b/rts/include/stg/MiscClosures.h
@@ -159,6 +159,7 @@ RTS_RET(stg_ctoi_t61);
RTS_RET(stg_ctoi_t62);
RTS_RET(stg_apply_interp);
+RTS_RET(stg_dead_thread);
RTS_ENTRY(stg_IND);
RTS_ENTRY(stg_IND_STATIC);