summaryrefslogtreecommitdiff
path: root/rts/PrimOps.cmm
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2009-06-24 14:15:30 +0000
committerSimon Marlow <marlowsd@gmail.com>2009-06-24 14:15:30 +0000
commitdce2394f7d2a695c1020643eda12465a280468f5 (patch)
treed65e883ef03b8e2b19b7a7f82591bad61bcab17d /rts/PrimOps.cmm
parentbabf070d4c20a1a3438918fcd6b1cc5d20f0dbe1 (diff)
downloadhaskell-dce2394f7d2a695c1020643eda12465a280468f5.tar.gz
propagate the result of atomically properly (fixes #3049)
Diffstat (limited to 'rts/PrimOps.cmm')
-rw-r--r--rts/PrimOps.cmm12
1 files changed, 8 insertions, 4 deletions
diff --git a/rts/PrimOps.cmm b/rts/PrimOps.cmm
index 84567fee8f..9efc9f1ed8 100644
--- a/rts/PrimOps.cmm
+++ b/rts/PrimOps.cmm
@@ -678,18 +678,20 @@ INFO_TABLE_RET(stg_atomically_frame, ATOMICALLY_FRAME,
#if defined(PROFILING)
W_ unused1, W_ unused2,
#endif
- P_ unused3, P_ unused4)
+ P_ code, P_ next_invariant_to_check, P_ result)
{
W_ frame, trec, valid, next_invariant, q, outer;
- frame = Sp;
- trec = StgTSO_trec(CurrentTSO);
+ frame = Sp;
+ trec = StgTSO_trec(CurrentTSO);
+ result = R1;
("ptr" outer) = foreign "C" stmGetEnclosingTRec(trec "ptr") [];
if (outer == NO_TREC) {
/* First time back at the atomically frame -- pick up invariants */
("ptr" q) = foreign "C" stmGetInvariantsToCheck(MyCapability() "ptr", trec "ptr") [];
StgAtomicallyFrame_next_invariant_to_check(frame) = q;
+ StgAtomicallyFrame_result(frame) = result;
} else {
/* Second/subsequent time back at the atomically frame -- abort the
@@ -723,6 +725,7 @@ INFO_TABLE_RET(stg_atomically_frame, ATOMICALLY_FRAME,
if (valid != 0) {
/* Transaction was valid: commit succeeded */
StgTSO_trec(CurrentTSO) = NO_TREC;
+ R1 = StgAtomicallyFrame_result(frame);
Sp = Sp + SIZEOF_StgAtomicallyFrame;
jump %ENTRY_CODE(Sp(SP_OFF));
} else {
@@ -740,7 +743,7 @@ INFO_TABLE_RET(stg_atomically_waiting_frame, ATOMICALLY_FRAME,
#if defined(PROFILING)
W_ unused1, W_ unused2,
#endif
- P_ unused3, P_ unused4)
+ P_ code, P_ next_invariant_to_check, P_ result)
{
W_ frame, trec, valid;
@@ -825,6 +828,7 @@ atomicallyzh_fast
SET_HDR(frame,stg_atomically_frame_info, W_[CCCS]);
StgAtomicallyFrame_code(frame) = R1;
+ StgAtomicallyFrame_result(frame) = NO_TREC;
StgAtomicallyFrame_next_invariant_to_check(frame) = END_INVARIANT_CHECK_QUEUE;
/* Start the memory transcation */