On Thu, Aug 02, 2007 at 06:26:36PM -0700, Tim Chevalier wrote: > On 8/2/07, Tim Chevalier <[EMAIL PROTECTED]> wrote: > > I'm forwarding this to ghc-users since nobody answered on > > haskell-cafe, and I'm still curious... (The original message is at > > http://www.nabble.com/Lazy-in-either-argument--t4133855.html) > > > > Replying to myself again, I figured out later that what's really going > on in this example is that when you write: > f = f > (with no type signature) it desugars to: > f = [EMAIL PROTECTED] -> let f' = f' in f' > whereas if you write: > f :: Bool > f = f > the code is left more or less as is (if you're compiling with -Onot). > Then the let-body in the unannotated version gets compiled to a loop > that doesn't allocate, whereas (and I don't quite follow why) the > definition in the annotated version gets compiled to a loop that > allocates a new closure on each iteration. Thus, in the example with > two threads, the second version will be pre-empted to run the other > thread that does terminate, whereas the first version will never be > pre-empted. > > This makes sense at least if you consider the desugaring of > polymorphic definitions separately from the semantics of threads... > it's only when they interact that something strange happens. Maybe > it's an extreme corner case, but it still seems weird to me that > adding or removing a type signature should change the semantics of > code like this. It seems to me like the problem is that that the > transformation from (f = f) to (f = let f' = f' in f') isn't valid in > the presence of threads, since in a multithreaded situation the two > are observably different... but is that a bug in the desugarer, or a > bug in GHC's concurrency semantics?
If anything I think it's a bug in the code generator/the runtime. We shouldn't be generating uninterruptable loops! Option 1: Don't generate non-allocating loops. In all functions classed as loop-breaker by the occurAnal, generate heap checks even if there are no bytes involved. Pro: Very simple Con: Neil won't be too happy ;) Adds heap checks to pure-arithmetic loops. Option 2: Preempt non-allocating loops. Store somewhere the addresses of a sufficient subset of safe points. Note that the addresses of all info tables is a sufficient subset. On timer interrupt, single step the code until a safepoint is reached. Pro: low overhead and will provide most of the infrastructure I'll need if I ever get around to trying to implement hardware heap checks in GHC. Con: More complicated, especially if single-stepping is so high overhead we wind up needing to implement some other scheme, like linking the bochs core. Stefan
signature.asc
Description: Digital signature
_______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users