> So technically, your example might need to involve using g (and forceful GC > at a certain point during execution)
Good observation. > Maybe a stupid question, sorry: The RemoteTable generated using > template-haskell in CH without XStaticPointers would keep CAFs alive. So the > XStaticPointers extension does not entail using such a table? That's correct. The extension is a substitute for the remote table. In addition, it has the compiler do what remote tables demanded from the user: * adding functions to the remote table before they are looked up, * collecting the table pieces from the various modules into a global table. > Another question: Would it be sufficient to desugar "static g" to > g `seq` StaticPtr(StaticName "" "Main" "g") > instead of introducing a stable ptr and all that? This keeps g alive only while the expression is not evaluated to HNF. The solution I proposed is flawed as well, since it relies on the desugared static form being evaluated to HNF for the CAF to be referenced with a StablePtr. Anyway, after this much time we figured out how to implement the static pointer table. > Finally, there is a flag keepCAFs in the runtime which you can set to secure > the CAFs for the entire run. The parallel runtimes for Eden and GUM (as well > as my "packman" serialisation) do this. Good to know about that. Thank you, Facundo > AFter all, g is a CAF, so it is anyway "stable" in some sense, as long as it > is alive. > > However, I conjecture that this only fixes the one-node test, not the actual > use case (sending "static" stuff over the wire). > > Finally, there is a flag keepCAFs in the runtime which you can set to secure > the CAFs for the entire run. The parallel runtimes for Eden and GUM (as well > as my "packman" serialisation) do this. Facundo On Tue, Nov 18, 2014 at 1:20 PM, Jost Berthold <[email protected]> wrote: > Hi Facundo, > > You are completely right, the CAF named "g" might be accessed at any time > during the program execution. Parallel Haskell systems with distributed heap > (and runtime-supported serialisation) need to keep all CAFS alive for this > reason. > > Some comments inline along your mail: > >> While working in the StaticPointers language extension [1], we >> found we have some unusual CAFs which can be accessed after some >> periods of time where there is no reference to them. >> >> For instance, the following program when compiled contains no >> reference to `g`. `g` is actually looked up at runtime in symbol >> tables via the call to `deRefStaticPtr`. >> g :: String >> g = "hello" >> >> main = >> deRefStaticPtr (static g) >>= putStrLn > > > The bad scenario is certainly one where CAF g (a static thunk) is evaluated > during execution (i.e. turned into an indirection into the heap), and then > garbage-collected, as it might not be referenced by any (runnable) thread. > This GC does not revert the indirection into a thunk. Why should it, there > are no references to it, right? ;-) > > So technically, your example might need to involve using g (and forceful GC > at a certain point during execution): > > main = putStrLn g >> performGC >> > deRefStaticPtr (static g) >>= putStrLn > >> >> Desugars to: >> >> g :: String >> g = "hello" >> >> main = > > putStrLn g >> performGC >> >> >> deRefStaticPtr (StaticPtr (StaticName "" "Main" "g")) >>= putStrLn > > > During performGC, there would be no reference to g from any thread's stack. > I am of course assuming that g is indeed a thunk, and not statically > evaluated to a string during compilation (I am unsure whether GHC would do > that). > >> In principle, there is nothing stopping the garbage collector from >> reclaiming the closure of `g` before it is dynamically looked up. > > > Maybe a stupid question, sorry: The RemoteTable generated using > template-haskell in CH without XStaticPointers would keep CAFs alive. So the > XStaticPointers extension does not entail using such a table? > >> We are considering using StablePtrs to preserve `g`. So the code >> desugars instead to: >> >> g :: String >> g = "hello" >> >> main = >> deRefStaticPtr (let x = StaticPtr (StaticName "" "Main" "g") >> in unsafePerformIO $ newStablePtr g >> return x >> ) >>= putStrLn >> > > Another question: Would it be sufficient to desugar "static g" to > g `seq` StaticPtr(StaticName "" "Main" "g") > instead of introducing a stable ptr and all that? > AFter all, g is a CAF, so it is anyway "stable" in some sense, as long as it > is alive. > > However, I conjecture that this only fixes the one-node test, not the actual > use case (sending "static" stuff over the wire). > > Finally, there is a flag keepCAFs in the runtime which you can set to secure > the CAFs for the entire run. The parallel runtimes for Eden and GUM (as well > as my "packman" serialisation) do this. > > Yes, obviously, this opens a memory leak. It would be nice to not "keep" but > "revert" the CAFs (ghci does that) but on a "by-need" basis when a simple GC > cannot reclaim enough space; this would plug the mem.leak. This requires a > modification to the GHC runtime system, and it is unclear _which_ CAFs to > prefer when starting to revert. But I think it would be a more generally > useful feature. > However, this discussion (runtime/GC features) leads us straight out of the > design goals of "-XStaticPointers", I guess... > > Best regards, > Jost > _______________________________________________ > ghc-devs mailing list > [email protected] > http://www.haskell.org/mailman/listinfo/ghc-devs _______________________________________________ ghc-devs mailing list [email protected] http://www.haskell.org/mailman/listinfo/ghc-devs
