Re: Finalizers: conclusion?
I also need the touchForeignPtr trick in much of my code. we need to come up with a replacement if we dont have haskell finalizers. here are my canidate suggestions: * add a subset of Weak pointers (or some subset of their functionality) to the FFI spec. just get rid of the finalizer capability (for obvious reasons) and the Weak pointers work just as well, and it might have uses elsewhere? - or - * add addForeignDependency :: ForeignPtr a -> ForeignPtr b -> IO () (which on ghc is trivially implemented as 'addForeignDependency a b = mkWeak a b Nothing >> return ()') note that breaking these dependencies might be tricky/impossible depending on what we choose. with weak pointers, one can finalize the Weak that the mkWeak call returns, but then you have to keep track of them in a seperate data structure than your ForeignPtr, which doesnt seem ideal. a better solution would be some sort of breakWeakPtr :: k -> v -> IO () breakForeignDependency :: ForeignPtr a -> ForeignPtr b -> IO () hmm... John On Mon, Oct 21, 2002 at 02:50:03PM -0400, Antony Courtney wrote: > I have only been watching this Haskell finalizers discussion from a > great distance, but I am keenly interested in the outcome, as it will > require a significant overhaul of some of my own FFI-based library code. > (My code currently uses touchForeignPtr in a Haskell finalizer to > express a liveness dependency, but this is apparently not supported by > the latest FFI spec. and won't be.) -- --- John Meacham - California Institute of Technology, Alum. - [EMAIL PROTECTED] --- ___ FFI mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/ffi
Re: The Revenge of Finalizers
>> The problem is that the G-machine optimizes away some of the >> updates which make sure that the heap is always in a consistent >> state in a pure graph-reduction system. > A pure G-machine updates all redexes, but the STG-machine only > updates /shared/ redexes, yes? It's a while since I looked at it but, IIRC, a naive graph reducer can update the same redex multiple times while the G-machine tries to update it just once. -- Alastair ___ FFI mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/ffi
Re: Finalizers: conclusion?
Hi Antony, [btw will you be in New Haven around 16-19 Nov? I'm going to swing through there on my next trip over and it'd be good to see you and maybe ever humiliate myself again in the Gunks with you.] > (My code currently uses touchForeignPtr in a Haskell > finalizer to express a liveness dependency, but this is apparently > not supported by the latest FFI spec. and won't be.) I think it was agreed that we need to replace touchForeignPtr with something else to let us express liveness dependencies. I hope you'll take part in that discussion since you and John Meacham are the only ones who seem to have used it so far. As a strawman to get discussion rolling, would something like the following do the job? -- | -- keepAlive x y ensures that the finalizer for y is not run -- until after the finalizer for x has run to completion. -- Of course, it might not even run then if y is still live -- at that point. keepAlive :: ForeignPtr a -> ForeignPtr b -> IO () Off the top of my head, I'd say the name sucks, the argument order is open to change and the semantics will cause headaches for GHC. Any other objections? :-) > I would really like to have just a little bit more in-depth > understanding of why Haskell finalizers are an impossibility. In > particular, the current finalizers.txt document on cvs.haskell.org > states: >> [...] It turns out that the real killer is shared thunks. Suppose the main thread is evaluating a thunk and is interrupted by a finalizer which needs to evaluate the same thunk. What should you do? The choices are: 1) Report an error. This is easy but semantically wrong. 2) Block the finalizer until the main thread completes evaluation just as GHC does. Blocking the finalizer would require all Haskell implementations to implement preemptive concurrency. This is thought to be an excessive burden. 3) Let the finalizer evaluate it. Eventually both finalizer and main thread will produce equivalent results and update the thunk with the same result. Sounds easy but: - it's quite delicate to achieve this goal. - it would require us to turn off blackholing - an implementation technique which eliminates some serious space leaks. Given the choice of poor semantics, huge implementation effort and reduced portability, and space leaks, we decided to redefine our goals and declare C finalizers adequate. [I tried to describe this problem in finalizers.txt this morning but I think the above is clearer.] >> We want to be able to use mutable Haskell state from a Haskell >> finalizer, but we clearly can't use IORefs. Finalizers which >> modify IORefs will always contain race conditions. > Although I suspect that the reason why we "clearly can't use IORefs" > or why such code will "always contain race conditions" is clear and > obvious to everyone else involved in this discussion, it is not at > all clear to me as an outsider. If someone would be kind enough to > write just a sentence or two clarifying the "obvious" problem, I > would be very grateful. Finalizers in Hugs and NHC behave like interrupts: at some random part of the execution of your program, the finalizer is run. Just as you worry about what happens to your money when interrupting C code like: int old = account.balance; int new = old + 1; account.balance = new; so you should worry about what happens to the corresponding Haskell code which uses IORefs. One way to fix this instance of the problem in Haskell is to provide an atomic operation to modify the value of an IORef. [Finalizers behave like threads in GHC. The same problem results.] -- 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
Re: The Death of Finalizers
> [snip] How sad. It's an unfortunate hole in the specification and I > hope someone will come up with a way of fixing it someday. I don't think it'll happen until preemptive concurrency is more widely implemented. > In the meantime, I'm glad we have got a new function > atomicModifyIORef which I for one will use, when it gets into GHC's > regular release. It's really nice that we can use laziness to > safely update a mutable value without blocking. Another nail in the > coffin for Standard ML. Do we still have atomicModifyIORef? I don't know that there's that much point now that Haskell finalizers are gone. I don't have a strong objection (esp. since it seems every implementation now has it) but it doesn't seem so necessary now. > I think the addForeignFinalizer function or whatever it is should > nevertheless be renamed to addUnsafeForeignFinalizer (and likewise > for newForeignObject). I see some sense in that argument but: 1) I don't especially like that the only standard way of doing finalizers is labelled 'unsafe'. 2) We started cutting release candidates for Hugs yesterday using the old names. Sigh... Again, no strong objection but I'd do it differently. > Also I suppose Alastair's hs_freeStablePtr function which allows you > to do it from C, or whatever, will have to be added. I've just added void hs_free_stable_ptr(HsStablePtr x); to Hugs in the hope that it will make it into the next release candidate The capitalization change is for consistency with void hs_perform_gc(void); and I hope it will be what we put into the FFI report. > I hope Alastair will forgive me for engaging him in such a lengthy > argument, when he turns out to have been right all along. I wish I'd come up with convincing arguments faster. -- Alastair ___ FFI mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/ffi
Finalizers: conclusion?
Ok, I'm sad to say that the problem we recently uncovered to do with finalizers sharing values with the rest of the program essentially kills off the possibility of doing Haskell finalizers in systems without proper concurrency support. I'm rather embarassed that I didn't notice this before; sorry for wasting everyone's time :-( Let's keep C finalizers for the FFI spec. In GHC I imagine we'll continue to offer Haskell finalizers as an extension, but I haven't decided on an interface yet (suggestions welcome). >From now on I intend to keep track of a strict quota that prevents me from writing more email than code :-) Cheers, Simon ___ FFI mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/ffi
Re: Finalizers: conclusion?
Hi, I have only been watching this Haskell finalizers discussion from a great distance, but I am keenly interested in the outcome, as it will require a significant overhaul of some of my own FFI-based library code. (My code currently uses touchForeignPtr in a Haskell finalizer to express a liveness dependency, but this is apparently not supported by the latest FFI spec. and won't be.) I would really like to have just a little bit more in-depth understanding of why Haskell finalizers are an impossibility. In particular, the current finalizers.txt document on cvs.haskell.org states: We want to be able to use mutable Haskell state from a Haskell finalizer, but we clearly can't use IORefs. Finalizers which modify IORefs will always contain race conditions. Although I suspect that the reason why we "clearly can't use IORefs" or why such code will "always contain race conditions" is clear and obvious to everyone else involved in this discussion, it is not at all clear to me as an outsider. If someone would be kind enough to write just a sentence or two clarifying the "obvious" problem, I would be very grateful. Thanks, -antony -- Antony Courtney Grad. Student, Dept. of Computer Science, Yale University [EMAIL PROTECTED] http://www.apocalypse.org/pub/u/antony ___ FFI mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/ffi
Re: Finalizers: conclusion?
"Simon Marlow" <[EMAIL PROTECTED]> writes: > Ok, I'm sad to say that the problem we recently uncovered to do with > finalizers sharing values with the rest of the program essentially kills > off the possibility of doing Haskell finalizers in systems without > proper concurrency support. Well, I'm not yet totally convinced that we can't do it, but I'll happily leave it for another time to work out how. > Let's keep C finalizers for the FFI spec. In GHC I imagine we'll > continue to offer Haskell finalizers as an extension, but I haven't > decided on an interface yet (suggestions welcome). Since ghc-5.04.x already has the published interface module Foreign.ForeignPtr newForeignPtr :: Ptr a -> IO () -> ForeignPtr a addForeignPtrFinalizer :: ForeignPtr a -> IO () -> IO () I suggest we keep those names for the "Haskell finaliser" extension. This would eliminate version configuration questions for both existing and future code that uses the interface. I quite liked the suggestion of newUnsafeForeignPtr :: Ptr a -> FunPtr (Ptr a->IO ()) -> ForeignPtr a addUnsafeForeignPtrFinalizer :: ForeignPtr a -> FunPtr (Ptr a->IO ()) -> IO () for the C-finaliser standard. Regards, Malcolm ___ FFI mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/ffi