+
+// 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) {
+ jump stg_threadFinished;
+ } else {
+ LOAD_THREAD_STATE();
+ ASSERT(StgTSO_what_next(CurrentTSO) == ThreadRunGHC::I16);
+ jump %ENTRY_CODE(Sp(0));
+ }
+}
+
+getApStackValzh_fast
+{
+ W_ ap_stack, offset, val, ok;
+
+ /* args: R1 = AP_STACK, R2 = offset */
+ ap_stack = R1;
+ offset = R2;
+
+ if (%INFO_PTR(ap_stack) == stg_AP_STACK_info) {
+ ok = 1;
+ val = StgAP_STACK_payload(ap_stack,offset);
+ } else {
+ ok = 0;
+ val = R1;
+ }
+ RET_NP(ok,val);
+}