
On 30 March 2006 13:05, John Meacham wrote:
but the debugging/deterministic benefits could be useful. you could be guarenteed to reproduce a given sequence of context switches which could make finding concurrent heisenbugs easier.
Actually +RTS -C0 already gives deterministic concurrency in GHC. And you're right, it's essential for debugging. SMP has made my life somewhat more painful of late :-)
or something like concurrent 'hat' or another debugger might find it easier to work in such a mode.
In any case, what I think of when I think of 'writing a portable app' is that from _the spec alone_ I can write something that I can expect to work on any compliant system. This goal can be achieved to various degrees. But if the specification says, 'the implementation might be cooperative' and I write assuming that, then it pretty much will definitly work anywhere perhaps with some spurious 'yields'.
Absolutely, but a preemptive implementation has no way to tell you if you missed out a 'yield', and that essentially is the same as non-portabiliy. It doesn't matter that the spec told you you needed the yield, if the implementation you're using works fine without it, non-portable software will be the result. What's more, in some cases it isn't even possible to insert enough yields. It's entirely reasonable to have an application that runs some CPU-bound pure computation in one thread and a GUI in some other threads. This type of application can't be implemented if the standard guarantees nothing more than cooperative scheduling. Worse, no static property of the code tells you that.
however if it says something to the effect of 'runnable threads will be timeshared via some fair algorithm for some definition of fair'
No, I'm suggesting the specific fairness guarantees mentioned earlier (and on the wiki page).
then it doesn't help much writing portable apps since you would want to test on the various compilers to see what their definiton of "fair" is.
Given those fairness guarantees, programmers will not need to care whether the implementation is using preemption based on allocation, or one based on reductions, or arbitrary inter-instruction preemption. Because it is hard to write a program that can tell the difference, especially if you stick to using proper synchronisation primitives, nobody will do it by accident. Contrast this with a standard that allows both cooperative and preemptive scheduling. It's much easier to write a program that can show the difference, and I'm worried that people will do it all the time, by accident. That's bad.
I thought yhc supported unboxed values, so a loop like
count 0 = 0 count n = count (n - 1)
count 100000
could block the runtime (assuming it was properly unboxed by the compiler) since it never calls back into it and is just a straight up countdown loop?
are we talking about the same compiler? YHC is fully interpreted, has no unboxed types, and AFAIK it is impossible to write any code that doesn't get preempted after a while. Cheers, Simon

"Simon Marlow"
I thought yhc supported unboxed values, so a loop like
count 0 = 0 count n = count (n - 1)
count 100000
could block the runtime (assuming it was properly unboxed by the compiler) since it never calls back into it and is just a straight up countdown loop?
are we talking about the same compiler? YHC is fully interpreted, has no unboxed types, and AFAIK it is impossible to write any code that doesn't get preempted after a while.
Indeed. But unboxing is not the issue - the main reason is that yhc cannot currently compile that code into a loop - jumps only go forwards in the bytecode, never backwards. The only possible bytecode representation of a loop is as a recursive call, which immediately presents an opportunity to insert a yield. Regards, Malcolm
participants (2)
-
Malcolm Wallace
-
Simon Marlow