[project @ 1998-11-26 09:17:22 by sof]
[ghc-hetmet.git] / ghc / runtime / main / StgThreads.lhc
index b3f9f28..ffd0286 100644 (file)
@@ -97,7 +97,8 @@ STGFUN(BQ_entry)
     FB_
 
 #if defined(GRAN)
-    STGCALL0(void,(),GranSimBlock);    /* Before overwriting TSO_LINK */
+    /* Before overwriting TSO_LINK */
+    STGCALL3(void,(),GranSimBlock,CurrentTSO,CurrentProc,Node);        
 #endif
 
     TSO_LINK(CurrentTSO) = (P_) BQ_ENTRIES(Node);
@@ -111,7 +112,7 @@ STGFUN(BQ_entry)
        QP_Event1("GR", CurrentTSO);
     }
 #ifdef PAR
-    if(do_gr_profile) {
+    if(RTSflags.ParFlags.granSimStats) {
         /* Note that CURRENT_TIME may perform an unsafe call */
        TIME now = CURRENT_TIME;
         TSO_EXECTIME(CurrentTSO) += now - TSO_BLOCKEDAT(CurrentTSO);
@@ -122,7 +123,7 @@ STGFUN(BQ_entry)
     }
 #endif
 #if defined(GRAN)
-    ReSchedule(NEW_THREAD);
+    ReSchedule(SAME_THREAD); /* NB: GranSimBlock activated next thread */
 #else
     ReSchedule(0);
 #endif
@@ -149,17 +150,22 @@ checked, yet. -- HWL
 
 \begin{code}
 
-#ifdef PAR
+#if defined(PAR) || defined(GRAN)
 
 STGFUN(RBH_entry)
 {
     FB_
 
-#if defined(GRAN)
-    STGCALL0(void, (), GranSimBlock);  /* Before overwriting TSO_LINK */
-#endif
+#  if defined(GRAN)
+    /* Before overwriting TSO_LINK */
+    STGCALL3(void,(),GranSimBlock,CurrentTSO,CurrentProc,Node);        
+#  endif
+
+    /* In GranSim and GUM on 2.04 the InfoPtr seems to be invalid when entering
+       this routine (exact reason is unknown). This change does the safe 
+       thing instead. -- HWL */
 
-    switch (INFO_TYPE(InfoPtr)) {
+    switch (INFO_TYPE(INFO_PTR(Node))) {  /* HWL orig: INFO_TYPE(InfoPtr) */
     case INFO_SPEC_RBH_TYPE:
        TSO_LINK(CurrentTSO) = (P_) SPEC_RBH_BQ(Node);
        SPEC_RBH_BQ(Node) = (W_) CurrentTSO;
@@ -182,7 +188,8 @@ STGFUN(RBH_entry)
        QP_Event1("GR", CurrentTSO);
     }
 
-    if(do_gr_profile) {
+#  ifdef PAR
+    if(RTSflags.ParFlags.granSimStats) {
         /* Note that CURRENT_TIME may perform an unsafe call */
        TIME now = CURRENT_TIME;
         TSO_EXECTIME(CurrentTSO) += now - TSO_BLOCKEDAT(CurrentTSO);
@@ -191,12 +198,12 @@ STGFUN(RBH_entry)
         TSO_BLOCKEDAT(CurrentTSO) = now;
         DumpGranEvent(GR_BLOCK, CurrentTSO);
     }
-
-#if defined(GRAN)
-    ReSchedule(NEW_THREAD);
-#else
+#  endif
+#  if defined(GRAN)
+    ReSchedule(SAME_THREAD);  /* NB: GranSimBlock activated next thread */
+#  else
     ReSchedule(0);
-#endif
+#  endif
 
     FE_
 }
@@ -211,22 +218,21 @@ STGFUN(RBH_entry)
 %*                                                                     *
 %************************************************************************
 
-The normal way of entering a thread is through resumeThread, which 
-short-circuits and indirections to the TSO and StkO, sets up STG registers,
-and jumps to the saved PC.
+The normal way of entering a thread is through \tr{resumeThread},
+which short-circuits any indirections to the TSO and StkO, sets up STG
+registers, and jumps to the saved PC.
 
 \begin{code}
-
 STGFUN(resumeThread)
 {
     FB_
 
-    while((P_) INFO_PTR(CurrentTSO) == Ind_info) {
+    while(IS_INDIRECTION(INFO_PTR(CurrentTSO))) {
        CurrentTSO = (P_) IND_CLOSURE_PTR(CurrentTSO);
     }
 
 #ifdef PAR
-    if (do_gr_profile) {
+    if (RTSflags.ParFlags.granSimStats) {
        TSO_QUEUE(CurrentTSO) = Q_RUNNING;
        /* Note that CURRENT_TIME may perform an unsafe call */
         TSO_BLOCKEDAT(CurrentTSO) = CURRENT_TIME;
@@ -235,18 +241,16 @@ STGFUN(resumeThread)
 
     CurrentRegTable = TSO_INTERNAL_PTR(CurrentTSO);
 
-    while((P_) INFO_PTR(SAVE_StkO) == Ind_info) {
+    while(IS_INDIRECTION(INFO_PTR(SAVE_StkO))) {
        SAVE_StkO = (P_) IND_CLOSURE_PTR(SAVE_StkO);
     }
     RestoreAllStgRegs();
 
     SET_TASK_ACTIVITY(ST_REDUCING);
-    SET_ACTIVITY(ACT_REDN); /* back to normal reduction */
     RESTORE_CCC(TSO_CCC(CurrentTSO));
     JMP_(TSO_PC1(CurrentTSO));
     FE_
 }
-
 \end{code}
 
 Since we normally context switch during a heap check, it is possible
@@ -255,26 +259,22 @@ sufficient heap for the thread to continue.  However, we have cleverly
 stashed away the heap requirements in @TSO_ARG1@ so that we can decide
 whether or not to perform a garbage collection before resuming the
 thread.  The actual thread resumption address (either @EnterNodeCode@
-or elsewhere) is stashed in TSO_PC2.
+or elsewhere) is stashed in @TSO_PC2@.
 
 \begin{code}
-
 STGFUN(CheckHeapCode)
 {
     FB_
 
     ALLOC_HEAP(TSO_ARG1(CurrentTSO)); /* ticky profiling */
-    SET_ACTIVITY(ACT_HEAP_CHK); /* SPAT counting */
     if ((Hp += TSO_ARG1(CurrentTSO)) > HpLim) {
        ReallyPerformThreadGC(TSO_ARG1(CurrentTSO), rtsFalse);
        JMP_(resumeThread);
     }
     SET_TASK_ACTIVITY(ST_REDUCING);
-    SET_ACTIVITY(ACT_REDN); /* back to normal reduction */
     RESUME_(TSO_PC2(CurrentTSO));
     FE_
 }
-
 \end{code}
 
 Often, a thread starts (or rather, resumes) by entering the closure
@@ -283,38 +283,34 @@ The saved PC in the TSO can be set to @EnterNodeCode@ whenever we
 want this to happen upon resumption of the thread.
 
 \begin{code}
-
 STGFUN(EnterNodeCode)
 {
     FB_
     ENT_VIA_NODE();
     InfoPtr=(D_)(INFO_PTR(Node));
-    GRAN_EXEC(5,1,2,0,0);
     JMP_(ENTRY_CODE(InfoPtr));
     FE_
 }
-
 \end{code}
 
-Then, there are the occasions when we just want to pick up where we left off.
-We use RESUME_ here instead of JMP_, because when we return to a call site,
-the alpha is going to try to load %gp from %ra rather than %pv, and JMP_ only
-sets %pv.  Resuming to the start of a function is currently okay, but an
-extremely bad practice.  As we add support for more architectures, we can expect 
-the difference between RESUME_ and JMP_ to become more acute.
+Then, there are the occasions when we just want to pick up where we
+left off.  We use \tr{RESUME_} here instead of \tr{JMP_}, because when
+we return to a call site, the Alpha is going to try to load \tr{%gp}
+from \tr{%ra} rather than \tr{%pv}, and \tr{JMP_} only sets \tr{%pv}.
+Resuming to the start of a function is currently okay, but an
+extremely bad practice.  As we add support for more architectures, we
+can expect the difference between \tr{RESUME_} and \tr{JMP_} to become
+more acute.
 
 \begin{code}
-
 STGFUN(Continue)
 {
     FB_
 
     SET_TASK_ACTIVITY(ST_REDUCING);
-    SET_ACTIVITY(ACT_REDN); /* back to normal reduction */
     RESUME_(TSO_PC2(CurrentTSO));
     FE_
 }
-
 \end{code}
 
 %************************************************************************
@@ -324,11 +320,7 @@ STGFUN(Continue)
 %************************************************************************
 
 \begin{code}
-
-extern P_ AvailableStack;
-
 #ifndef PAR
-
 \end{code}
 
 On a uniprocessor, stack underflow causes us no great headaches.  The
@@ -368,7 +360,7 @@ DO_RETURN_TEMPLATE(UnderflowVect7, ((P_)RetReg)[RVREL(7)])
 
 DO_RETURN_TEMPLATE(StackUnderflowEnterNode, EnterNodeCode)
 
-#else
+#else /* PAR */
 
 \end{code}
 
@@ -388,6 +380,20 @@ STGFUN(CommonUnderflow)
 
     FB_
     temp = STKO_LINK(StkOReg);
+
+    /* fprintf(stderr,"Stk Underflow from: %lx to: %lx size abandoned: %d\n",StkOReg,temp,STKO_CLOSURE_CTS_SIZE(StkOReg)); */
+
+    /* change the guy we are abandoning into something
+       that will not be "interesting" on the mutables
+       list.  (As long as it is there, it will be
+       scavenged in GC, and we cannot guarantee that
+       it is still a "sane" StkO object).  (And, besides,
+       why continue to keep it [and all it pts to] alive?)
+       Will & Phil 95/10
+    */
+    FREEZE_MUT_HDR(StkOReg, ImMutArrayOfPtrs_info);
+    MUTUPLE_CLOSURE_SIZE(StkOReg) = MUTUPLE_VHS;
+
     StkOReg = temp;
     /* ToDo: Fetch the remote stack object here! */
     RestoreStackStgRegs();
@@ -434,6 +440,9 @@ STGFUN(PrimUnderflow)
  * because R2 is dead, and R1 points to a PAP.  Only R1 is live.
  */
 
+#if 0
+
+/* old version of the code */
 STGFUN(StackUnderflowEnterNode)
 {
     FB_
@@ -443,8 +452,50 @@ STGFUN(StackUnderflowEnterNode)
     FE_
 }
 
+#else
+
+/*
+   We've inlined CommonUnderFlow because setting RetReg would zap
+   the return vector that the node needs.
+   We pick up the RetReg from the STkO header instead.
+   KH/HWL 14/2/97
+*/
+
+STGFUN(StackUnderflowEnterNode)
+{
+    P_ temp;
+    FB_
+    RetReg = STKO_RETURN(StkOReg); /* pick up return code from the StkO hdr
+                                      needed because we come from UpdatePAP */
+    LivenessReg = LIVENESS_R1;
+
+    temp = STKO_LINK(StkOReg);
+
+    /*? fprintf(stderr,"Stk Underflow from: %lx to: %lx size abandoned: %d\n",StkOReg,temp,STKO_CLOSURE_CTS_SIZE(StkOReg)); ?*/
+
+    /* change the guy we are abandoning into something
+       that will not be "interesting" on the mutables
+       list.  (As long as it is there, it will be
+       scavenged in GC, and we cannot guarantee that
+       it is still a "sane" StkO object).  (And, besides,
+       why continue to keep it [and all it pts to] alive?)
+       Will & Phil 95/10
+    */
+    FREEZE_MUT_HDR(StkOReg, ImMutArrayOfPtrs_info);
+    MUTUPLE_CLOSURE_SIZE(StkOReg) = MUTUPLE_VHS;
+
+    StkOReg = temp;
+    /* ToDo: Fetch the remote stack object here! */
+    RestoreStackStgRegs();
+    JMP_(EnterNodeCode);  /* this will enter a PAP containing the old stkos
+                            A and B stacks */
+    FE_
+}
 #endif
 
+
+#endif /* !PAR */
+
 const W_
 vtbl_Underflow[] = {
     /* "MAX_VECTORED_RTN" elements (see GhcConstants.lh) */
@@ -458,39 +509,5 @@ vtbl_Underflow[] = {
     (W_) UnderflowVect7
 };
 
-\end{code}
-
-\begin{code}
-
-IFN_(seqDirectReturn) {
-    void *cont;
-
-    FB_
-    RetReg = (StgRetAddr) SpB[BREL(0)];
-    cont = (void *) SpB[BREL(1)];
-    SpB += BREL(2);
-/*  GRAN_EXEC(1,1,2,0,0); /? ToDo: RE-CHECK (WDP) */
-    JMP_(cont);
-    FE_
-}
-
-/*
-   NB: For direct returns to work properly, the name of the routine must be
-   the same as the name of the vector table with vtbl_ removed and DirectReturn
-   appended.  This is all the mangler understands.
- */
-
-const W_
-vtbl_seq[] = {
-    (W_) seqDirectReturn,
-    (W_) seqDirectReturn,
-    (W_) seqDirectReturn,
-    (W_) seqDirectReturn,
-    (W_) seqDirectReturn,
-    (W_) seqDirectReturn,
-    (W_) seqDirectReturn,
-    (W_) seqDirectReturn
-};
-
 #endif /* CONCURRENT */
 \end{code}