[MLton-devel] Re: [MLton-user] ffi pointer lifetime
Matthew Fluet
fluet@cs.cornell.edu
Tue, 13 May 2003 19:45:11 -0400 (EDT)
> > It is all a bit weird since counting on finalization order is definitely a
> > bad idea any way.
>
> I agree with this. I think this makes it a good idea to do what we do
> now with the reversal every time, or something equally bizarre, and
> require the user to build additional structure on top of finalization
> if they want a particular order. And document that finalization order
> is unspecified.
I guess; I admit I haven't thought about it much.
Here's the best I could come up with for C-side malloc/free:
structure F = MLton.Finalize
local
val nop = _ffi "nop": Word32.word ref -> unit;
in
datatype cptr = CPtr of Word32.word ref
fun getW (CPtr w) = w
fun make (w: Word32.word, ptrs: cptr list, free: Word32.word -> unit) =
let
val ptr = CPtr (ref w)
in
F.finalize (ptr, fn () =>
(List.app (nop o getW) ptrs;
free w)) ;
ptr
end
end
local
val listSing = _ffi "listSing": int -> Word32.word;
val listCons = _ffi "listCons": int * Word32.word ref -> Word32.word;
val listFree = _ffi "listFree": Word32.word -> unit;
val listSum = _ffi "listSum": Word32.word ref -> int;
fun install (w: Word32.word, ptrs: cptr list) : cptr =
make (w, ptrs, listFree)
in
val listSing : int -> cptr =
fn i =>
install (listSing i, [])
val listCons : int * cptr -> cptr =
fn (i,ptr) =>
install (listCons (i, getW ptr), [ptr])
val listSum : cptr -> int =
fn ptr =>
listSum (getW ptr)
end
Note that "uses" of C-ptrs (with the exception of listFree) are
Word32.word refs -- this ensures that the ref cell that is being tracked
by finalization is kept all the way until it is actually used.
One problem with the above is that finalization is "slow", in the sense
that because the ptrs list is kept in the closure of the finalization
function; therefore, we only free one cons-cell per GC. I haven't been
able to come up with a better scheme. The goal was to write:
fun f n = ... some function requiring limit checks ...
val l = listSing 2
val l = listCons (2,l)
val l = listCons (2,l)
val l = listCons (2,l)
val l = listCons (2,l)
val l = listCons (2,l)
val l = listCons (2,l)
val _ = MLton.GC.collect ()
val _ = f 100
val _ = print (concat ["listSum(l) = ",
Int.toString (listSum l),
"\n"])
val _ = MLton.GC.collect ()
val _ = f 100
and have listSum correctly compute 14, but then collect all the C-side
data after the second GC.collect().
-------------------------------------------------------
Enterprise Linux Forum Conference & Expo, June 4-6, 2003, Santa Clara
The only event dedicated to issues related to Linux enterprise solutions
www.enterpriselinuxforum.com
_______________________________________________
MLton-devel mailing list
MLton-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mlton-devel