<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta name="robots" content="index,nofollow">



<title>MLtonFinalizable - MLton Standard ML Compiler (SML Compiler)</title>
<link rel="stylesheet" type="text/css" charset="iso-8859-1" media="all" href="common.css">
<link rel="stylesheet" type="text/css" charset="iso-8859-1" media="screen" href="screen.css">
<link rel="stylesheet" type="text/css" charset="iso-8859-1" media="print" href="print.css">


<link rel="Start" href="Home">


</head>

<body lang="en" dir="ltr">

<table bgcolor = lightblue cellspacing = 0 style = "border: 0px;" width = 100%>
  <tr>
    <td style = "
		border: 0px;
		color: darkblue; 
		font-size: 150%;
		text-align: left;">
      <a class = mltona href="Home">MLton 20051202</a>
    <td style = "
		border: 0px;
		font-size: 150%;
		text-align: center;
		width: 50%;">
      MLtonFinalizable
    <td style = "
		border: 0px;
		text-align: right;">
      <table cellspacing = 0 style = "border: 0px">
        <tr style = "vertical-align: middle;">
      </table>
  <tr style = "background-color: white;">
    <td colspan = 3
	style = "
		border: 0px;
		font-size:70%;
		text-align: right;">
      <a href = "Home">Home</a>
      &nbsp;<a href = "Index">Index</a>
      &nbsp;
</table>
<div id="content" lang="en" dir="ltr">

<pre class=code>
<B><FONT COLOR="#0000FF">signature</FONT></B> MLTON_FINALIZABLE =
   <B><FONT COLOR="#0000FF">sig</FONT></B>
      <B><FONT COLOR="#A020F0">type</FONT></B><FONT COLOR="#228B22"><B> 'a t

      </FONT></B><B><FONT COLOR="#A020F0">val</FONT></B> addFinalizer: 'a t * ('a -&gt; unit) -&gt; unit
      <B><FONT COLOR="#A020F0">val</FONT></B> finalizeBefore: 'a t * 'b t -&gt; unit
      <B><FONT COLOR="#A020F0">val</FONT></B> new: 'a -&gt; 'a t
      <B><FONT COLOR="#A020F0">val</FONT></B> touch: 'a t -&gt; unit
      <B><FONT COLOR="#A020F0">val</FONT></B> withValue: 'a t * ('a -&gt; 'b) -&gt; 'b
   <B><FONT COLOR="#0000FF">end</FONT></B>
</PRE>
<p>
 
</p>
<p>
A finalizable value is a value to which <em>finalizers</em> can be attached.  A finalizer is a function that runs after a garbage collection determines that the value to which it is attached is unreachable.  Reachability is the same as with <a href="MLtonWeak">weak pointers</a>.  The finalizer is treated like a signal handler, in that it runs asynchronously in a separate thread, with signals blocked, and will not interrupt a critical section (see <a href="MLtonThread">MLtonThread</a>). 
</p>

    <ul>

    <li>
<p>
 <tt>addFinalizer&nbsp;(v,&nbsp;f)</tt> 
</p>
</li>

        <ul>

  adds <tt>f</tt> as a finalizer to <tt>v</tt>.  This means that sometime   after the last call to <tt>withValue</tt> on <tt>v</tt> completes and   <tt>v</tt> becomes unreachable, <tt>f</tt> will be called with the value of   <tt>v</tt>.  
        </ul>


    <li class="gap">
<p>
 <tt>finalizeBefore&nbsp;(v1,&nbsp;v2)</tt> 
</p>
</li>

        <ul>

  ensures that <tt>v1</tt> will be finalized before <tt>v2</tt>.  A cycle of   values <tt>v</tt> = <tt>v1</tt>, ..., <tt>vn</tt> = <tt>v</tt> with   <tt>finalizeBefore&nbsp;(vi,&nbsp;vi+1)</tt> will result in none of the <tt>vi</tt>   being finalized. 
        </ul>


    <li class="gap">
<p>
 <tt>new&nbsp;x</tt> 
</p>
</li>

        <ul>

  creates a new finalizable value, <tt>v</tt>, with value <tt>x</tt>.  The   finalizers of <tt>v</tt> will run sometime after the last call to   <tt>withValue</tt> on <tt>v</tt> when the garbage collector determines that   <tt>v</tt> is unreachable.  
        </ul>


    <li class="gap">
<p>
 <tt>touch&nbsp;v</tt> 
</p>
</li>

        <ul>

  ensures that <tt>v</tt>'s finalizers will not run before the call to   <tt>touch</tt>. 
        </ul>


    <li class="gap">
<p>
 <tt>withValue&nbsp;(v,&nbsp;f)</tt> 
</p>
</li>

        <ul>

  returns the result of applying <tt>f</tt> to the value of <tt>v</tt> and   ensures that <tt>v</tt>'s finalizers will not run before <tt>f</tt>   completes.  The call to <tt>f</tt> is a nontail call. 
        </ul>



    </ul>


<h2 id="head-0f01ed56a1e32a05e5ef96e4d779f34784af9a96">Example</h2>
<p>
Suppose that <tt>finalizable.sml</tt> contains the following. 
</p>

<pre class=code>
<B><FONT COLOR="#0000FF">signature</FONT></B> CLIST =
   <B><FONT COLOR="#0000FF">sig</FONT></B>
      <B><FONT COLOR="#A020F0">type</FONT></B><FONT COLOR="#228B22"><B> t

      </FONT></B><B><FONT COLOR="#A020F0">val</FONT></B> cons: int * t -&gt; t
      <B><FONT COLOR="#A020F0">val</FONT></B> sing: int -&gt; t
      <B><FONT COLOR="#A020F0">val</FONT></B> sum: t -&gt; int
   <B><FONT COLOR="#0000FF">end</FONT></B>

<B><FONT COLOR="#0000FF">functor</FONT></B> CList (<B><FONT COLOR="#0000FF">structure</FONT></B> F: MLTON_FINALIZABLE
               <B><FONT COLOR="#0000FF">structure</FONT></B> Prim:
                  <B><FONT COLOR="#0000FF">sig</FONT></B>
                     <B><FONT COLOR="#A020F0">val</FONT></B> cons: int * Word32.word -&gt; Word32.word
                     <B><FONT COLOR="#A020F0">val</FONT></B> free: Word32.word -&gt; unit
                     <B><FONT COLOR="#A020F0">val</FONT></B> sing: int -&gt; Word32.word
                     <B><FONT COLOR="#A020F0">val</FONT></B> sum: Word32.word -&gt; int
                  <B><FONT COLOR="#0000FF">end</FONT></B>): CLIST =
   <B><FONT COLOR="#0000FF">struct</FONT></B>
      <B><FONT COLOR="#A020F0">type</FONT></B><FONT COLOR="#228B22"><B> t </FONT></B>=<FONT COLOR="#228B22"><B> Word32.word F.t

      </FONT></B><B><FONT COLOR="#A020F0">fun</FONT></B> cons (n: int, l: t) =
         F.withValue
         (l, <B><FONT COLOR="#A020F0">fn</FONT></B> w' =&gt;
          <B><FONT COLOR="#A020F0">let</FONT></B>
             <B><FONT COLOR="#A020F0">val</FONT></B> c = F.new (Prim.cons (n, w'))
             <B><FONT COLOR="#A020F0">val</FONT></B> _ = F.addFinalizer (c, Prim.free)
             <B><FONT COLOR="#A020F0">val</FONT></B> _ = F.finalizeBefore (c, l)
          <B><FONT COLOR="#A020F0">in</FONT></B>
             c
          <B><FONT COLOR="#A020F0">end</FONT></B>)
      
      <B><FONT COLOR="#A020F0">fun</FONT></B> sing n =
         <B><FONT COLOR="#A020F0">let</FONT></B>
            <B><FONT COLOR="#A020F0">val</FONT></B> c = F.new (Prim.sing n)
            <B><FONT COLOR="#A020F0">val</FONT></B> _ = F.addFinalizer (c, Prim.free)
         <B><FONT COLOR="#A020F0">in</FONT></B>
            c
         <B><FONT COLOR="#A020F0">end</FONT></B>

      <B><FONT COLOR="#A020F0">fun</FONT></B> sum c = F.withValue (c, Prim.sum)
   <B><FONT COLOR="#0000FF">end</FONT></B>

<B><FONT COLOR="#0000FF">functor</FONT></B> Test (<B><FONT COLOR="#0000FF">structure</FONT></B> CList: CLIST
              <B><FONT COLOR="#0000FF">structure</FONT></B> MLton: <B><FONT COLOR="#0000FF">sig</FONT></B>
                                  <B><FONT COLOR="#0000FF">structure</FONT></B> GC:
                                     <B><FONT COLOR="#0000FF">sig</FONT></B>
                                        <B><FONT COLOR="#A020F0">val</FONT></B> collect: unit -&gt; unit
                                     <B><FONT COLOR="#0000FF">end</FONT></B>
                               <B><FONT COLOR="#0000FF">end</FONT></B>) =
   <B><FONT COLOR="#0000FF">struct</FONT></B>
      <B><FONT COLOR="#A020F0">fun</FONT></B> f n =
         <B><FONT COLOR="#A020F0">if</FONT></B> n = <B><FONT COLOR="#5F9EA0">1</FONT></B>
            <B><FONT COLOR="#A020F0">then</FONT></B> ()
         <B><FONT COLOR="#A020F0">else</FONT></B>
            <B><FONT COLOR="#A020F0">let</FONT></B>
               <B><FONT COLOR="#A020F0">val</FONT></B> a = Array.tabulate (n, <B><FONT COLOR="#A020F0">fn</FONT></B> i =&gt; i)
               <B><FONT COLOR="#A020F0">val</FONT></B> _ = Array.sub (a, <B><FONT COLOR="#5F9EA0">0</FONT></B>) + Array.sub (a, <B><FONT COLOR="#5F9EA0">1</FONT></B>)
            <B><FONT COLOR="#A020F0">in</FONT></B>
               f (n - <B><FONT COLOR="#5F9EA0">1</FONT></B>)
            <B><FONT COLOR="#A020F0">end</FONT></B>
            
      <B><FONT COLOR="#A020F0">val</FONT></B> l = CList.sing <B><FONT COLOR="#5F9EA0">2</FONT></B>
      <B><FONT COLOR="#A020F0">val</FONT></B> l = CList.cons (<B><FONT COLOR="#5F9EA0">2</FONT></B>,l)
      <B><FONT COLOR="#A020F0">val</FONT></B> l = CList.cons (<B><FONT COLOR="#5F9EA0">2</FONT></B>,l)
      <B><FONT COLOR="#A020F0">val</FONT></B> l = CList.cons (<B><FONT COLOR="#5F9EA0">2</FONT></B>,l)
      <B><FONT COLOR="#A020F0">val</FONT></B> l = CList.cons (<B><FONT COLOR="#5F9EA0">2</FONT></B>,l)
      <B><FONT COLOR="#A020F0">val</FONT></B> l = CList.cons (<B><FONT COLOR="#5F9EA0">2</FONT></B>,l)
      <B><FONT COLOR="#A020F0">val</FONT></B> l = CList.cons (<B><FONT COLOR="#5F9EA0">2</FONT></B>,l)
      <B><FONT COLOR="#A020F0">val</FONT></B> _ = MLton.GC.collect ()
      <B><FONT COLOR="#A020F0">val</FONT></B> _ = f <B><FONT COLOR="#5F9EA0">100</FONT></B>
      <B><FONT COLOR="#A020F0">val</FONT></B> _ = print (concat [<FONT COLOR="#BC8F8F"><B>&quot;listSum(l) = &quot;</FONT></B>,
                             Int.toString (CList.sum l),
                             <FONT COLOR="#BC8F8F"><B>&quot;\n&quot;</FONT></B>])
      <B><FONT COLOR="#A020F0">val</FONT></B> _ = MLton.GC.collect ()
      <B><FONT COLOR="#A020F0">val</FONT></B> _ = f <B><FONT COLOR="#5F9EA0">100</FONT></B>
   <B><FONT COLOR="#0000FF">end</FONT></B>

<B><FONT COLOR="#0000FF">structure</FONT></B> CList =
   CList (<B><FONT COLOR="#0000FF">structure</FONT></B> F = MLton.Finalizable
          <B><FONT COLOR="#0000FF">structure</FONT></B> Prim =
             <B><FONT COLOR="#0000FF">struct</FONT></B>
                <B><FONT COLOR="#A020F0">val</FONT></B> cons = _import <FONT COLOR="#BC8F8F"><B>&quot;listCons&quot;</FONT></B>: int * Word32.word -&gt; Word32.word;
                <B><FONT COLOR="#A020F0">val</FONT></B> free = _import <FONT COLOR="#BC8F8F"><B>&quot;listFree&quot;</FONT></B>: Word32.word -&gt; unit;
                <B><FONT COLOR="#A020F0">val</FONT></B> sing = _import <FONT COLOR="#BC8F8F"><B>&quot;listSing&quot;</FONT></B>: int -&gt; Word32.word;
                <B><FONT COLOR="#A020F0">val</FONT></B> sum = _import <FONT COLOR="#BC8F8F"><B>&quot;listSum&quot;</FONT></B>: Word32.word -&gt; int;
             <B><FONT COLOR="#0000FF">end</FONT></B>)

<B><FONT COLOR="#0000FF">structure</FONT></B> S = Test (<B><FONT COLOR="#0000FF">structure</FONT></B> CList = CList
                    <B><FONT COLOR="#0000FF">structure</FONT></B> MLton = MLton)
</PRE>
<p>
 
</p>
<p>
Suppose that <tt>cons.c</tt> contains the following. 
<pre>#include &lt;stdio.h&gt;

typedef unsigned int uint;

typedef struct Cons {
        struct Cons *next;
        int value;
} *Cons;

Cons listCons (int n, Cons c) {
        Cons res;

        res = (Cons) malloc (sizeof(*res));
        fprintf (stderr, "0x%08x = listCons (%d)\n", (uint)res, n);
        res-&gt;next = c;
        res-&gt;value = n;
        return res;
}

Cons listSing (int n) {
        Cons res;

        res = (Cons) malloc (sizeof(*res));
        fprintf (stderr, "0x%08x = listSing (%d)\n", (uint)res, n);
        res-&gt;next = NULL;
        res-&gt;value = n;
        return res;
}

void listFree (Cons p) {
        fprintf (stderr, "listFree (0x%08x)\n", (uint)p);
        free (p);
}

int listSum (Cons c) {
        int res;

        fprintf (stderr, "listSum\n");
        res = 0;
        for (; c != NULL; c = c-&gt;next)
                res += c-&gt;value;
        return res;
}
</pre>
</p>
<p>
We can compile these to create an executable with 
<pre>% mlton -default-ann 'allowFFI true' finalizable.sml cons.c
</pre>
</p>
<p>
Running this executable will create output like the following. 
<pre>% finalizable
0x08072890 = listSing (2)
0x080728a0 = listCons (2)
0x080728b0 = listCons (2)
0x080728c0 = listCons (2)
0x080728d0 = listCons (2)
0x080728e0 = listCons (2)
0x080728f0 = listCons (2)
listSum
listSum(l) = 14
listFree (0x080728f0)
listFree (0x080728e0)
listFree (0x080728d0)
listFree (0x080728c0)
listFree (0x080728b0)
listFree (0x080728a0)
listFree (0x08072890)
</pre>
</p>
<h2 id="head-1a7d780f4e551c514e4ae9523e76c5fe42784626">Synchronous Finalizers</h2>
<p>
Finalizers in MLton are asynchronous.  That is, they run at an unspecified time, interrupting the user program.  It is also possible, and sometimes useful, to have synchronous finalizers, where the user program explicitly decides when to run enabled finalizers.  We have considered this in MLton, and it seems possible, but there are some unresolved design issues.  See the thread at 
</p>

    <ul>

    <li>
<p>
 <a class="external" href="http://mlton.org/pipermail/mlton/2004-September/016570.html"><img src="moin-www.png" alt="[WWW]" height="11" width="11">http://mlton.org/pipermail/mlton/2004-September/016570.html</a> 
</p>
</li>

    </ul>


<p>
Also see <a href = "References#Boehm03">Boehm03</a>. 
</p>
</div>



<p>
<hr>
Last edited on 2005-12-02 03:43:20 by <span title="209-6-203-188.c3-0.smr-ubr1.sbo-smr.ma.cable.rcn.com"><a href="MatthewFluet">MatthewFluet</a></span>.
</body></html>
