<aspect xmlns:src="http://www.sdml.info/srcML/src" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:cpp="http://www.sdml.info/srcML/cpp" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://control.ee.ethz.ch/XWeaver/AspectX" xsi:schemaLocation="http://control.ee.ethz.ch/XWeaver/AspectX ../../../../src/xsd/aspectX.xsd" name="PassiveToCyclical">
        
<description>
          This sample aspect transforms passive classes into active classes with cyclical activation. A 
<i>passive class</i> 
      is a class whose object instances do not
      have their own execution thread. An 
<i>active class</i> is instead a class whose instances 
      have an execution thread associated to them.
      This aspect demonstrates how to turn a passive class into a 
<i>cyclical class</i> i.e. a class with its own
      thread of execution that is activated on a cyclical basis.
      
<p />
      The base code upon which the aspect operates is a small but self-contained application.
      This application consists of the following four classes: 
<code>main</code>
      
<code>MicroTime</code><code>Task1</code>, and <code>Task2</code>. The two task classes 
      are the classes that are initially passive and that must be provided with activation code.
      These two classes expose a method called 
<code>activate</code>. This is the method through 
      which the classes should be activated.
      
<p />
      The 
<code>main</code> class contains a small main program that consists of an endless loop
      that, at every iteration, calls the 
<code>activate</code> methods on the two task classes.
      
<p />
      The 
<code>MicroTime</code> class is just a helper class that encapsulates access to timing service.
      This class is not affected by the aspect transformation.
      
<p />
      The most important transformations performed by aspect program are:
<ul>
      
<li>In each task class, the aspect transformation adds a new method called <code>_activate</code>. This
      method consists of an endless loop that calls the pre-existing 
<code>activate</code> method and then
      suspends itself for the duration of one activation cycle. Normally the 
<code>sleep_until()</code> function 
      should be used to suspend the execution of the task. Unfortunately this function is not 
      always supported by underlaying operating system. Hence we use a 
<code>sleep()</code> function to demonstrate 
      the implementation
      of the aspect. In this example 
<code>microSleep()</code> is used to achieve higher timing precision.
      
</li>
      
<li>In the main class, the aspect transformation replaces the code that calls the <code>activate</code>
      methods of the two task class with code that creates and starts two threads whose entry points are
      the new 
<code>_activate</code> methods.</li>
      
</ul>
      In all cases, the activation code uses synchronization primitives provided by the POSIX standard. This as
      also the reason why 
<code>sleep()</code> function is used instead of <code>sleep_until()</code>.
                
<author>A. Pasetti, O. Rohlik</author>
                
<see>PassiveToSporadic</see>
        
</description>
        
         
<pointcut name="targetInitializationUnit" type="src:unit">
                
<description>
                    Points to the 
<code>unit</code> that contains <code>main()</code> method. In srcML, a <code>unit</code> is 
                    a source file (a definition file, a declaration file, or
                        an inline file). The pointcut is restricted to include only those units that contain
                        function whose full name is 
<code>main</code>
        
</description>
        
<restriction type="contain">
            
<pointcut type="src:function" constraint="src:name='main'" />
        
</restriction>
        
</pointcut>
        
        
<pointcut name="targetSchedulerMethodBody" type="src:block" constraint="../src:name='scheduler' and ../src:block[1]"> 
                
<description>Points to the body of the function <code>scheduler()</code>
            
</description>
        
</pointcut>

        
<pointcut name="targetTaskClassDeclaration" type="src:class" constraint="contains(src:name,'Task')">
                
<description>
                        Points to target classes to which declarations of 
<code>_activate()</code> method
                        should be added. 
                        The classes that must be modified are identified by their full name. The name
                        have to contain substring 
<code>Task</code>.
                
</description>
        
</pointcut>

    
<pointcut name="targetTaskClassDefinition" type="src:unit">
                
<description>
            Points to the target units where are definitions of methods classes identified 
            by pointcut 
<code>targetTaskClassDeclaration</code>
        
</description>
        
<restriction type="isDefinitionOf">
            
<pointcutRef ref="targetTaskClassDeclaration" type="src:class" />
        
</restriction>
    
</pointcut>

        
<advice name="addCyclicalActivateDeclaraion" type="add">
        
<description>
            Add declaration of the 
<code>_activate()</code> method to the class declaration. 
            This method is to be called as a POSIX thread. Therefore its
            return value has to be a pointer (
<code>void *</code>) and has to have 
            one untyped pointer as a parameter. 
        
</description>
            
<pointcutRef ref="targetTaskClassDeclaration" type="src:class" />
            
<codeModifier type="declaration">
                
<accessModifier type="public" />
                
<text>void * _activate(void * param); // added by aspect </text>
            
</codeModifier>
        
</advice>
        
        
<advice name="addCyclicalActivateDefinition" type="add">
        
<description>
             Add definition of 
<code>_activate()</code> method to class definition files. 
             The full name of the method is constructed using 
<i>dollar variable</i> 
            
<code>${className}</code>.
            
<p />
            The method body contains a loop that call the 
<code>activate()</code> method of the 
            same class with period of 7 seconds. The 
<code>activate()</code> method
            is called at the beginning of the loop.             
            After the method call the thread is suspended for time remaining to the 
            end of the period. 
        
</description>
            
<pointcutRef ref="targetTaskClassDefinition" type="src:unit" />
            
<codeModifier type="definition">
                
<accessModifier type="public" />
                
<text>void * ${className}::_activate(void * param) {</text>
                
<text>    unsigned long tSchedulerStart, tLoopStart, cycle; //, tLoopEnd;</text>
                
<text />
                
<text>    cycle = 7000000ul;</text>
                
<text>    tSchedulerStart = MicroTime::getMicroTime();</text>
                
<text>    while (1) {</text>
                
<text>            tLoopStart = MicroTime::getMicroTime();</text>
                
<text>             //cout &lt;&lt; "--------------------------------------------------------------------------------" &lt;&lt; endl; </text>
                
<text>             //cout &lt;&lt; "Scheduler starts new cycle (at time " &lt;&lt; MicroTime::getMicroTime()-tSchedulerStart &lt;&lt; " microseconds after the scheduler start)" &lt;&lt; endl; </text>
                
<text>            activate(); // this task takes 3 seconds</text>
                
<text>            MicroTime::microSleep(  cycle - (MicroTime::getMicroTime()-tLoopStart)  );</text>
                
<text>             //tLoopEnd = MicroTime::getMicroTime();  </text>
                
<text>             //cout &lt;&lt; endl &lt;&lt; "The loop took " &lt;&lt; (tLoopEnd-tLoopStart)/1000ul &lt;&lt; " miliseconds" &lt;&lt; endl; </text>
                
<text>    }</text>
                
<text>}</text>
            
</codeModifier>
        
</advice>
        
        
<advice name="addActivationHelperFunctions" type="add">
            
<description>
                Adds definition of two methods that
                activate the threads of active objects.
                The threads execution (in 
<code>pthread_create()</code>
                is associated with the two helper functions
                
<code>_activate1()</code> and <code>_activate2()</code> that
                pass the calls to the respective methods in classes 
                
<code>Task1</code> and <code>Task2</code>
                These helper functions are used because POSIX function 
                
<code>pthread_create()</code> does not allow
                to use 
<i>C++ method</i> 
                as a parameter - only 
<i>C functions</i> are accepted.
            
</description>
            
<pointcutRef ref="targetInitializationUnit" type="src:unit" />
            
<codeModifier type="definition"><text> 
void * _activate1(void * param) {
        return task1._activate(param);
}

void * _activate2(void * param) {
        return task2._activate(param);

</text></codeModifier>
        
</advice>
        
        
<advice type="add" name="addIncludesToMain">
            
<description>
                Add the 
<code>#include "main.h"</code> preprocessor instruction.
            Header file 
<code>main.h</code> contains signatures of two functions 
            (
<code>_activate1()</code> and <code>_activate2()</code>
            added to the main module. Since 
            both functions are woven at the end of the file their declarations have to 
            be inserted at the beginning of the unit using the header file.
        
</description>
                
<pointcutRef ref="targetInitializationUnit" type="src:unit" />
                
<codeModifier type="include">
                    
<text>#include "main.h" // added by aspect </text>
                
</codeModifier>
        
</advice>
        
    
<advice name="replaceSchedulerBody" type="around">
        
<description>
            Replaces the body of 
<code>schedule()</code> function.
            It inserts code that
                initializes the two threads and suspends the execution of the 
                main thread. 
                
<p />
                The threads are executed using helper functions
                
<code>_activate1()</code> and <code>_activate2()</code> that
                pass the calls to the respective methods in classes 
                
<code>Task1</code> and <code>Task2</code>
        
</description>
        
<pointcutRef ref="targetSchedulerMethodBody" type="src:block" />
            
<codeModifier type="codeFragment"><text>int retcode;
pthread_t a, b;
void * retval;
    
retcode = pthread_create(&amp;a, NULL, _activate1, NULL);
if (retcode != 0) fprintf(stderr, "create a failed %d\n", retcode);
MicroTime::microSleep( 4000000 ); // task2 is about to start at t = 0+4 sec
retcode = pthread_create(&amp;b, NULL, _activate2, NULL);
if (retcode != 0) fprintf(stderr, "create b failed %d\n", retcode);
retcode = pthread_join(a, &amp;retval);
if (retcode != 0) fprintf(stderr, "join a failed %d\n", retcode);
retcode = pthread_join(b, &amp;retval);
if (retcode != 0) fprintf(stderr, "join b failed %d\n", retcode);
return 0; 
</text></codeModifier>
        
</advice>

</aspect>






































v