Commit 78c491b1 authored by Simon Marlow's avatar Simon Marlow
Browse files

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).
parent a1e3066e
......@@ -1532,6 +1532,11 @@ primop IsCurrentThreadBoundOp "isCurrentThreadBound#" GenPrimOp
with
out_of_line = True
primop NoDuplicateOp "noDuplicate#" GenPrimOp
State# RealWorld -> State# RealWorld
with
out_of_line = True
------------------------------------------------------------------------
section "Weak pointers"
------------------------------------------------------------------------
......
......@@ -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));
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment