[MLton] CML
Matthew Fluet
fluet@cs.cornell.edu
Mon, 3 May 2004 20:48:26 -0400 (EDT)
> So, it seems like we really need finalizers.
>
> datatype 'a chan =
> CHAN of {prio: int ref, inQ: 'a inQ, outQ: 'a outQ}
> type 'a in_chan = 'a chan Finalizable.t option ref
> type 'a out_chan = 'a chan Finalizable.t option ref
>
> And creating a channel would do something like:
> fun channel () =
> let
> val prio = ref 1
> val inQ = Q.new ()
> val outQ = Q.new ()
> val chan = {prio = prio, inQ = inQ, outQ = outQ}
>
> val incf = Finalizable.new chan
> val inc = ref (SOME incf)
> val incw = Weak.new inc
> val outc' = Finalizable.new chan
> val outc = ref (SOME outcf)
> val outcw = Weak.new outc
>
> val () = Finalizable.addFinalizer
> (incf, fn () =>
> case Weak.get outcw of
> NONE => ()
> | SOME outc => outc := NONE)
> val () = Finalizable.addFinalizer
> (outf, fn () =>
> case Weak.get incw of
> NONE => ()
> | SOME inc => inc := NONE)
> in
> (inc, outc)
> end
>
> Now, when an in_chan is GCed, it will trigger the outQ' finalizer, which
> will bang NONE into the out_chan, killing all the blocked writers.
Typo above: when an inc is GCed, it will trigger the incf finalizer, which
will bang NONE into the outc, killing all the blocked writers.
> Running it, taking n from the command line, I get:
>
> [fluet@cfs39 tests 56]% ./ping-pong 100000
> Time start: 1083629751.794
> Time end: 1083629751.878
> Time diff: 83ms
That was with the CML asserts turned off; with them turned on (which
corresponds to what is checked into CVS), I get:
[fluet@cfs39 tests 82]% ./ping-pong 100000
Time start: 1083631571.779
Time end: 1083631572.149
Time diff: 369ms
BTW, this was on a 1.1GHz machine.