<aspect xmlns:cpp="http://www.sdml.info/srcML/cpp" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://control.ee.ethz.ch/XWeaver/AspectX" xmlns:src="http://www.sdml.info/srcML/src" xsi:schemaLocation="http://control.ee.ethz.ch/XWeaver/AspectX ../../../../src/xsd/aspectX.xsd" name="PassiveToSporadic">
        
<description>
          This sample aspect transforms passive classes into active (sporadic) classes. 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 apsect demonstrates how to turn a passive class into a 
<i>sporadic class</i> i.e. a class with its own
      thread of execution that is triggered by some external entity.
      
<p />
      This aspect operates on base code that sporadically calls 
<code>activate()</code> method 
      of class 
<code>Task</code>. These calls are invoked from the function 
      
<code>scheduler()</code> which acts as a source of sporadic triggers.
      
<p />
      The aspect replaces the original 
<code>activate()</code> function defined in the passive class
      by the a new function 
<code>_activate()</code>. This function contain an infinite loop. 
      On every cycle the 
<i>condition variable</i> <code>trigger</code> is checked. If 
      it has a zero value the execution of the thread is suspended until the value of the 
      
<code>trigger</code> variable is non-zero. On release the original function 
      
<code>activate()</code> is called. At the end of every cycle the value of the trigger is set back to 
      zero. 
      
<p />
      Since the trigger acts act as a 
<i>condition variable</i> it has to be protected
      against access by more then one thread at the same time. The protection 
      if this critical section is implemented using 
<code>mutex</code> object.    
        
<p />
      The aspect also replaces the body of the original 
<code>scheduler()</code> function
      by function 
<code>_scheduler()</code>.
      It creates and runs the thread of the 
<code>Task</code> object. It also emulates
      two sporadic events by setting up the 
<code>trigger</code> to non-zero values.
        
<p />
      The activation code uses synchronization primitives provided by the POSIX standard.
                
<author>A. Pasetti, O. Rohlik</author>
                
<see>PassiveToCyclical</see>
                
<see>Entry</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 'main'. 
        
</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 the target class to which the declaration of the 
<code>_activate()</code> method
                        should be added. The class that must be modified is identified by its full name: 
<code>Task</code>.
                
</description>
        
</pointcut>

    
<pointcut name="targetTaskClassDefinition" type="src:unit">
                
<description>
            Points to the target unit where is defined class 
<code>Task</code>.
        
</description>
        
<restriction type="isDefinitionOf">
            
<pointcutRef ref="targetTaskClassDeclaration" type="src:class" />
        
</restriction>
    
</pointcut>

        
        
        
<advice type="add" name="addSynchronizationDefinition">
            
<description>
                Adds declaration and initialization of three variables 
                needed to implement the mutual exclusive access
                to the condition variable 
<code>trigger</code>.
            
<p />            
            This advice has to precede other advices that modify code
            in the main unit.
        
</description>
                
<pointcutRef ref="targetInitializationUnit" type="src:unit" />
                
<codeModifier type="declaration">
                    
<text>pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;</text>
                    
<text>pthread_cond_t condvar=PTHREAD_COND_INITIALIZER;</text>
                    
<text>int trigger = 0;</text>
                    
<text />
                
</codeModifier>
        
</advice>
        
        
<advice type="add" name="addSynchronizationDeclaration">
            
<description>
                Adds 
<i>external</i> declaration of three variables 
                needed to implement the mutual exclusive access
                to the condition variable 
<code>trigger</code>.
        
</description>
                
<pointcutRef ref="targetTaskClassDefinition" type="src:unit" />
                
<codeModifier type="definition">
                    
<text>extern pthread_mutex_t mutex;</text>
                    
<text>extern pthread_cond_t condvar;</text>
                    
<text>extern int trigger;</text>
                
</codeModifier>
        
</advice>
        
        
<advice name="addSporadicActivateDeclaraion" type="add">
        
<description>
            Add declaration of 
<code>_activate()</code> method to the class declaration. 
            This method is to be called as a POSIX thread. Therefore its
            return value must be a pointer (
<code>void *</code>) and must 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="addSporadicActivateDefinition" type="add">
        
<description>
             Add definition of 
<code>_activate()</code> method to class definition files. 
            
<p />
            The method body contains an infinite loop. The 
<code>activate()</code> method of the 
            same class is called if the condition variable has non-zero value.
        
</description>
            
<pointcutRef ref="targetTaskClassDefinition" type="src:unit" />
            
<codeModifier type="definition">
                
<accessModifier type="public" /><text> 
void * Task::_activate(void * param){
        
        cout &lt;&lt;  "Sporadic task running..." &lt;&lt; endl;
        while(1) {
                pthread_mutex_lock(&amp;mutex);
                while (!trigger) { // non-zero value == do action, otherwise wait
                        pthread_cond_wait(&amp;condvar,&amp;mutex); // waits for notification 
                }
                cout &lt;&lt; endl &lt;&lt; "Sporadic task triggered..." &lt;&lt; endl;
                activate();
                cout &lt;&lt; "Sporadic task waiting for next trigger..." &lt;&lt; endl;
                trigger=0; // it is over, trigger is set back to zero
                pthread_cond_signal(&amp;condvar); // notify others that trigger is available
                pthread_mutex_unlock(&amp;mutex);  // release mutex
        }

</text>
      
</codeModifier>
        
</advice>
        
        
<advice name="addActivationHelperFunctions" type="add">
            
<description>
                Adds definition of helper a function 
                
<code>_activate()</code> to tha main program unit. This function
                activates the thread of a sporadic object. It 
                passes the call to the 
<code>_activate()</code> method of the object 
                
<code>task</code> - an instance of class <code>Task</code>.
                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 * _activate(void * param) {
        return task._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 signature of function
            
<code>_activate()</code> which is inserted to the main module. Since 
            function is woven at the end of the file its 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 the code that
                initialize the thread of an active object, emulates
                two sporadic events by setting the 
<code>trigger</code>
                variable to non-zero value, and suspend the 
                execution of the main thread. 
                
<p />
                he threads are executed using helper functions 
                
<code>_activate()</code> 
                that passes the call to the 
<code>_activate()</code> method 
                defined in the class 
<code>Task</code>
            
</description>
        
<pointcutRef ref="targetSchedulerMethodBody" type="src:block" />
            
<codeModifier type="codeFragment"><text>int retcode;
pthread_t a;
void * retval;

cout &lt;&lt; "Scheduler starts, it triggers the sporadic task in t=0+2 and t=0+5 " &lt;&lt; endl;

retcode = pthread_create(&amp;a, NULL, _activate, NULL);
if (retcode != 0) cerr &lt;&lt; "Create failed " &lt;&lt; retcode &lt;&lt; endl;
cout &lt;&lt; "Sporadic class activated, waiting for external trigger (it will come in 2 seconds) " &lt;&lt; endl;
MicroTime::microSleep(2000000);

pthread_mutex_lock(&amp;mutex);
trigger = 1; // set up condvar to non-zero value
pthread_cond_signal(&amp;condvar); 
pthread_mutex_unlock(&amp;mutex);
pthread_cond_signal(&amp;condvar);
    
MicroTime::microSleep(3000000); // another activation comes after 3 seconds

pthread_mutex_lock(&amp;mutex);
trigger = 2; // set up condvar to non-zero value
pthread_cond_signal(&amp;condvar);
pthread_mutex_unlock(&amp;mutex);
pthread_cond_signal(&amp;condvar);

retcode = pthread_join(a, &amp;retval);
if (retcode != 0) cerr &lt;&lt; "Join failed " &lt;&lt; retcode &lt;&lt; endl;
return 0; 
</text></codeModifier>
        
</advice>
             
</aspect>






































v