diff options
| author | Simon Marlow <marlowsd@gmail.com> | 2011-12-06 11:38:07 +0000 | 
|---|---|---|
| committer | Simon Marlow <marlowsd@gmail.com> | 2011-12-06 15:19:18 +0000 | 
| commit | 8b75acd3ca25165536f18976c8d80cb62ad613e4 (patch) | |
| tree | ccb87f6f5df2af15ca2ca8f65e5163b1f34886b8 /rts/RtsAPI.c | |
| parent | 657773c8e59917fda05ee08065ec566aebb50a5f (diff) | |
| download | haskell-8b75acd3ca25165536f18976c8d80cb62ad613e4.tar.gz | |
Make forkProcess work with +RTS -N
Consider this experimental for the time being.  There are a lot of
things that could go wrong, but I've verified that at least it works
on the test cases we have.
I also did some API cleanups while I was here.  Previously we had:
Capability * rts_eval (Capability *cap, HaskellObj p, /*out*/HaskellObj *ret);
but this API is particularly error-prone: if you forget to discard the
Capability * you passed in and use the return value instead, then
you're in for subtle bugs with +RTS -N later on.  So I changed all
these functions to this form:
void rts_eval (/* inout */ Capability **cap,
               /* in    */ HaskellObj p,
               /* out */   HaskellObj *ret)
It's much harder to use this version incorrectly, because you have to
pass the Capability in by reference.
Diffstat (limited to 'rts/RtsAPI.c')
| -rw-r--r-- | rts/RtsAPI.c | 64 | 
1 files changed, 34 insertions, 30 deletions
| diff --git a/rts/RtsAPI.c b/rts/RtsAPI.c index 8fcf8ce812..0463f15ad8 100644 --- a/rts/RtsAPI.c +++ b/rts/RtsAPI.c @@ -421,36 +421,39 @@ createStrictIOThread(Capability *cap, nat stack_size,  StgClosure *closure)     Evaluating Haskell expressions     ------------------------------------------------------------------------- */ -Capability * -rts_eval (Capability *cap, HaskellObj p, /*out*/HaskellObj *ret) +void rts_eval (/* inout */ Capability **cap, +               /* in    */ HaskellObj p, +               /* out */   HaskellObj *ret)  {      StgTSO *tso; -    tso = createGenThread(cap, RtsFlags.GcFlags.initialStkSize, p); -    return scheduleWaitThread(tso,ret,cap); +    tso = createGenThread(*cap, RtsFlags.GcFlags.initialStkSize, p); +    scheduleWaitThread(tso,ret,cap);  } -Capability * -rts_eval_ (Capability *cap, HaskellObj p, unsigned int stack_size,  -	   /*out*/HaskellObj *ret) +void rts_eval_ (/* inout */ Capability **cap, +                /* in    */ HaskellObj p, +                /* in    */ unsigned int stack_size, +                /* out   */ HaskellObj *ret)  {      StgTSO *tso; -    tso = createGenThread(cap, stack_size, p); -    return scheduleWaitThread(tso,ret,cap); +    tso = createGenThread(*cap, stack_size, p); +    scheduleWaitThread(tso,ret,cap);  }  /*   * rts_evalIO() evaluates a value of the form (IO a), forcing the action's   * result to WHNF before returning.   */ -Capability * -rts_evalIO (Capability *cap, HaskellObj p, /*out*/HaskellObj *ret) +void rts_evalIO (/* inout */ Capability **cap, +                 /* in    */ HaskellObj p, +                 /* out */   HaskellObj *ret)  {      StgTSO* tso;  -    tso = createStrictIOThread(cap, RtsFlags.GcFlags.initialStkSize, p); -    return scheduleWaitThread(tso,ret,cap); +    tso = createStrictIOThread(*cap, RtsFlags.GcFlags.initialStkSize, p); +    scheduleWaitThread(tso,ret,cap);  }  /* @@ -459,49 +462,50 @@ rts_evalIO (Capability *cap, HaskellObj p, /*out*/HaskellObj *ret)   * action's result to WHNF before returning.  The result is returned   * in a StablePtr.   */ -Capability * -rts_evalStableIO (Capability *cap, HsStablePtr s, /*out*/HsStablePtr *ret) +void rts_evalStableIO (/* inout */ Capability **cap, +                       /* in    */ HsStablePtr s, +                       /* out */   HsStablePtr *ret)  {      StgTSO* tso;      StgClosure *p, *r;      SchedulerStatus stat; -     +      p = (StgClosure *)deRefStablePtr(s); -    tso = createStrictIOThread(cap, RtsFlags.GcFlags.initialStkSize, p); +    tso = createStrictIOThread(*cap, RtsFlags.GcFlags.initialStkSize, p);      // async exceptions are always blocked by default in the created      // thread.  See #1048.      tso->flags |= TSO_BLOCKEX | TSO_INTERRUPTIBLE; -    cap = scheduleWaitThread(tso,&r,cap); -    stat = rts_getSchedStatus(cap); +    scheduleWaitThread(tso,&r,cap); +    stat = rts_getSchedStatus(*cap);      if (stat == Success && ret != NULL) {  	ASSERT(r != NULL);  	*ret = getStablePtr((StgPtr)r);      } - -    return cap;  }  /*   * Like rts_evalIO(), but doesn't force the action's result.   */ -Capability * -rts_evalLazyIO (Capability *cap, HaskellObj p, /*out*/HaskellObj *ret) +void rts_evalLazyIO (/* inout */ Capability **cap, +                     /* in    */ HaskellObj p, +                     /* out */   HaskellObj *ret)  {      StgTSO *tso; -    tso = createIOThread(cap, RtsFlags.GcFlags.initialStkSize, p); -    return scheduleWaitThread(tso,ret,cap); +    tso = createIOThread(*cap, RtsFlags.GcFlags.initialStkSize, p); +    scheduleWaitThread(tso,ret,cap);  } -Capability * -rts_evalLazyIO_ (Capability *cap, HaskellObj p, unsigned int stack_size,  -		 /*out*/HaskellObj *ret) +void rts_evalLazyIO_ (/* inout */ Capability **cap, +                      /* in    */ HaskellObj p, +                      /* in    */ unsigned int stack_size, +                      /* out   */ HaskellObj *ret)  {      StgTSO *tso; -    tso = createIOThread(cap, stack_size, p); -    return scheduleWaitThread(tso,ret,cap); +    tso = createIOThread(*cap, stack_size, p); +    scheduleWaitThread(tso,ret,cap);  }  /* Convenience function for decoding the returned status. */ | 
