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