
On Sat, Apr 01, 2006 at 07:31:05AM -0500, David Roundy wrote:
I'd like to be sure that asynchronous exceptions can get into the standard. They require concurrency, but I'm not sure that they're included in John's page.
I am assuming you mean supporting the 'throwTo' primitive, which can be caught in the IO Monad? Asynchronous is something of a misnomer, they are only as asynchronous as your threading model, so in a standard cooperative system, they would only be delivered in the IO monad simply for the fact that that is the only time some other thread would be running in order to call 'throwTo'. There are no issues with implementing them in a fully cooperative system, in fact they are much much easier, you just need to set a flag on the target thread and when it resumes it checks the flag and throws the exception itself. The run-time cost of checking the flag will be consumed by the block that must have occured to being with. however, in a preemptive one, it is less clear whether they may be delivered right away or not and what the implementation costs are, as threads arn't necessarily blocked at a point where they can happily deal with an exception. Perhaps the yhc guys have thought about the problem? there are also a few questions we would want answered for the spec * do we require the thrower to 'block' until the signal is recieved? (only relevant to pre-emptive implementations) * what happens if mutilple thrown exceptions "pile up" before the catcher gets to them? * what happns to exceptions that fall off the end of threads, or the main thread? (should be answered anyway) * promtness? how much work is the target allowed to do before it "sees" the exception? pthreads allows an implementation to delay processing an exception to a "cancellation point" do we want the same thing in haskell? if not, how will this affect OS threaded implementations?
It would also be nice to address signal behavior, and by default state that signals should be converted to asynchronous exceptions. The only downside I can see of this as default behavior would be that in cooperative systems the response to a sigTERM might be very slow. But the benefits in terms of having bracket et al "just work" would be huge. Signals aren't entirely portable... but then I'd say a lot of the purpose of the standard is to allow the writing of portable code, which means addressing signals. And Windows (which doesn't have signals) has its own weird way of dealing with a keyboard interrupt that also ought to be converted into an asynchronous exception.
Yeah, I would like to deal with signals too, but a concise clear way does not occur to me off the top of my head.
It might be nice to have a third alternative option for cooperative systems in which all standard library IO routines automatically yield after running, to make it easier to port code written for a preemptive system to a cooperative compiler without manually inserting yields all over the place. It wouldn't give strong guarantees, but would seem convenient. It might also relax the requirement that yield will always switch threads, allowing the implementation to decide not to switch too frequently if yield is called very often. Or introduce a maybe_yield that is weaker.
There is (almost) no need to insert yields anyway, in order to meet the progress guarentee, a cooperative system must possibly yield at any potentialy blocking IO action. this ensures no time is actually wasted, haskell threads are always making progress and when one is waiting for something, another picks up the slack. The only time a manual 'yield' would be needed is when you had a long series of actions or a loop with no "actual" IO in them. meaning reading/writing handles, calling foreign concurrent functions, or any other potentially blocking operation. of course, such a thing as you say is totally okay by the standard. there is certainly wiggle room between strict cooperative and pre-emptive. pthreads has a sort of 'weaker yield' that just checks for exceptions but doesn't necessarily yield. John -- John Meacham - ⑆repetae.net⑆john⑈