ASSERT(Sp != 0); \
ASSERT(SpLim != 0); \
ASSERT(HpLim != 0); \
- ASSERT(SpLim - RESERVED_STACK_WORDS <= Sp); \
+ ASSERT(SpLim - WDS(RESERVED_STACK_WORDS) <= Sp); \
ASSERT(HpLim >= Hp);
/* -----------------------------------------------------------------------------
SAVE_THREAD_STATE();
- /* R1 contains the return value of the thread */
- R1 = ThreadFinished;
+ /* The return code goes in BaseReg->rRet, and BaseReg is returned in R1 */
+ StgRegTable_rRet(BaseReg) = ThreadFinished;
+ R1 = BaseReg;
jump StgReturn;
}
Start a thread from the scheduler by returning to the address on
the top of the stack. This is used for all entries to STG code
from C land.
+
+ On the way back, we (usually) pass through stg_returnToSched which saves
+ the thread's state away nicely.
-------------------------------------------------------------------------- */
stg_returnToStackTop
jump %ENTRY_CODE(Sp(0));
}
+stg_returnToSched
+{
+ SAVE_THREAD_STATE();
+ foreign "C" threadPaused(MyCapability() "ptr", CurrentTSO);
+ jump StgReturn;
+}
+
+// A variant of stg_returntToSched that doesn't call threadPaused() on the
+// current thread. This is used for switching from compiled execution to the
+// interpreter, where calling threadPaused() on every switch would be too
+// expensive.
+stg_returnToSchedNotPaused
+{
+ SAVE_THREAD_STATE();
+ jump StgReturn;
+}
+
+// A variant of stg_returnToSched, but instead of returning directly to the
+// scheduler, we jump to the code fragment pointed to by R2. This lets us
+// perform some final actions after making the thread safe, such as unlocking
+// the MVar on which we are about to block in SMP mode.
+stg_returnToSchedButFirst
+{
+ SAVE_THREAD_STATE();
+ foreign "C" threadPaused(MyCapability() "ptr", CurrentTSO);
+ jump R2;
+}
+
/* -----------------------------------------------------------------------------
Strict IO application - performing an IO action and entering its result.
stg_init
{
W_ next;
- Sp = W_[MainCapability + OFFSET_Capability_r + OFFSET_StgRegTable_rSp];
+ Sp = W_[BaseReg + OFFSET_StgRegTable_rSp];
next = W_[Sp];
Sp_adj(1);
jump next;