summaryrefslogtreecommitdiff
path: root/rts/HeapStackCheck.cmm
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2010-04-20 12:21:25 +0000
committerSimon Marlow <marlowsd@gmail.com>2010-04-20 12:21:25 +0000
commit870b59f53cb97904096bfd6ea0e58ffc055a14ea (patch)
tree08d13d098df4f1b7e49579aa4acbc9d83802f04c /rts/HeapStackCheck.cmm
parent5a252eb7bbbe655f63f65e012b8176fd1dd6953f (diff)
downloadhaskell-870b59f53cb97904096bfd6ea0e58ffc055a14ea.tar.gz
Fix crash in non-threaded RTS on Windows
The tso->block_info field is now overwritten by pushOnRunQueue(), but stg_block_async_info was assuming that it still held a pointer to the StgAsyncIOResult. We must therefore save this value somewhere safe before putting the TSO on the run queue.
Diffstat (limited to 'rts/HeapStackCheck.cmm')
-rw-r--r--rts/HeapStackCheck.cmm17
1 files changed, 8 insertions, 9 deletions
diff --git a/rts/HeapStackCheck.cmm b/rts/HeapStackCheck.cmm
index f8195768fb..d17961145a 100644
--- a/rts/HeapStackCheck.cmm
+++ b/rts/HeapStackCheck.cmm
@@ -662,24 +662,24 @@ stg_block_throwto
}
#ifdef mingw32_HOST_OS
-INFO_TABLE_RET( stg_block_async, RET_SMALL )
+INFO_TABLE_RET( stg_block_async, RET_SMALL, W_ unused )
{
W_ ares;
W_ len, errC;
- ares = StgTSO_block_info(CurrentTSO);
+ ares = Sp(1);
len = StgAsyncIOResult_len(ares);
errC = StgAsyncIOResult_errCode(ares);
- StgTSO_block_info(CurrentTSO) = NULL;
foreign "C" free(ares "ptr");
R1 = len;
+ Sp_adj(1);
Sp(0) = errC;
jump %ENTRY_CODE(Sp(1));
}
stg_block_async
{
- Sp_adj(-1);
+ Sp_adj(-2);
Sp(0) = stg_block_async_info;
BLOCK_GENERIC;
}
@@ -687,20 +687,19 @@ stg_block_async
/* Used by threadDelay implementation; it would be desirable to get rid of
* this free()'ing void return continuation.
*/
-INFO_TABLE_RET( stg_block_async_void, RET_SMALL )
+INFO_TABLE_RET( stg_block_async_void, RET_SMALL, W_ ares )
{
W_ ares;
- ares = StgTSO_block_info(CurrentTSO);
- StgTSO_block_info(CurrentTSO) = NULL;
+ ares = Sp(1);
foreign "C" free(ares "ptr");
- Sp_adj(1);
+ Sp_adj(2);
jump %ENTRY_CODE(Sp(0));
}
stg_block_async_void
{
- Sp_adj(-1);
+ Sp_adj(-2);
Sp(0) = stg_block_async_void_info;
BLOCK_GENERIC;
}