diff options
Diffstat (limited to 'rts')
-rw-r--r-- | rts/Schedule.c | 4 | ||||
-rw-r--r-- | rts/StgMiscClosures.cmm | 10 | ||||
-rw-r--r-- | rts/StgStartup.cmm | 20 | ||||
-rw-r--r-- | rts/include/rts/storage/Closures.h | 7 | ||||
-rw-r--r-- | rts/include/stg/MiscClosures.h | 1 |
5 files changed, 31 insertions, 11 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 b9aee516d0..dbdd2d71fa 100644 --- a/rts/StgMiscClosures.cmm +++ b/rts/StgMiscClosures.cmm @@ -414,6 +414,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..388e27965e 100644 --- a/rts/StgStartup.cmm +++ b/rts/StgStartup.cmm @@ -49,15 +49,15 @@ INFO_TABLE_RET(stg_stop_thread, STOP_FRAME, We save R1 on top of the stack where the scheduler can find it, tidy up the registers and return to the scheduler. - We Leave the stack looking like this: + We leave the stack looking like this: - +----------------+ - | -------------------> return value - +----------------+ - | stg_enter_info | - +----------------+ + +----------------------+ + Sp ---> | stg_dead_thread_info | + +----------------------+ + | -----------------------> return value + +----------------------+ - 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(1) = R1; - Sp(0) = stg_enter_info; + Sp = Sp + SIZEOF_StgStopFrame - SIZEOF_StgDeadThreadFrame; + SET_HDR(Sp, stg_dead_thread_info, CCS_SYSTEM); + StgDeadThreadFrame_result(Sp) = R1; StgTSO_what_next(CurrentTSO) = ThreadComplete::I16; diff --git a/rts/include/rts/storage/Closures.h b/rts/include/rts/storage/Closures.h index bfc8308c29..09c7bfdb88 100644 --- a/rts/include/rts/storage/Closures.h +++ b/rts/include/rts/storage/Closures.h @@ -285,6 +285,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); |