Re: Finalizers: conclusion?

2002-10-21 Thread John Meacham
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

2002-10-21 Thread Alastair Reid

>> 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?

2002-10-21 Thread Alastair Reid

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

2002-10-21 Thread Alastair Reid

> [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?

2002-10-21 Thread Simon Marlow

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?

2002-10-21 Thread Antony Courtney
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?

2002-10-21 Thread Malcolm Wallace
"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