[project @ 2000-03-20 09:42:49 by andy]
[ghc-hetmet.git] / ghc / rts / Evaluator.c
index c123d39..b33c10f 100644 (file)
@@ -5,8 +5,8 @@
  * Copyright (c) 1994-1998.
  *
  * $RCSfile: Evaluator.c,v $
- * $Revision: 1.32 $
- * $Date: 2000/02/14 11:04:58 $
+ * $Revision: 1.44 $
+ * $Date: 2000/03/20 09:42:49 $
  * ---------------------------------------------------------------------------*/
 
 #include "Rts.h"
 #include "Assembler.h" /* for CFun stuff */
 #include "ForeignCall.h"
 #include "PrimOps.h"   /* for __{encode,decode}{Float,Double} */
+#include "Prelude.h"
+#include "ITimer.h"
 #include "Evaluator.h"
+#include "sainteger.h"
 
 #ifdef DEBUG
 #include "Printer.h"
 #include <ieee754.h> /* These are for primops */
 #endif
 
-#ifdef STANDALONE_INTEGER
-#include "sainteger.h"
-#else
-#error Non-standalone integer not yet supported
-#endif
+
+/* Allegedly useful macro, taken from ClosureMacros.h */
+#define payloadWord( c, i )   (*stgCast(StgWord*,      ((c)->payload+(i))))
+#define payloadPtr( c, i )    (*stgCast(StgPtr*,       ((c)->payload+(i))))
 
 /* An incredibly useful abbreviation.
  * Interestingly, there are some uses of END_TSO_QUEUE_closure that
@@ -105,6 +107,7 @@ void cp_init ( void )
 }
 
 
+
 void cp_enter ( StgBCO* b )
 {
    int is_ret_cont;
@@ -256,6 +259,12 @@ void setRtsFlags( int x )
 }
 
 
+typedef struct { 
+  StgTSOBlockReason reason;
+  unsigned int delay;
+} HugsBlock;
+
+
 /* --------------------------------------------------------------------------
  * Entering-objects and bytecode interpreter part of evaluator
  * ------------------------------------------------------------------------*/
@@ -285,7 +294,7 @@ void setRtsFlags( int x )
 /* Forward decls ... */
 static        void* enterBCO_primop1 ( int );
 static        void* enterBCO_primop2 ( int , int* /*StgThreadReturnCode* */, 
-                                       StgBCO**, Capability* );
+                                       StgBCO**, Capability*, HugsBlock * );
 static inline void PopUpdateFrame ( StgClosure* obj );
 static inline void PopCatchFrame  ( void );
 static inline void PopSeqFrame    ( void );
@@ -298,7 +307,6 @@ static        StgClosure* raiseAnError   ( StgClosure* exception );
 
 static int  enterCountI = 0;
 
-#ifdef STANDALONE_INTEGER
 StgDouble B__encodeDouble (B* s, I_ e);
 void      B__decodeDouble (B* man, I_* exp, StgDouble dbl);
 #if ! FLOATS_AS_DOUBLES
@@ -308,7 +316,6 @@ StgPtr    CreateByteArrayToHoldInteger ( int );
 B*        IntegerInsideByteArray ( StgPtr );
 void      SloppifyIntegerEnd ( StgPtr );
 #endif
-#endif
 
 
 
@@ -456,6 +463,10 @@ StgThreadReturnCode enter( Capability* cap, StgClosure* obj0 )
     register StgClosure*      obj;    /* object currently under evaluation */
              char             eCount; /* enter counter, for context switching */
 
+
+   HugsBlock hugsBlock = { NotBlocked, 0 };
+
+
 #ifdef DEBUG
     StgPtr tSp; StgUpdateFrame* tSu; StgPtr tSpLim;
 #endif
@@ -507,8 +518,35 @@ StgThreadReturnCode enter( Capability* cap, StgClosure* obj0 )
 #endif
        ) {
        if (context_switch) {
-          xPushCPtr(obj); /* code to restart with */
-          RETURN(ThreadYielding);
+        switch(hugsBlock.reason) {
+        case NotBlocked: {
+          xPushCPtr(obj); /* code to restart with */
+          RETURN(ThreadYielding);
+        }
+        case BlockedOnDelay: /* fall through */
+        case BlockedOnRead:  /* fall through */
+        case BlockedOnWrite: {
+          ASSERT(cap->rCurrentTSO->why_blocked == NotBlocked);
+          cap->rCurrentTSO->why_blocked = BlockedOnDelay;
+          ACQUIRE_LOCK(&sched_mutex);
+          
+#if defined(HAVE_SETITIMER)
+          cap->rCurrentTSO->block_info.delay 
+            = hugsBlock.delay + ticks_since_select;
+#else
+          cap->rCurrentTSO->block_info.target
+            = hugsBlock.delay + getourtimeofday();
+#endif
+          APPEND_TO_BLOCKED_QUEUE(cap->rCurrentTSO);
+          
+          RELEASE_LOCK(&sched_mutex);
+          
+          xPushCPtr(obj); /* code to restart with */
+          RETURN(ThreadBlocked);
+        }
+        default:
+          barf("Unknown context switch reasoning");
+        }
        }
     }
 
@@ -776,7 +814,7 @@ StgThreadReturnCode enter( Capability* cap, StgClosure* obj0 )
                     nat np = info->layout.payload.nptrs; 
                     nat i;
                     for(i=0; i < p; ++i) {
-                        payloadCPtr(o,i) = xPopCPtr();
+                        o->payload[i] = xPopCPtr();
                     }
                     for(i=0; i < np; ++i) {
                         payloadWord(o,p+i) = 0xdeadbeef;
@@ -798,7 +836,7 @@ StgThreadReturnCode enter( Capability* cap, StgClosure* obj0 )
                     nat np = info->layout.payload.nptrs; 
                     nat i;
                     for(i=0; i < p; ++i) {
-                        payloadCPtr(o,i) = xPopCPtr();
+                        o->payload[i] = xPopCPtr();
                     }
                     for(i=0; i < np; ++i) {
                         payloadWord(o,p+i) = 0xdeadbeef;
@@ -851,7 +889,7 @@ StgThreadReturnCode enter( Capability* cap, StgClosure* obj0 )
                 {
                     int  tag       = BCO_INSTR_8;
                     StgWord offset = BCO_INSTR_16;
-                    if (constrTag(stgCast(StgClosure*,xStackPtr(0))) != tag) {
+                    if (constrTag( (StgClosure*)xStackPtr(0) ) != tag) {
                         bciPtr += offset;
                     }
                     Continue;
@@ -871,7 +909,7 @@ StgThreadReturnCode enter( Capability* cap, StgClosure* obj0 )
                           || itbl->type == CONSTR_0_2
                           );
                     while (--i>=0) {
-                        xPushCPtr(payloadCPtr(o,i));
+                        xPushCPtr(o->payload[i]);
                     }
                     Continue;
                 }
@@ -915,11 +953,17 @@ StgThreadReturnCode enter( Capability* cap, StgClosure* obj0 )
                     xPushTaggedInt(bcoConstInt(bco,BCO_INSTR_8));
                     Continue;
                 }
+            Case(i_CONST_INT_big):
+                {
+                    int n = BCO_INSTR_16;
+                    xPushTaggedInt(bcoConstInt(bco,n));
+                    Continue;
+                }
             Case(i_PACK_INT):
                 {
                     StgClosure* o;
                     SSS; o = (StgClosure*)grabHpNonUpd(Izh_sizeW); LLL;
-                    SET_HDR(o,&Izh_con_info,??);
+                    SET_HDR(o,Izh_con_info,??);
                     payloadWord(o,0) = xPopTaggedInt();
                     IF_DEBUG(evaluator,
                              fprintf(stderr,"\tBuilt "); 
@@ -976,7 +1020,7 @@ StgThreadReturnCode enter( Capability* cap, StgClosure* obj0 )
                 {
                     StgClosure* o;
                     SSS; o = (StgClosure*)grabHpNonUpd(Wzh_sizeW); LLL;
-                    SET_HDR(o,&Wzh_con_info,??);
+                    SET_HDR(o,Wzh_con_info,??);
                     payloadWord(o,0) = xPopTaggedWord();
                     IF_DEBUG(evaluator,
                              fprintf(stderr,"\tBuilt "); 
@@ -1005,11 +1049,17 @@ StgThreadReturnCode enter( Capability* cap, StgClosure* obj0 )
                     xPushTaggedAddr(bcoConstAddr(bco,BCO_INSTR_8));
                     Continue;
                 }
+            Case(i_CONST_ADDR_big):
+                {
+                    int n = BCO_INSTR_16;
+                    xPushTaggedAddr(bcoConstAddr(bco,n));
+                    Continue;
+                }
             Case(i_PACK_ADDR):
                 {
                     StgClosure* o;
                     SSS; o = (StgClosure*)grabHpNonUpd(Azh_sizeW); LLL;
-                    SET_HDR(o,&Azh_con_info,??);
+                    SET_HDR(o,Azh_con_info,??);
                     payloadPtr(o,0) = xPopTaggedAddr();
                     IF_DEBUG(evaluator,
                              fprintf(stderr,"\tBuilt "); 
@@ -1042,7 +1092,7 @@ StgThreadReturnCode enter( Capability* cap, StgClosure* obj0 )
                 {
                     StgClosure* o;
                     SSS; o = (StgClosure*)grabHpNonUpd(Czh_sizeW); LLL;
-                    SET_HDR(o,&Czh_con_info,??);
+                    SET_HDR(o,Czh_con_info,??);
                     payloadWord(o,0) = xPopTaggedChar();
                     xPushPtr(stgCast(StgPtr,o));
                     IF_DEBUG(evaluator,
@@ -1075,7 +1125,7 @@ StgThreadReturnCode enter( Capability* cap, StgClosure* obj0 )
                 {
                     StgClosure* o;
                     SSS; o = (StgClosure*)grabHpNonUpd(Fzh_sizeW); LLL;
-                    SET_HDR(o,&Fzh_con_info,??);
+                    SET_HDR(o,Fzh_con_info,??);
                     ASSIGN_FLT(&payloadWord(o,0),xPopTaggedFloat());
                     IF_DEBUG(evaluator,
                              fprintf(stderr,"\tBuilt "); 
@@ -1114,7 +1164,7 @@ StgThreadReturnCode enter( Capability* cap, StgClosure* obj0 )
                 {
                     StgClosure* o;
                     SSS; o = (StgClosure*)grabHpNonUpd(Dzh_sizeW); LLL;
-                    SET_HDR(o,&Dzh_con_info,??);
+                    SET_HDR(o,Dzh_con_info,??);
                     ASSIGN_DBL(&payloadWord(o,0),xPopTaggedDouble());
                     IF_DEBUG(evaluator,
                              fprintf(stderr,"\tBuilt "); 
@@ -1140,7 +1190,7 @@ StgThreadReturnCode enter( Capability* cap, StgClosure* obj0 )
                 {
                     StgClosure* o;
                     SSS; o = (StgClosure*)grabHpNonUpd(Stablezh_sizeW); LLL;
-                    SET_HDR(o,&StablePtr_con_info,??);
+                    SET_HDR(o,StablePtr_con_info,??);
                     payloadWord(o,0) = xPopTaggedStable();
                     IF_DEBUG(evaluator,
                              fprintf(stderr,"\tBuilt "); 
@@ -1177,7 +1227,8 @@ StgThreadReturnCode enter( Capability* cap, StgClosure* obj0 )
                     pc_saved = PC; 
                     bco_tmp  = bco;
                     SSS;
-                    p        = enterBCO_primop2 ( i, &trc, &bco_tmp, cap ); 
+                    p        = enterBCO_primop2 ( i, &trc, &bco_tmp, cap, 
+                                                 &hugsBlock ); 
                     LLL;
                     bco      = bco_tmp;
                     bciPtr   = &(bcoInstr(bco,pc_saved));
@@ -1186,8 +1237,9 @@ StgThreadReturnCode enter( Capability* cap, StgClosure* obj0 )
                           /* we want to enter p */
                           obj = p; goto enterLoop;
                        } else {
-                          /* trc is the the StgThreadReturnCode for this thread */
-                          RETURN((StgThreadReturnCode)trc);
+                          /* trc is the the StgThreadReturnCode for 
+                          * this thread */
+                        RETURN((StgThreadReturnCode)trc);
                        };
                     }
                     Continue;
@@ -1268,11 +1320,9 @@ StgThreadReturnCode enter( Capability* cap, StgClosure* obj0 )
             Case(i_VAR_FLOAT_big):
             Case(i_CONST_CHAR_big):
             Case(i_VAR_CHAR_big):
-            Case(i_CONST_ADDR_big):
             Case(i_VAR_ADDR_big):
             Case(i_VAR_STABLE_big):
             Case(i_CONST_INTEGER_big):
-            Case(i_CONST_INT_big):
             Case(i_VAR_INT_big):
             Case(i_VAR_WORD_big):
             Case(i_RETADDR_big):
@@ -1337,7 +1387,7 @@ StgThreadReturnCode enter( Capability* cap, StgClosure* obj0 )
     case SE_CAF_BLACKHOLE:
         {
             /* Let the scheduler figure out what to do :-) */
-            cap->rCurrentTSO->whatNext = ThreadEnterGHC;
+            cap->rCurrentTSO->what_next = ThreadEnterGHC;
             xPushCPtr(obj);
             RETURN(ThreadYielding);
         }
@@ -1448,7 +1498,9 @@ StgThreadReturnCode enter( Capability* cap, StgClosure* obj0 )
                 case RET_VEC_SMALL:
                 case RET_BIG:
                 case RET_VEC_BIG:
-                 //       barf("todo: RET_[VEC_]{BIG,SMALL}");
+                        cap->rCurrentTSO->what_next = ThreadEnterGHC;
+                        xPushCPtr(obj);
+                        RETURN(ThreadYielding);
                 default:
                         belch("entered CONSTR with invalid continuation on stack");
                         IF_DEBUG(evaluator,
@@ -1467,7 +1519,7 @@ StgThreadReturnCode enter( Capability* cap, StgClosure* obj0 )
             //fprintf(stderr, "entering unknown closure -- yielding to sched\n"); 
             //printObj(obj);
             //LLL;
-            cap->rCurrentTSO->whatNext = ThreadEnterGHC;
+            cap->rCurrentTSO->what_next = ThreadEnterGHC;
             xPushCPtr(obj); /* code to restart with */
             RETURN(ThreadYielding);
         }
@@ -1779,7 +1831,7 @@ static StgClosure* makeErrorCall ( const char* msg )
    HaskellObj error 
       = asmClosureOfObject(getHugs_AsmObject_for("error"));
    HaskellObj unpack
-      = asmClosureOfObject(getHugs_AsmObject_for("primUnpackString"));
+      = asmClosureOfObject(getHugs_AsmObject_for("hugsprimUnpackString"));
    HaskellObj thunk
       = rts_apply ( unpack, rts_mkAddr ( (void*)msg ) );
    thunk
@@ -2113,17 +2165,16 @@ static StgClosure* makeErrorCall ( const char* msg )
 }
 
 
-#ifdef STANDALONE_INTEGER
 StgPtr CreateByteArrayToHoldInteger ( int nbytes )
 {
-   StgInt  words     = (nbytes+sizeof(W_)-1)/sizeof(W_);
+   StgWord words     = (nbytes+sizeof(W_)-1)/sizeof(W_);
    StgWord size      = sizeofW(StgArrWords) + words;
    StgArrWords* arr  = (StgArrWords*)allocate(size);
    SET_HDR(arr,&ARR_WORDS_info,CCCS);
    arr->words = words;
-   ASSERT(nbytes <= arr->words * sizeof(W_));
+   ASSERT((W_)nbytes <= arr->words * sizeof(W_));
 #ifdef DEBUG
-   {nat i;
+   {StgWord i;
     for (i = 0; i < words; ++i) {
     arr->payload[i] = 0xdeadbeef;
    }}
@@ -2182,7 +2233,6 @@ void SloppifyIntegerEnd ( StgPtr arr0 )
    SloppifyIntegerEnd(p);                            \
    PushPtr(p);                                       \
 }
-#endif
 
 
 
@@ -2211,7 +2261,7 @@ void SloppifyIntegerEnd ( StgPtr arr0 )
 }
 
 
-void myStackCheck ( Capability* cap )
+static void myStackCheck ( Capability* cap )
 {
    /* fprintf(stderr, "myStackCheck\n"); */
    if (!(gSpLim <= gSp && gSp <= stgCast(StgPtr,gSu))) {
@@ -2219,21 +2269,22 @@ void myStackCheck ( Capability* cap )
       assert(0);
    }
    while (1) {
-      if (!(gSu >= cap->rCurrentTSO->stack 
-            && gSu <= cap->rCurrentTSO->stack 
-               + cap->rCurrentTSO->stack_size)) {
+      if (!( (P_)gSu >= (P_)cap->rCurrentTSO->stack 
+              && 
+              (P_)gSu <= (P_)(cap->rCurrentTSO->stack 
+                              + cap->rCurrentTSO->stack_size))) {
          fprintf ( stderr, "myStackCheck: gSu out of stack\n" );
          assert(0);
       }
       switch (get_itbl(stgCast(StgClosure*,gSu))->type) {
       case CATCH_FRAME:
-         gSu = (StgPtr) ((StgCatchFrame*)(gSu))->link;
+         gSu = (StgUpdateFrame*) ((StgCatchFrame*)(gSu))->link;
          break;
       case UPDATE_FRAME:
-         gSu = (StgPtr) ((StgUpdateFrame*)(gSu))->link;
+         gSu = (StgUpdateFrame*) ((StgUpdateFrame*)(gSu))->link;
          break;
       case SEQ_FRAME:
-         gSu = (StgPtr) ((StgSeqFrame*)(gSu))->link;
+         gSu = (StgUpdateFrame*) ((StgSeqFrame*)(gSu))->link;
          break;
       case STOP_FRAME:
          goto postloop;
@@ -2426,7 +2477,6 @@ static void* enterBCO_primop1 ( int primop1code )
         case i_readStableOffAddr:  OP_AI_s(indexStablePtrOffAddrzh(r,x,y)); break;
         case i_writeStableOffAddr: OP_AIs_(writeStablePtrOffAddrzh(x,y,z)); break;
 
-#ifdef STANDALONE_INTEGER
         case i_compareInteger:     
             {
                 B* x = IntegerInsideByteArray(PopPtr());
@@ -2491,9 +2541,6 @@ static void* enterBCO_primop1 ( int primop1code )
                                       IntegerInsideByteArray(PopPtr())
                                    ));
                                    break; 
-#else
-#error Non-standalone integer not yet implemented
-#endif /* STANDALONE_INTEGER */
 
         case i_gtFloat:         OP_FF_B(x>y);        break;
         case i_geFloat:         OP_FF_B(x>=y);       break;
@@ -2534,7 +2581,6 @@ static void* enterBCO_primop1 ( int primop1code )
         case i_tanhFloat:       OP_F_F(tanh(x));     break;
         case i_powerFloat:      OP_FF_F(pow(x,y));   break;
 
-#ifdef STANDALONE_INTEGER
         case i_encodeFloatZ:
             {
                 StgPtr sig = PopPtr();
@@ -2554,9 +2600,7 @@ static void* enterBCO_primop1 ( int primop1code )
                 PushPtr(sig);
             }
             break;
-#else
-#error encode/decodeFloatZ not yet implemented for GHC ints
-#endif
+
         case i_isNaNFloat:      OP_F_B(isFloatNaN(x));      break;
         case i_isInfiniteFloat: OP_F_B(isFloatInfinite(x)); break;
         case i_isNegativeZeroFloat: OP_F_B(isFloatNegativeZero(x)); break;
@@ -2602,7 +2646,6 @@ static void* enterBCO_primop1 ( int primop1code )
         case i_tanhDouble:      OP_D_D(tanh(x));     break;
         case i_powerDouble:     OP_DD_D(pow(x,y));   break;
 
-#ifdef STANDALONE_INTEGER
         case i_encodeDoubleZ:
             {
                 StgPtr sig = PopPtr();
@@ -2622,9 +2665,7 @@ static void* enterBCO_primop1 ( int primop1code )
                 PushPtr(sig);
             }
             break;
-#else
-#error encode/decodeDoubleZ not yet implemented for GHC ints
-#endif
+
         case i_isNaNDouble:      OP_D_B(isDoubleNaN(x));      break;
         case i_isInfiniteDouble: OP_D_B(isDoubleInfinite(x)); break;
         case i_isNegativeZeroDouble: OP_D_B(isDoubleNegativeZero(x)); break;
@@ -2647,14 +2688,23 @@ static void* enterBCO_primop1 ( int primop1code )
       return the address of it and leave *return2 unchanged.
    To return a StgThreadReturnCode to the scheduler,
       set *return2 to it and return a non-NULL value.
+   To cause a context switch, set context_switch (its a global),
+   and optionally set hugsBlock to your rational.
 */
 static void* enterBCO_primop2 ( int primop2code, 
                                 int* /*StgThreadReturnCode* */ return2,
                                 StgBCO** bco,
-                                Capability* cap )
+                                Capability* cap,
+                               HugsBlock *hugsBlock )
 {
-        if (combined)
-           barf("enterBCO_primop1 in combined mode");
+        if (combined) {
+          /* A small concession: we need to allow ccalls, 
+              even in combined mode.
+           */
+           if (primop2code != i_ccall_ccall_IO &&
+               primop2code != i_ccall_stdcall_IO)
+              barf("enterBCO_primop2 in combined mode");
+        }
 
         switch (primop2code) {
         case i_raise:  /* raise#{err} */
@@ -2966,7 +3016,7 @@ static void* enterBCO_primop2 ( int primop2code,
                     */
                     PushCPtr((StgClosure*)(*bco));
                     *return2 = ThreadBlocked;
-                    return (void*)(1+(NULL));
+                    return (void*)(1+(char*)(NULL));
 
                 } else {
                     PushCPtr(mvar->value);
@@ -3012,21 +3062,7 @@ static void* enterBCO_primop2 ( int primop2code,
                 PushTaggedBool(x==y);
                 break;
             }
-        case i_getThreadId:
-            {
-                StgWord tid = cap->rCurrentTSO->id;
-                PushTaggedWord(tid);
-                break;
-            }
-        case i_cmpThreadIds:
-            {
-                StgWord tid1 = PopTaggedWord();
-                StgWord tid2 = PopTaggedWord();
-                if (tid1 < tid2) PushTaggedInt(-1);
-                else if (tid1 > tid2) PushTaggedInt(1);
-                else PushTaggedInt(0);
-                break;
-            }
+#ifdef PROVIDE_CONCURRENT
         case i_forkIO:
             {
                 StgClosure* closure;
@@ -3037,14 +3073,31 @@ static void* enterBCO_primop2 ( int primop2code,
                 tid     = tso->id;
                 scheduleThread(tso);
                 context_switch = 1;
+               /* Later: Change to use tso as the ThreadId */
                 PushTaggedWord(tid);
                 break;
             }
 
-#ifdef PROVIDE_CONCURRENT
         case i_killThread:
             {
-                StgTSO* tso = stgCast(StgTSO*,PopPtr());
+                StgWord n = PopTaggedWord();
+               StgTSO* tso = 0;
+               StgTSO *t;
+
+               // Map from ThreadId to Thread Structure */
+               for (t = all_threads; t != END_TSO_QUEUE; t = t->global_link) {
+                 if (n == t->id)
+                   tso = t;
+               }
+               if (tso == 0) {
+                 // Already dead
+                 break;
+               }
+
+               while (tso->what_next == ThreadRelocated) {
+                 tso = tso->link;
+               }
+
                 deleteThread(tso);
                 if (tso == cap->rCurrentTSO) { /* suicide */
                     *return2 = ThreadFinished;
@@ -3052,21 +3105,55 @@ static void* enterBCO_primop2 ( int primop2code,
                 }
                 break;
             }
-
-#if 1
-#if 0
-ToDo: another way out of the problem might be to add an explicit
-continuation to primTakeMVar: takeMVar v = primTakeMVar v takeMVar.
-The problem with this plan is that now I dont know how much to chop
-off the stack.
-#endif
-#endif
+        case i_raiseInThread:
+         ASSERT(0); /* not (yet) supported */
         case i_delay:
+         {
+           StgInt  n = PopTaggedInt();
+           context_switch = 1;
+           hugsBlock->reason = BlockedOnDelay;
+           hugsBlock->delay = n;
+           break;
+         }
         case i_waitRead:
+         {
+           StgInt  n = PopTaggedInt();
+           context_switch = 1;
+           hugsBlock->reason = BlockedOnRead;
+           hugsBlock->delay = n;
+           break;
+         }
         case i_waitWrite:
-                /* As PrimOps.h says: Hmm, I'll think about these later. */
-                ASSERT(0);
+         {
+           StgInt  n = PopTaggedInt();
+           context_switch = 1;
+           hugsBlock->reason = BlockedOnWrite;
+           hugsBlock->delay = n;
+           break;
+         }
+       case i_yield:
+         {
+           /* The definition of yield include an enter right after
+            * the primYield, at which time context_switch is tested.
+            */
+           context_switch = 1;
+           break;
+         }
+        case i_getThreadId:
+            {
+                StgWord tid = cap->rCurrentTSO->id;
+                PushTaggedWord(tid);
                 break;
+            }
+        case i_cmpThreadIds:
+            {
+                StgWord tid1 = PopTaggedWord();
+                StgWord tid2 = PopTaggedWord();
+                if (tid1 < tid2) PushTaggedInt(-1);
+                else if (tid1 > tid2) PushTaggedInt(1);
+                else PushTaggedInt(0);
+                break;
+            }
 #endif /* PROVIDE_CONCURRENT */
 
         case i_ccall_ccall_Id:
@@ -3116,7 +3203,7 @@ nat marshall(char arg_ty, void* arg)
     case INT_REP:
             PushTaggedInt(*((int*)arg));
             return ARG_SIZE(INT_TAG);
-#ifdef TODO_STANDALONE_INTEGER
+#if 0
     case INTEGER_REP:
             PushTaggedInteger(*((mpz_ptr*)arg));
             return ARG_SIZE(INTEGER_TAG);
@@ -3168,7 +3255,7 @@ nat unmarshall(char res_ty, void* res)
     case INT_REP:
             *((int*)res) = PopTaggedInt();
             return ARG_SIZE(INT_TAG);
-#ifdef TODO_STANDALONE_INTEGER
+#if 0
     case INTEGER_REP:
             *((mpz_ptr*)res) = PopTaggedInteger();
             return ARG_SIZE(INTEGER_TAG);
@@ -3219,7 +3306,7 @@ nat argSize( const char* ks )
         case INT_REP:
                 sz += sizeof(StgWord) * ARG_SIZE(INT_TAG);
                 break;
-#ifdef TODO_STANDALONE_INTEGER
+#if 0
         case INTEGER_REP:
                 sz += sizeof(StgWord) * ARG_SIZE(INTEGER_TAG);
                 break;
@@ -3264,8 +3351,6 @@ nat argSize( const char* ks )
  * (ghc/rts/StgPrimFloat.c)
  * ---------------------------------------------------------------------------*/
 
-#ifdef STANDALONE_INTEGER
-
 #if IEEE_FLOATING_POINT
 #define MY_DMINEXP  ((DBL_MIN_EXP) - (DBL_MANT_DIG) - 1)
 /* DMINEXP is defined in values.h on Linux (for example) */
@@ -3437,6 +3522,4 @@ void B__decodeFloat (B* man, I_* exp, StgFloat flt)
 
 #endif /* FLOATS_AS_DOUBLES */
 
-#endif /* STANDALONE_INTEGER */
-
 #endif /* INTERPRETER */