> When running this program under GHC 4.08 (OpenBSD 2.7, x86),
> only "b"s are written. Shouldn't GHC's implementation of
> Concurrent Haskell be preemptive?
>
> Regards,
>
> Hannah.
>
> import Concurrent
>
> main = forkIO a >> b
> where
> a = putStrLn "a" >> a
> b = putStrLn "b" >> b
If you run it for long enough, you'll see it switch to "a"s. The problem is
that the stdout handle has to be locked while one thread writes to it, and
we don't wake up the blocked thread immediately the lock is released, so the
initial thread just re-aquires it, and the second thread doesn't get a look
in.
The patch below causes a reschedule after a putMVar has woken a thread. It
helps the program above, and maybe it's the right thing to do in general -
opinions?
Cheers,
Simon
*** PrimOps.hc 2000/05/10 11:02:00 1.52
--- PrimOps.hc 2000/08/01 09:03:54
***************
*** 973,984 ****
if (mvar->head == (StgTSO *)&END_TSO_QUEUE_closure) {
mvar->tail = (StgTSO *)&END_TSO_QUEUE_closure;
}
}
/* unlocks the MVar in the SMP case */
SET_INFO(mvar,&FULL_MVAR_info);
- /* ToDo: yield here for better communication performance? */
JMP_(ENTRY_CODE(Sp[0]));
FE_
}
--- 973,989 ----
if (mvar->head == (StgTSO *)&END_TSO_QUEUE_closure) {
mvar->tail = (StgTSO *)&END_TSO_QUEUE_closure;
}
+
+ /* unlocks the MVar in the SMP case */
+ SET_INFO(mvar,&FULL_MVAR_info);
+
+ /* yield, to give the newly woken thread a chance to take the MVar */
+ JMP_(stg_yield_noregs);
}
/* unlocks the MVar in the SMP case */
SET_INFO(mvar,&FULL_MVAR_info);
JMP_(ENTRY_CODE(Sp[0]));
FE_
}