Re: Updates to FFI spec: performGC
Alastair wrote about performGC (snipped)
It'd be nice to say that it has to be a full GC - but I've no idea how to specify that in a non-operational (i.e., implementation dependent) way. I certainly don't think you should constrain implementations to be able to perform a "full GC" in any sense. It is possible if unlikely that someone will get along to implementing the "HaskellKit", where GC is entirely dispensed with and replaced by region analysis. Even if that's not the case, I certainly hope that one of these days someone will get along to implementing a Haskell compiler that does at least some easy region analysis. Also there are probably hard-real-time GC algorithms (like Baker's treadmill) or algorithms which are close to being hard-real-time (like the train algorithm) where doing a "full GC" would be a major pain.
Alastair wrote about performGC (snipped)
It'd be nice to say that it has to be a full GC - but I've no idea how to specify that in a non-operational (i.e., implementation dependent) way.
George Russell <ger@tzi.de> writes:
I certainly don't think you should constrain implementations to be able to perform a "full GC" in any sense. It is possible if unlikely that someone will get along to implementing the "HaskellKit", where GC is entirely dispensed with and replaced by region analysis. Even if that's not the case, I certainly hope that one of these days someone will get along to implementing a Haskell compiler that does at least some easy region analysis.
Region-based systems have the quite wonderful property that garbage is disposed of promptly - you don't have to wait for the next GC for the memory to be released. Which means that performGC becomes a nullop. [That said, I'm not sure that region-based analysis is all that easy in the presence of lazy evaluation since it is so critically tied to estimating lifetimes.]
Also there are probably hard-real-time GC algorithms (like Baker's treadmill) or algorithms which are close to being hard-real-time (like the train algorithm) where doing a "full GC" would be a major pain.
The desired property is that the runtime system releases all unreachable objects. To make the fine-grained GCs (i.e., those that do a little GC now and then instead of a full GC) do this, all you need is stop mutating or allocating objects and then keep invoking the GC until it gets round to where it was when you started. There's usually some kind of colouring or 'epoch' mechanism that lets you know when you're back where you started. Of course, you trash any real-time properties in the process - see recent mail by me in the archive or my old paper for ideas on how to lessen that or dream up your own ideas for how to make two real time GCs work together nicely. [Again, though, I'm not sure there's much danger of a RT GC being added to Haskell - it's too hard estimating execution time, memory usage, etc. so making your GC more predictable doesn't seem like a major win.] In short, I think the current design is perfectly adequate for interfacing current systems to C code and will extend nicely in the future as motivating examples make actual needs. For example, even if we had a finer grained version of performGC, I expect most people would find that performGC provided the functionality that they need so they'd write their own (using a finer-grained interface) if we didn't provide it for them - only those who have real time programs interfacing to Haskell would make use of the finer-grained interface. -- Alastair Reid alastair@reid-consulting-uk.ltd.uk Reid Consulting (UK) Limited http://www.reid-consulting-uk.ltd.uk/alastair/
Alastair Reid <alastair@reid-consulting-uk.ltd.uk> wrote,
George Russell <ger@tzi.de> writes:
Also there are probably hard-real-time GC algorithms (like Baker's treadmill) or algorithms which are close to being hard-real-time (like the train algorithm) where doing a "full GC" would be a major pain.
The desired property is that the runtime system releases all unreachable objects.
I like that phrase, so I put Finally, \code{hs\_perform\_gc()} advices the Haskell storage manager to perform a garbage collection, where the storage manager makes an effort to releases all unreachable objects. This function must not be invoked from C functions that are imported \code{unsafe} into Haskell code nor may it be used from a finalizer. into the spec. It's signals the intent, but still leaves an implementation some freedom. Manuel
Alastair Reid wrote: [snip]
Region-based systems have the quite wonderful property that garbage is disposed of promptly - you don't have to wait for the next GC for the memory to be released. Which means that performGC becomes a nullop. [snip] This is not entirely true. Firstly, some region-based systems could use stacks of some sort, which might mean hanging onto something recognised as garbage until it is possible to pop the stack. Secondly, the user may think that something is garbage at the time of performGC, although the compiler is not yet able to prove that it is.
I agree with those who regard it as extremely undesirable to rely on the garbage-collection algorithm to carry out important actions (like closing a window or a file), if it matters at all when they happen. I think "performGC" should be seen more as something like C's "register" storage attribute, which is a friendly hint to the compiler but nothing more. Manuel's new wording (except for the typo "advices" instead of "advises") expresses this perfectly, so there probably isn't much point in discussing this further.
participants (3)
-
Alastair Reid -
George Russell -
Manuel M T Chakravarty