summaryrefslogtreecommitdiff
path: root/rts/HeapStackCheck.cmm
diff options
context:
space:
mode:
authorEdward Z. Yang <ezyang@mit.edu>2013-07-08 11:03:35 -0700
committerEdward Z. Yang <ezyang@mit.edu>2013-07-09 11:29:11 -0700
commit70e20631742e516c6a11c3c112fbd5b4a08c15ac (patch)
treed0097f8b1c8e5c0a67b26bb950c036ea7684c65d /rts/HeapStackCheck.cmm
parentca9a431401755f119d97dec59a1fc963a8e9f681 (diff)
downloadhaskell-70e20631742e516c6a11c3c112fbd5b4a08c15ac.tar.gz
Implement atomicReadMVar, fixing #4001.
We add the invariant to the MVar blocked threads queue that threads blocked on an atomic read are always at the front of the queue. This invariant is easy to maintain, since takers are only ever added to the end of the queue. Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
Diffstat (limited to 'rts/HeapStackCheck.cmm')
-rw-r--r--rts/HeapStackCheck.cmm31
1 files changed, 29 insertions, 2 deletions
diff --git a/rts/HeapStackCheck.cmm b/rts/HeapStackCheck.cmm
index fbceb7691a..20cd9dffb9 100644
--- a/rts/HeapStackCheck.cmm
+++ b/rts/HeapStackCheck.cmm
@@ -487,11 +487,11 @@ stg_block_noregs
/* -----------------------------------------------------------------------------
* takeMVar/putMVar-specific blocks
*
- * Stack layout for a thread blocked in takeMVar:
+ * Stack layout for a thread blocked in takeMVar/atomicReadMVar:
*
* ret. addr
* ptr to MVar (R1)
- * stg_block_takemvar_info
+ * stg_block_takemvar_info (or stg_block_readmvar_info)
*
* Stack layout for a thread blocked in putMVar:
*
@@ -531,6 +531,33 @@ stg_block_takemvar /* mvar passed in R1 */
BLOCK_BUT_FIRST(stg_block_takemvar_finally);
}
+INFO_TABLE_RET ( stg_block_atomicreadmvar, RET_SMALL, W_ info_ptr, P_ mvar )
+ return ()
+{
+ jump stg_atomicReadMVarzh(mvar);
+}
+
+// code fragment executed just before we return to the scheduler
+stg_block_atomicreadmvar_finally
+{
+ W_ r1, r3;
+ r1 = R1;
+ r3 = R3;
+ unlockClosure(R3, stg_MVAR_DIRTY_info);
+ R1 = r1;
+ R3 = r3;
+ jump StgReturn [R1];
+}
+
+stg_block_atomicreadmvar /* mvar passed in R1 */
+{
+ Sp_adj(-2);
+ Sp(1) = R1;
+ Sp(0) = stg_block_atomicreadmvar_info;
+ R3 = R1; // mvar communicated to stg_block_atomicreadmvar_finally in R3
+ BLOCK_BUT_FIRST(stg_block_atomicreadmvar_finally);
+}
+
INFO_TABLE_RET( stg_block_putmvar, RET_SMALL, W_ info_ptr,
P_ mvar, P_ val )
return ()