Re: Finalizers strike back
(It would be nice to have some concurrency in nhc98, of course, but I don't foresee that happening soon.) I remember implementing cooperative concurrency in Hugs as being rather easy. Of course, that was building on a base which already used a continuation passing IO monad... If you want to try, I could dig out some details but the main issues are: 1) When you have a choice of which thread to wake next, it matters which you wake next. IIRC, waking the wrong one makes it impossible to implement a producer-consumer pattern. 2) There's a lot of interaction with non-deterministic exception handling. 3) unsafePerformIO foo had better not block since we have no way to block the non-monadic code that invoked it. In that case, we raise an exception or give up (don't remember which). Actually, I'm just wondering whether I can use the GC as a poor-man's scheduler. If a finaliser blocks on an MVar, save its state, keep the finaliser in the pending queue, and return to the main thread. Then on the next GC, try the same finaliser again, ad infinitum until it succeeds. The finalizer won't become runnable until someone does a putMVar so you can deal with this case by storing the finalizer's state in a queue of blocked threads attached to the MVar and having putMVar do a context switch to the thread at the head of the MVar's queue of blocked threads. If you want finalizers to have priority over other threads, have two queues: one for finalizers, one for normal threads. -- Alastair ___ FFI mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/ffi
Re: Finalizers strike back
George Russell [EMAIL PROTECTED] writes: it would normally be a good idea for implementations and programmers to provide and use MVars, even if they do not provide and use concurrency, ... If NHC does not provide MVars, I think it should. I don't think MVars make any sense without concurrency, so I don't see the point of implementing the one without the other. I'm willing to be persuaded otherwise. (It would be nice to have some concurrency in nhc98, of course, but I don't foresee that happening soon.) I apologise to Malcolm, but in any case I doubt if implementing MVars in a world with only one thread would cost him a great deal of effort. Well it would be simple enough provided you didn't mind your computation halting with deadlock rather unpredictably. :-) Actually, I'm just wondering whether I can use the GC as a poor-man's scheduler. If a finaliser blocks on an MVar, save its state, keep the finaliser in the pending queue, and return to the main thread. Then on the next GC, try the same finaliser again, ad infinitum until it succeeds. Regards, Malcolm ___ FFI mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/ffi
Re: Finalizers strike back
On 11-Oct-2002, George Russell [EMAIL PROTECTED] wrote: I think we should remember that the FFI standard has to address various audiences (1) those who want to implement portable code in just FFI + Haskell98. This group does not have access to functions for conveniently manipulating mutable state, therefore Alastair's problem with IORefs will not be a problem for them. However Haskell inside finalizers will at any rate not harm them This argument is invalid, because those who want to implement portable code in just Haskel98 + FFI will very quickly use the FFI to implement IORefs or something similar. Consider someone who, say, calls out from Haskell to Java (to do funny graphics, say) and writes a finalizer which calls Java code. At the same time, they also want to do some completely separate pure computation in Haskell, which is made available to Java. Since Java at least does have preemptive concurrency, while it is running at all, it is perfectly possible that Java will call the Haskell computation while the Java finalizer is running. You want a license to make the roof fall in at this point; I don't think you should have it. If you have a non-thread-safe Haskell implementation, and you try to call it from two different threads without protecting this somehow, then the roof *will* fall in at least some of the time. This follows directly from the definition of non-thread-safe. So you want to disallow non-thread-safe Haskell implementations from supporting the FFI? -- Fergus Henderson [EMAIL PROTECTED] | I have always known that the pursuit The University of Melbourne | of excellence is a lethal habit WWW: http://www.cs.mu.oz.au/~fjh | -- the last words of T. S. Garp. ___ FFI mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/ffi
Re: Finalizers strike back
Alastair Reid wrote: [snip] I'm not sure I really understand the problem. The FFI standard (Release Candidate 4, the one I have printed out here) does not define IORefs, and of course Haskell 98 doesn't either. Therefore, although this code is broken, this particular example doesn't matter if all we are considering is code written in Haskell 98 + FFI. If there's no shared mutable Haskell state, writing finalizers in Haskell buys you little - what does a finalizer do other than cleanup shared state? (Note that it doesn't cleanup unshared state - what would be the point?) [snip] What I hear you saying is that the FFI standard should depend on a concurrency standard. I think there was a strong sentiment that we should avoid this. I agree though that it is necessary if we allow Haskell finalizers. [snip] I think we should remember that the FFI standard has to address various audiences (1) those who want to implement portable code in just FFI + Haskell98. This group does not have access to functions for conveniently manipulating mutable state, therefore Alastair's problem with IORefs will not be a problem for them. However Haskell inside finalizers will at any rate not harm them. Furthermore it is incorrect to say that just because there is no Haskell mutable state, there is no reason such people may want it to be possible to call Haskell while a finalizer is running. Consider someone who, say, calls out from Haskell to Java (to do funny graphics, say) and writes a finalizer which calls Java code. At the same time, they also want to do some completely separate pure computation in Haskell, which is made available to Java. Since Java at least does have preemptive concurrency, while it is running at all, it is perfectly possible that Java will call the Haskell computation while the Java finalizer is running. You want a license to make the roof fall in at this point; I don't think you should have it. (2) those who want to implement portable code in FFI + Haskell98 + something else. (I suspect this is the larger group.) To discuss this at all we simply have to speculate about what something else might be. One obvious something else is mutable state. Alastair is assuming that something else is IORefs but not MVars. However I assert this is implausible or at least unfortunate, because for reasons I've explained, it would normally be a good idea for implementations and programmers to provide and use MVars, even if they do not provide and use concurrency, since otherwise you can't write functions like Alastair's newObject and killObject without making unnecessary assumptions about the properties of the implementation. If NHC does not provide MVars, I think it should. I apologise to Malcolm, but in any case I doubt if implementing MVars in a world with only one thread would cost him a great deal of effort. To sum up, it's NOT that I want the FFI standard to depend on concurrency. It's once again that I don't want the FFI standard to depend on the absence of concurrency (as Alastair's IORef code does). ___ FFI mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/ffi
Re: Finalizers strike back
[snip] I'm not sure I really understand the problem. The FFI standard (Release Candidate 4, the one I have printed out here) does not define IORefs, and of course Haskell 98 doesn't either. Therefore, although this code is broken, this particular example doesn't matter if all we are considering is code written in Haskell 98 + FFI. If there's no shared mutable Haskell state, writing finalizers in Haskell buys you little - what does a finalizer do other than cleanup shared state? (Note that it doesn't cleanup unshared state - what would be the point?) I think IORefs are the most widely accepted extension of Haskell. The FFI spec doesn't depend on IORefs but it should certainly be designed to work in an environment where they exist. However to me this code just looks totally wrong because of course I use GHC, a system with preemptive scheduling, and would regard it as incompetent to use anything other than an MVar here. I completely agree. I do not believe we can have any useful form of Haskell finalizers (meaning finalizers that manipulate shared Haskell state) without adding MVars. But, since concurrency is not so widely implemented as IORefs, we are trying to produce an FFI design which does not require concurrency extensions. My solution to this conflict is not to add Haskell finalizers. However to me this code just looks totally wrong because of course I use GHC, a system with preemptive scheduling, and would regard it as incompetent to use anything other than an MVar here. Even for Hugs I don't like this code, because [...] I think you're taking my code out of context. The purpose in writing that code using IORefs was to show the kind of code you should not write because it would suffer from race conditions. I completely agree that some form of locking is required to make the code safe. I guess I'd be willing to have Haskell finalizers if we agreed on an appropriate form of locking that all implementers can and will implement. NHC currently lacks a locking mechanism. I believe that using Hugs' MVars in conjunction with SimonM's patch will lead to deadlock in the cases that would have suffered race conditions using IORefs. Supposing we posit that there is a GlobalVariables standard. Just want to remark that the variables don't have to be global. Haskell finalizers are specified by closures and closures can point to any IORefs you fancy. Anyone writing a finalizer should be aware (indeed the FFI standard should say) that the finalizer may be run at any point (after all, when else would you expect it to run) and should take precautions against it. What I hear you saying is that the FFI standard should depend on a concurrency standard. I think there was a strong sentiment that we should avoid this. I agree though that it is necessary if we allow Haskell finalizers. -- Alastair Reid [EMAIL PROTECTED] Reid Consulting (UK) Limited http://www.reid-consulting-uk.ltd.uk/alastair/ ___ FFI mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/ffi