diff options
author | Simon Marlow <simonmar@microsoft.com> | 2007-03-06 14:31:12 +0000 |
---|---|---|
committer | Simon Marlow <simonmar@microsoft.com> | 2007-03-06 14:31:12 +0000 |
commit | 78c491b13bd3afea76a8bb3f30d13e417c768941 (patch) | |
tree | e14ad4e8ab5774dbef717aa9515728b641aeda17 /rts/PrimOps.cmm | |
parent | a1e3066e066f0f75da361f881b2f3198e0aada5f (diff) | |
download | haskell-78c491b13bd3afea76a8bb3f30d13e417c768941.tar.gz |
add noDuplicate#
This primop ensures that the current computation is not being
duplicated, by calling threadPaused(). The idea is to use it inside
unsafePerformIO/unsafeInterleaveIO (see #986).
Diffstat (limited to 'rts/PrimOps.cmm')
-rw-r--r-- | rts/PrimOps.cmm | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/rts/PrimOps.cmm b/rts/PrimOps.cmm index b58baa0995..437ce55ac5 100644 --- a/rts/PrimOps.cmm +++ b/rts/PrimOps.cmm @@ -2130,3 +2130,23 @@ asyncDoProczh_fast #endif } #endif + +// noDuplicate# tries to ensure that none of the thunks under +// evaluation by the current thread are also under evaluation by +// another thread. It relies on *both* threads doing noDuplicate#; +// the second one will get blocked if they are duplicating some work. +noDuplicatezh_fast +{ + SAVE_THREAD_STATE(); + ASSERT(StgTSO_what_next(CurrentTSO) == ThreadRunGHC::I16); + foreign "C" threadPaused (MyCapability() "ptr", CurrentTSO "ptr") []; + + if (StgTSO_what_next(CurrentTSO) == ThreadKilled::I16) { + R1 = ThreadFinished; + jump StgReturn; + } else { + LOAD_THREAD_STATE(); + ASSERT(StgTSO_what_next(CurrentTSO) == ThreadRunGHC::I16); + jump %ENTRY_CODE(Sp(0)); + } +} |