Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > media > contrib-release > by-pkgid > bd5c3d824c3db63ffd9226c15941e6ad > files > 107

mozart-1.4.0-1mdv2010.0.i586.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><TITLE>17 Situated Cell-Like Objects</TITLE><LINK href="ozdoc.css" rel="stylesheet" type="text/css"></HEAD><BODY><TABLE align="center" border="0" cellpadding="6" cellspacing="6" class="nav"><TR bgcolor="#DDDDDD"><TD><A href="node21.html#chapter.counter.object">&lt;&lt; Prev</A></TD><TD><A href="node19.html">- Up -</A></TD></TR></TABLE><DIV id="chapter.celloid"><H1><A name="chapter.celloid">17 Situated Cell-Like Objects</A></H1><P>In this chapter, we implement <SPAN class="ignore"><CODE><SPAN class="keyword">class</SPAN>&nbsp;</CODE></SPAN><CODE><SPAN class="type">Celloid</SPAN></CODE>s: an extension class for objects that behave essentially like cells; they have content which can be accessed (read) and assigned (written). The new challenge here is twofold: (1) during garbage collection the content of a <SPAN class="ignore"><CODE><SPAN class="keyword">class</SPAN>&nbsp;</CODE></SPAN><CODE><SPAN class="type">Celloid</SPAN></CODE> must also be copied, (2) we must ensure that only a local <SPAN class="ignore"><CODE><SPAN class="keyword">class</SPAN>&nbsp;</CODE></SPAN><CODE><SPAN class="type">Celloid</SPAN></CODE> can be mutated (for a non-local one, we should signal an error).</P><P>A <SPAN class="ignore"><CODE><SPAN class="keyword">class</SPAN>&nbsp;</CODE></SPAN><CODE><SPAN class="type">Celloid</SPAN></CODE> is <EM>situated</EM>. What does <EM>situated</EM> mean? Simply that the object resides in one specific constraint store, aka a computation space. If <SPAN class="ignore"><CODE><SPAN class="keyword">class</SPAN>&nbsp;</CODE></SPAN><CODE><SPAN class="type">Celloid</SPAN></CODE> <CODE>C</CODE> resides in space S1, and S2 is a subspace of S1 (i.&nbsp;e. is subordinated to S1), it is meaningful for a thread in S2 to <EM>access</EM> <CODE>C</CODE> since any constraint (therefore value) from S1 are visible in S2, but it is generally not meaningful for a thread in S2 to <EM>assign</EM> <CODE>C</CODE> since constraints (therefore values) specific to S2 are not visible from S1. Our implementation will enforce the appropriate restrictions.</P><H2><A name="label62">17.1 Celloid Class</A></H2><P>Again, we subclass <SPAN class="ignore"><CODE><SPAN class="keyword">class</SPAN>&nbsp;</CODE></SPAN><CODE><SPAN class="type">OZ_Extension</SPAN></CODE>. </P><DL class="anonymous"><DD class="code"><CODE>#include&nbsp;<SPAN class="string">&quot;mozart.h&quot;</SPAN>&nbsp;<BR>&nbsp;<BR><SPAN class="keyword">class</SPAN>&nbsp;<SPAN class="type">Celloid</SPAN>&nbsp;:&nbsp;<SPAN class="keyword">public</SPAN>&nbsp;<SPAN class="type">OZ_Extension</SPAN>&nbsp;{<BR><SPAN class="keyword">public</SPAN>:<BR>&nbsp;&nbsp;<SPAN class="type">OZ_Term</SPAN>&nbsp;<SPAN class="variablename">content</SPAN>;<BR>&nbsp;&nbsp;<SPAN class="functionname">Celloid</SPAN>(<SPAN class="type">OZ_Term</SPAN>&nbsp;<SPAN class="variablename">t</SPAN>):content(t){}<BR>&nbsp;&nbsp;<SPAN class="keyword">static</SPAN>&nbsp;<SPAN class="type">int</SPAN>&nbsp;<SPAN class="variablename">id</SPAN>;<BR>&nbsp;&nbsp;<SPAN class="keyword">virtual</SPAN>&nbsp;<SPAN class="type">int</SPAN>&nbsp;<SPAN class="functionname">getIdV</SPAN>()&nbsp;{&nbsp;<SPAN class="keyword">return</SPAN>&nbsp;id;&nbsp;}<BR>&nbsp;&nbsp;<SPAN class="keyword">virtual</SPAN>&nbsp;<SPAN class="type">OZ_Term</SPAN>&nbsp;<SPAN class="functionname">typeV</SPAN>()&nbsp;{&nbsp;<SPAN class="keyword">return</SPAN>&nbsp;OZ_atom(<SPAN class="string">&quot;celloid&quot;</SPAN>);&nbsp;}<BR>&nbsp;&nbsp;<SPAN class="keyword">virtual</SPAN>&nbsp;<SPAN class="type">OZ_Extension</SPAN>*&nbsp;<SPAN class="functionname">gCollectV</SPAN>();<BR>&nbsp;&nbsp;<SPAN class="keyword">virtual</SPAN>&nbsp;<SPAN class="type">OZ_Extension</SPAN>*&nbsp;<SPAN class="functionname">sCloneV</SPAN>();<BR>&nbsp;&nbsp;<SPAN class="keyword">virtual</SPAN>&nbsp;<SPAN class="type">void</SPAN>&nbsp;<SPAN class="functionname">gCollectRecurseV</SPAN>();<BR>&nbsp;&nbsp;<SPAN class="keyword">virtual</SPAN>&nbsp;<SPAN class="type">void</SPAN>&nbsp;<SPAN class="functionname">sCloneRecurseV</SPAN>();<BR>&nbsp;&nbsp;<SPAN class="keyword">virtual</SPAN>&nbsp;<SPAN class="type">OZ_Term</SPAN>&nbsp;<SPAN class="functionname">printV</SPAN>(<SPAN class="type">int</SPAN>&nbsp;<SPAN class="variablename">depth</SPAN>&nbsp;=&nbsp;10);<BR>};</CODE></DD></DL><P></P><H2><A name="label63">17.2 Celloid Creation</A></H2><P>The <CODE>celloid_new</CODE> builtin takes one input argument <CODE>t</CODE>, creates a new celloid whose content is initialized to <CODE>t</CODE>, boxes it and returns the result. </P><DL class="anonymous"><DD class="code"><CODE><SPAN class="functionname">OZ_BI_define</SPAN>(celloid_new,1,1)<BR>{<BR>&nbsp;&nbsp;OZ_declareTerm(0,t);<BR>&nbsp;&nbsp;OZ_RETURN(OZ_extension(<SPAN class="keyword">new</SPAN>&nbsp;<SPAN class="type">Celloid</SPAN>(t)));<BR>}<BR>OZ_BI_end</CODE></DD></DL><P></P><H2><A name="label64">17.3 Type Testing</A></H2><P>The definitions here are similar to the ones presented earlier for the <SPAN class="ignore"><CODE><SPAN class="keyword">class</SPAN>&nbsp;</CODE></SPAN><CODE><SPAN class="type">Counter</SPAN></CODE> class. </P><DL class="anonymous"><DD class="code"><CODE><SPAN class="type">int</SPAN>&nbsp;<SPAN class="reference">Celloid</SPAN>::<SPAN class="variablename">id</SPAN>;<BR>&nbsp;<BR><SPAN class="keyword">inline</SPAN>&nbsp;<SPAN class="type">OZ_Boolean</SPAN>&nbsp;<SPAN class="functionname">OZ_isCelloid</SPAN>(<SPAN class="type">OZ_Term</SPAN>&nbsp;<SPAN class="variablename">t</SPAN>)<BR>{<BR>&nbsp;&nbsp;t&nbsp;=&nbsp;OZ_deref(t);<BR>&nbsp;&nbsp;<SPAN class="keyword">return</SPAN>&nbsp;OZ_isExtension(t)&nbsp;&amp;&amp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;OZ_getExtension(t)-&gt;getIdV()==<SPAN class="reference">Celloid</SPAN>::id;<BR>}<BR>&nbsp;<BR><SPAN class="functionname">OZ_BI_define</SPAN>(celloid_is,1,1)<BR>{<BR>&nbsp;&nbsp;OZ_declareDetTerm(0,t);<BR>&nbsp;&nbsp;OZ_RETURN_BOOL(OZ_isCelloid(t));<BR>}<BR>OZ_BI_end</CODE></DD></DL><P></P><H2><A name="label65">17.4 Expecting Celloid Arguments in Builtins</A></H2><P>Again this is similar to the <SPAN class="ignore"><CODE><SPAN class="keyword">class</SPAN>&nbsp;</CODE></SPAN><CODE><SPAN class="type">Counter</SPAN></CODE> class: we define an unboxing function and a convenience macro. </P><DL class="anonymous"><DD class="code"><CODE><SPAN class="keyword">inline</SPAN>&nbsp;<SPAN class="type">Celloid</SPAN>*&nbsp;<SPAN class="functionname">OZ_CelloidToC</SPAN>(<SPAN class="type">OZ_Term</SPAN>&nbsp;<SPAN class="variablename">t</SPAN>)<BR>{<BR>&nbsp;&nbsp;<SPAN class="keyword">return</SPAN>&nbsp;(<SPAN class="type">Celloid</SPAN>*)&nbsp;OZ_getExtension(OZ_deref(t));<BR>}<BR>&nbsp;<BR>#define&nbsp;<SPAN class="functionname">OZ_declareCelloid</SPAN>(<SPAN class="variablename">ARG</SPAN>,<SPAN class="variablename">VAR</SPAN>)&nbsp;\<BR>OZ_declareType(ARG,VAR,<SPAN class="type">Celloid</SPAN>*,<SPAN class="string">&quot;celloid&quot;</SPAN>,OZ_isCelloid,OZ_CelloidToC)</CODE></DD></DL><P></P><H2><A name="label66">17.5 Operations on Celloids</A></H2><P>First, we provide an <EM>access</EM> builtin that retrieves the content of the celloid. </P><DL class="anonymous"><DD class="code"><CODE><SPAN class="functionname">OZ_BI_define</SPAN>(celloid_access,1,1)<BR>{<BR>&nbsp;&nbsp;OZ_declareCelloid(0,c);<BR>&nbsp;&nbsp;OZ_RETURN(c-&gt;content);<BR>}<BR>OZ_BI_end</CODE></DD></DL><P> Second, we provide an <EM>assign</EM> builtin that sets the content of the celloid. This operation should only be allowed for a thread executing in the home space of the celloid. For a thread executing in a subordinated space, an exception will be raised. </P><DL class="anonymous"><DD class="code"><CODE><SPAN class="functionname">OZ_BI_define</SPAN>(celloid_assign,2,0)<BR>{<BR>&nbsp;&nbsp;OZ_declareCelloid(0,c);<BR>&nbsp;&nbsp;OZ_declareTerm(1,t);<BR>&nbsp;&nbsp;<SPAN class="keyword">if</SPAN>&nbsp;(c-&gt;isLocal())&nbsp;{&nbsp;c-&gt;content=t;&nbsp;<SPAN class="keyword">return</SPAN>&nbsp;PROCEED;&nbsp;}<BR>&nbsp;&nbsp;<SPAN class="keyword">else</SPAN>&nbsp;<SPAN class="keyword">return</SPAN>&nbsp;OZ_raiseErrorC(<SPAN class="string">&quot;celloid&quot;</SPAN>,3,OZ_atom(<SPAN class="string">&quot;nonLocal&quot;</SPAN>),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OZ_in(0),OZ_in(1));<BR>}<BR>OZ_BI_end</CODE></DD></DL><P> virtual member function <CODE>isLocal()</CODE> indicates whether the current space is the home space of the celloid. If yes, we set the content to the given argument; if no, we raise an error. <CODE>OZ_in(</CODE><I>n</I><CODE>)</CODE> refers to the <I>n</I>th input argument of the builtin.</P><H2><A name="label67">17.6 Printing Support</A></H2><P>We provide here only minimal printing support. </P><DL class="anonymous"><DD class="code"><CODE><SPAN class="type">OZ_Term</SPAN>&nbsp;<SPAN class="reference">Celloid</SPAN>::<SPAN class="functionname">printV</SPAN>(<SPAN class="type">int</SPAN>&nbsp;<SPAN class="variablename">depth</SPAN>&nbsp;=&nbsp;10)<BR>{<BR>&nbsp;&nbsp;<SPAN class="keyword">return</SPAN>&nbsp;OZ_atom(<SPAN class="string">&quot;&lt;celloid&gt;&quot;</SPAN>);<BR>}</CODE></DD></DL><P></P><H2><A name="label68">17.7 Garbage Collection</A></H2><P>The first part of garbage collection is as before: we create a new instance of <SPAN class="ignore"><CODE><SPAN class="keyword">class</SPAN>&nbsp;</CODE></SPAN><CODE><SPAN class="type">Celloid</SPAN></CODE> initialized with the current content of the celloid that is being copied by gc. </P><DL class="anonymous"><DD class="code"><CODE><SPAN class="type">OZ_Extension</SPAN>*&nbsp;<SPAN class="reference">Celloid</SPAN>::<SPAN class="functionname">gCollectV</SPAN>()&nbsp;{&nbsp;<SPAN class="keyword">return</SPAN>&nbsp;<SPAN class="keyword">new</SPAN>&nbsp;<SPAN class="type">Celloid</SPAN>(content);&nbsp;}</CODE></DD></DL><P> The second part involves recursively copying the content of the celloid. This is implemented in a different virtual function: </P><DL class="anonymous"><DD class="code"><CODE><SPAN class="type">void</SPAN>&nbsp;<SPAN class="reference">Celloid</SPAN>::<SPAN class="functionname">gCollectRecurseV</SPAN>()&nbsp;{&nbsp;OZ_gCollect(&amp;content);&nbsp;}</CODE></DD></DL><P> The procedure <CODE>OZ_gCollect(<SPAN class="type">OZ_Term</SPAN>*)</CODE> performs the gc copy and update of its argument.</P><P>You may wonder: why not perform the recursive copy of the content in <CODE>gCollectV()</CODE> itself. Under no circumstances should you do this! It would break essential invariants in the garbage collector. GC copy must proceed in these 2 phases: </P><OL type="1"><LI><P><CODE>gCollectV()</CODE> creates a new instance (on the <EM>to</EM> heap) and initializes it with the current contents of the object being gced. </P></LI><LI><P><CODE>gCollectRecurseV()</CODE> is at some subsequent point invoked on the new instance and should perform the gc copy and update of its contents.</P></LI></OL><P></P><H2><A name="label69">17.8 Cloning</A></H2><P>Cloning is used to produce a copy of a computation space. It has the same structure, and the underlying implementation in fact shares most of the code with, garbage collection. </P><DL class="anonymous"><DD class="code"><CODE><SPAN class="type">OZ_Extension</SPAN>*&nbsp;<SPAN class="reference">Celloid</SPAN>::<SPAN class="functionname">sCloneV</SPAN>()&nbsp;{&nbsp;<SPAN class="keyword">return</SPAN>&nbsp;<SPAN class="keyword">new</SPAN>&nbsp;<SPAN class="type">Celloid</SPAN>(content);&nbsp;}<BR><SPAN class="type">void</SPAN>&nbsp;<SPAN class="reference">Celloid</SPAN>::<SPAN class="functionname">sCloneRecurseV</SPAN>()&nbsp;{&nbsp;OZ_sClone(&amp;content);&nbsp;}</CODE></DD></DL><P> </P><H2><A name="label70">17.9 Native Functor</A></H2><P>Again, we proceed as before: </P><DL class="anonymous"><DD class="code"><CODE><SPAN class="type">OZ_C_proc_interface</SPAN>&nbsp;*&nbsp;<SPAN class="functionname">oz_init_module</SPAN>(<SPAN class="type">void</SPAN>)<BR>{<BR>&nbsp;&nbsp;<SPAN class="keyword">static</SPAN>&nbsp;<SPAN class="type">OZ_C_proc_interface</SPAN>&nbsp;<SPAN class="variablename">table</SPAN>[]&nbsp;=&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<SPAN class="string">&quot;new&quot;</SPAN>,1,1,celloid_new},<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<SPAN class="string">&quot;is&quot;</SPAN>,1,1,celloid_is},<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<SPAN class="string">&quot;access&quot;</SPAN>,1,1,celloid_access},<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<SPAN class="string">&quot;assign&quot;</SPAN>,2,0,celloid_assign},<BR>&nbsp;&nbsp;&nbsp;&nbsp;{0,0,0,0}<BR>&nbsp;&nbsp;};<BR>&nbsp;&nbsp;<SPAN class="reference">Celloid</SPAN>::id&nbsp;=&nbsp;OZ_getUniqueId();<BR>&nbsp;&nbsp;<SPAN class="keyword">return</SPAN>&nbsp;table;<BR>}</CODE></DD></DL><P> Assuming the code above is put in file <A href="celloid.cc"><CODE>celloid.cc</CODE></A>, we first compile and then create a DLL as follows </P><BLOCKQUOTE class="code"><CODE>oztool&nbsp;c++&nbsp;-c&nbsp;celloid.cc<BR>oztool&nbsp;ld&nbsp;celloid.o&nbsp;-o&nbsp;celloid.so-`oztool&nbsp;platform`</CODE></BLOCKQUOTE><P></P><H2><A name="label71">17.10 Oz Wrapper Module</A></H2><P>Here, we hardly need an Oz wrapper module. Unlike for counter objects, we don't need to register celloid for finalization: there are no resources off the heap. However, we can provide a nice error print formatter for the case when an access is attempted from without the celloid's home space. </P><DL class="anonymous"><DD class="code"><CODE><SPAN class="keyword">functor</SPAN>&nbsp;<BR><SPAN class="keyword">import</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;Celloid(new:New&nbsp;is:Is&nbsp;access:Access&nbsp;assign:Assign)<BR>&nbsp;&nbsp;&nbsp;<SPAN class="keyword">at</SPAN>&nbsp;<SPAN class="string">'celloid.so{native}'</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;Error(registerFormatter)<BR><SPAN class="keyword">export</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;New&nbsp;Is&nbsp;Access&nbsp;Assign<BR><SPAN class="keyword">define</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<SPAN class="keyword">fun</SPAN><SPAN class="variablename">&nbsp;</SPAN>{<SPAN class="functionname">CelloidFormatter</SPAN>&nbsp;E}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;=&nbsp;<SPAN class="string">'Celloid&nbsp;Error'</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<SPAN class="keyword">in</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="keyword">case</SPAN>&nbsp;E&nbsp;<SPAN class="keyword">of</SPAN>&nbsp;celloid(nonLocal&nbsp;C&nbsp;V)&nbsp;<SPAN class="keyword">then</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;error(kind:&nbsp;T<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg:&nbsp;<SPAN class="string">'Attempted&nbsp;assign&nbsp;on&nbsp;non&nbsp;local&nbsp;celloid'</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;items:&nbsp;[hint(l:<SPAN class="string">'Operation'</SPAN>&nbsp;m:<SPAN class="string">'Celloid.assign'</SPAN>)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hint(l:<SPAN class="string">'Celloid'</SPAN>&nbsp;&nbsp;&nbsp;m:oz(C))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hint(l:<SPAN class="string">'Value'</SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m:oz(V))])<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="keyword">else</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;error(kind:&nbsp;T<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;items:&nbsp;[line(oz(E))])<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="keyword">end</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<SPAN class="keyword">end</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;{Error<SPAN class="keyword">.</SPAN>registerFormatter&nbsp;celloid&nbsp;CelloidFormatter}<BR><SPAN class="keyword">end</SPAN></CODE></DD></DL><P></P></DIV><TABLE align="center" border="0" cellpadding="6" cellspacing="6" class="nav"><TR bgcolor="#DDDDDD"><TD><A href="node21.html#chapter.counter.object">&lt;&lt; Prev</A></TD><TD><A href="node19.html">- Up -</A></TD></TR></TABLE><HR><ADDRESS><A href="http://www.ps.uni-sb.de/~duchier/">Denys&nbsp;Duchier</A>, <A href="http://www.ps.uni-sb.de/~kornstae/">Leif&nbsp;Kornstaedt</A> and&nbsp;<A href="http://www.ps.uni-sb.de/~schulte/">Christian&nbsp;Schulte</A><BR><SPAN class="version">Version 1.4.0 (20090610)</SPAN></ADDRESS></BODY></HTML>