diff options
author | Ryan Yates <ryates@cs.rochester.edu> | 2019-06-21 15:32:05 -0400 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2019-10-23 05:59:03 -0400 |
commit | 1f40e68aa1c02f3db685efe140dd941e6ba1edb0 (patch) | |
tree | 7d58432710c1ab53de22e740213984c442a322eb /rts/PrimOps.cmm | |
parent | aa7781521bf2796a6f0b3e3cfc08e9e80ae6dc47 (diff) | |
download | haskell-1f40e68aa1c02f3db685efe140dd941e6ba1edb0.tar.gz |
Full abort on validate failure merging `orElse`.
Previously partial roll back of a branch of an `orElse` was attempted
if validation failure was observed. Validation here, however, does
not account for what part of the transaction observed inconsistent
state. This commit fixes this by fully aborting and restarting the
transaction.
Diffstat (limited to 'rts/PrimOps.cmm')
-rw-r--r-- | rts/PrimOps.cmm | 54 |
1 files changed, 34 insertions, 20 deletions
diff --git a/rts/PrimOps.cmm b/rts/PrimOps.cmm index d06cde05d9..ec35ee42b4 100644 --- a/rts/PrimOps.cmm +++ b/rts/PrimOps.cmm @@ -1032,6 +1032,37 @@ stg_threadStatuszh ( gcptr tso ) * TVar primitives * -------------------------------------------------------------------------- */ +stg_abort /* no arg list: explicit stack layout */ +{ + W_ frame_type; + W_ frame; + W_ trec; + W_ outer; + W_ r; + + // STM operations may allocate + MAYBE_GC_ (stg_abort); // NB. not MAYBE_GC(), we cannot make a + // function call in an explicit-stack proc + + // Find the enclosing ATOMICALLY_FRAME + SAVE_THREAD_STATE(); + (frame_type) = ccall findAtomicallyFrameHelper(MyCapability(), CurrentTSO "ptr"); + LOAD_THREAD_STATE(); + frame = Sp; + trec = StgTSO_trec(CurrentTSO); + outer = StgTRecHeader_enclosing_trec(trec); + + // We've reached the ATOMICALLY_FRAME + ASSERT(frame_type == ATOMICALLY_FRAME); + ASSERT(outer == NO_TREC); + + // Restart the transaction. + ("ptr" trec) = ccall stmStartTransaction(MyCapability() "ptr", outer "ptr"); + StgTSO_trec(CurrentTSO) = trec; + Sp = frame; + R1 = StgAtomicallyFrame_code(frame); + jump stg_ap_v_fast [R1]; +} // Catch retry frame ----------------------------------------------------------- #define CATCH_RETRY_FRAME_FIELDS(w_,p_,info_ptr, \ @@ -1066,26 +1097,9 @@ INFO_TABLE_RET(stg_catch_retry_frame, CATCH_RETRY_FRAME, StgTSO_trec(CurrentTSO) = outer; return (ret); } else { - // Did not commit: re-execute - P_ new_trec; - ("ptr" new_trec) = ccall stmStartTransaction(MyCapability() "ptr", - outer "ptr"); - StgTSO_trec(CurrentTSO) = new_trec; - if (running_alt_code != 0) { - jump stg_ap_v_fast - (CATCH_RETRY_FRAME_FIELDS(,,info_ptr, p1, p2, - running_alt_code, - first_code, - alt_code)) - (alt_code); - } else { - jump stg_ap_v_fast - (CATCH_RETRY_FRAME_FIELDS(,,info_ptr, p1, p2, - running_alt_code, - first_code, - alt_code)) - (first_code); - } + // Did not commit: abort and restart. + StgTSO_trec(CurrentTSO) = outer; + jump stg_abort(); } } |