From 8b75acd3ca25165536f18976c8d80cb62ad613e4 Mon Sep 17 00:00:00 2001 From: Simon Marlow Date: Tue, 6 Dec 2011 11:38:07 +0000 Subject: 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. --- rts/RtsAPI.c | 64 ++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 34 insertions(+), 30 deletions(-) (limited to 'rts/RtsAPI.c') 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. */ -- cgit v1.2.1