UppaalInterpreter.cpp

Go to the documentation of this file.
00001 /** @file UppaalInterpreter.cpp
00002 * @author Gabor Madl
00003 * @date Created 07/2005
00004 * @brief This interpreter generates Uppaal XML input from the DREAM models.
00005 *
00006 *
00007 * =================================================================
00008 * DREAM License v2.0
00009 * 
00010 * DREAM - Distributed Real-time Embedded Analysis Method
00011 * http://dre.sourceforge.net.
00012 * Copyright (c) 2005-2007 Gabor Madl, All Rights Reserved.
00013 * 
00014 * This file is part of DREAM.
00015 * 
00016 * DREAM is free software; you can redistribute it and/or modify it
00017 * under the terms of the GNU General Public License version 2 as
00018 * published by the Free Software Foundation. No future versions of
00019 * the GPL license may be automatically applied to DREAM. It is in
00020 * the sole discretion of the copyright holder to determine whether
00021 * DREAM may be released under a different license or terms. There
00022 * are no restrictions on the use of DREAM for any purpose.
00023 * 
00024 * DREAM is distributed in the hope that it will be useful,
00025 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00026 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00027 * GNU General Public License for more details.
00028 * 
00029 * You should have received a copy of the GNU General Public License
00030 * along with this program; if not, write to the Free Software
00031 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00032 * MA 02110-1301, USA.
00033 * 
00034 * By submitting comments, suggestions, code, code snippets,
00035 * techniques (including that of usage), and algorithms, submitters
00036 * acknowledge that they have the right to do so, that any such
00037 * submissions are given freely and unreservedly, and that they
00038 * waive any claims to copyright or ownership. In addition,
00039 * submitters acknowledge that any such submission might become
00040 * part of the copyright maintained on the overall body of code,
00041 * which comprises DREAM. By making a submission, submitter agrees
00042 * to these terms. Furthermore, submitters acknowledge that the
00043 * incorporation or modification of such submissions is entirely
00044 * at the discretion of the moderators of the DREAM project.
00045 * 
00046 * DREAM links to the Libxml2 third party library. Please see 
00047 * COPYING-libxml for the copyright information of Libxml2.
00048 * =================================================================
00049 */
00050 
00051 #include "UppaalInterpreter.h"
00052 
00053 namespace DREAM
00054 {
00055 
00056 UppaalInterpreter::UppaalInterpreter (DREAM::System* system_ptr)
00057 : system_ptr_ (system_ptr)
00058 {
00059 }
00060 
00061 UppaalInterpreter::~UppaalInterpreter ()
00062 {
00063 }
00064 
00065 std::string UppaalInterpreter::create_fixedpriority_guard (NODE_MAP* node_map, std::string scheduler_id, const DREAM::Node* const node)
00066 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00067         throw (DREAM::Exception)
00068 #endif
00069 {
00070         uint k = 0;
00071         NODE_MAP::const_iterator node_iter;
00072         std::string output = "en[";
00073 
00074         for (node_iter = node_map->begin (); node_iter != node_map->end (); node_iter++)
00075         {
00076                 if ((node_iter->first) == node->id ())
00077                 {
00078                                 output << k << "]";
00079                 }
00080                 ++k;
00081         }
00082 
00083         k = 0;
00084         for (node_iter = node_map->begin (); node_iter != node_map->end (); node_iter++)
00085         {
00086                 if (node_iter->second->scheduler ()->id () == scheduler_id)
00087                 {
00088                         if (node_iter->second->priority () <= node->priority ())
00089                                 if ((node_iter->second->priority () < node->priority ()) ||
00090                                                  (node_iter->second->subpriority () < node->subpriority ()))
00091                                 {       
00092                                         output << " &amp;&amp; !en[" << k << "]";
00093                                 }
00094                 }
00095                 ++k;
00096         }
00097 
00098         return output;
00099 }
00100 
00101 bool UppaalInterpreter::highestpriority (DREAM::Node* node_ptr)
00102 {
00103         return node_ptr->scheduler ()->highestpriority (node_ptr);
00104 }
00105 
00106 bool UppaalInterpreter::lowestpriority (DREAM::Node* node_ptr)
00107 {
00108         return node_ptr->scheduler ()->lowestpriority (node_ptr);
00109 }
00110 
00111 void UppaalInterpreter::visitor_uppaal (char* outputFile)
00112 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00113         throw (DREAM::Exception)
00114 #endif
00115 {
00116         std::ofstream f_stream (outputFile, std::ios::app);
00117 
00118         f_stream << "<instantiation>\n";
00119 
00120         DREAM::NODE_MAP task_map;
00121         DREAM::NODE_MAP channel_map;
00122         DREAM::NODE_MAP timer_map;
00123 
00124         system_ptr_->visitor_map (&task_map, &channel_map, &timer_map);
00125 
00126         system_ptr_->visitor_uppaal (&task_map, &channel_map, &timer_map, f_stream);
00127 
00128         f_stream << "</instantiation>\n\n";
00129 
00130         f_stream << "<system>system \n";
00131         
00132         uint needcolon = false;
00133 
00134         NODE_MAP::const_iterator node_iter;
00135         for (node_iter = task_map.begin (); node_iter != task_map.end (); node_iter++)
00136         {
00137                 if (needcolon)
00138                         f_stream << ",\n" << node_iter->first;
00139                 else
00140                 {
00141                         f_stream << node_iter->first;
00142                         needcolon = true;
00143                 }
00144         }
00145 
00146         for (node_iter = channel_map.begin (); node_iter != channel_map.end (); node_iter++)
00147         {
00148                 if (needcolon)
00149                         f_stream << ",\n" << node_iter->first;
00150                 else
00151                 {
00152                         f_stream << node_iter->first;
00153                         needcolon = true;
00154                 }
00155         }
00156 
00157         for (node_iter = timer_map.begin (); node_iter != timer_map.end (); node_iter++)
00158         {
00159                 if (needcolon)
00160                         f_stream << ",\n" << node_iter->first;
00161                 else
00162                 {
00163                         f_stream << node_iter->first;
00164                         needcolon = true;
00165                 }
00166         }
00167 
00168         SCHEDULER_MAP::const_iterator scheduler_iter;
00169         const SCHEDULER_MAP* scheduler_map = system_ptr_->scheduler_map ();
00170 
00171         for (scheduler_iter = scheduler_map->begin (); scheduler_iter != scheduler_map->end (); scheduler_iter++)
00172         {
00173                 if (scheduler_iter->second->CPUs () > 0)
00174                 {
00175                         if (needcolon)
00176                                 f_stream << ",\n" << scheduler_iter->first;
00177                         else
00178                         {
00179                                 f_stream << scheduler_iter->first;
00180                                 needcolon = true;
00181                         }
00182                 }
00183         }
00184 
00185         f_stream << ";</system>\n</nta>\n";
00186 
00187         f_stream.close ();
00188 }
00189 
00190 void UppaalInterpreter::visitor_uppaaltemplate (char* outputFile)
00191 #ifdef DREAM_ENHANCED_EXCEPTION_CHECKING
00192         throw (DREAM::Exception)
00193 #endif
00194 {
00195         // This is a somewhat ugly implementation. Anyone feel like rewriting it?
00196         // Gabe
00197 
00198         std::cout << "\nGenerating UPPAAL input \"" << outputFile << "\"...\n\n";
00199 
00200         uint i, j, k, l;
00201 
00202         DREAM::NODE_MAP task_map;
00203         DREAM::NODE_MAP channel_map;
00204         DREAM::NODE_MAP timer_map;
00205 
00206         std::ofstream f_stream (outputFile, std::ios::trunc);
00207 
00208         system_ptr_->visitor_map (&task_map, &channel_map, &timer_map);
00209 
00210         f_stream << "<?xml version=\"1.0\"?>\n\n"
00211                 << "<!--\n"
00212                 << "=================================================================\n"
00213                 << "DREAM License v2.0\n"
00214                 << "\n"
00215                 << "DREAM - Distributed Real-time Embedded Analysis Method\n"
00216                 << "http://dre.sourceforge.net.\n"
00217                 << "Copyright (c) 2005-2007 Gabor Madl, All Rights Reserved.\n"
00218                 << "\n"
00219                 << "This file is part of DREAM.\n"
00220                 << "\n"
00221                 << "DREAM is free software; you can redistribute it and/or modify it\n"
00222                 << "under the terms of the GNU General Public License version 2 as\n"
00223                 << "published by the Free Software Foundation. No future versions of\n"
00224                 << "the GPL license may be automatically applied to DREAM. It is in\n"
00225                 << "the sole discretion of the copyright holder to determine whether\n"
00226                 << "DREAM may be released under a different license or terms. There\n"
00227                 << "are no restrictions on the use of DREAM for any purpose.\n"
00228                 << "\n"
00229                 << "DREAM is distributed in the hope that it will be useful,\n"
00230                 << "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00231                 << "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
00232                 << "GNU General Public License for more details.\n"
00233                 << "\n"
00234                 << "You should have received a copy of the GNU General Public License\n"
00235                 << "along with this program; if not, write to the Free Software\n"
00236                 << "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, \n"
00237                 << "MA 02110-1301, USA.\n"
00238                 << "\n"
00239                 << "By submitting comments, suggestions, code, code snippets,\n"
00240                 << "techniques (including that of usage), and algorithms, submitters\n"
00241                 << "acknowledge that they have the right to do so, that any such\n"
00242                 << "submissions are given freely and unreservedly, and that they\n"
00243                 << "waive any claims to copyright or ownership. In addition,\n"
00244                 << "submitters acknowledge that any such submission might become\n"
00245                 << "part of the copyright maintained on the overall body of code,\n"
00246                 << "which comprises DREAM. By making a submission, submitter agrees\n"
00247                 << "to these terms. Furthermore, submitters acknowledge that the\n"
00248                 << "incorporation or modification of such submissions is entirely\n"
00249                 << "at the discretion of the moderators of the DREAM project.\n"
00250                 << "\n"
00251                 << "DREAM links to the Libxml2 third party library. Please see\n"
00252                 << "COPYING-libxml for the copyright information of Libxml2.\n"
00253                 << "=================================================================\n-->" 
00254                 << "\n" << std::endl
00255 
00256         << "<!DOCTYPE nta PUBLIC \"-//Uppaal Team//DTD Flat System 1.0//EN\" "
00257         << "\"http://www.docs.uu.se/docs/rtmv/uppaal/xml/flat-1_0.dtd\">\n"
00258         << "<nta>\n<declaration>\nint isidle[";
00259 
00260         uint numberoftasks = task_map.size ();
00261 
00262         f_stream << numberoftasks << "] := {";
00263 
00264         for (i = 1; i <= numberoftasks; i++)
00265         {
00266                 if (i != numberoftasks)
00267                         f_stream << "1, ";
00268                 else
00269                         f_stream << "1";
00270         }
00271 
00272         f_stream << "};\nint en[";
00273 
00274         f_stream << numberoftasks << "] := {";
00275 
00276         for (i = 1; i <= numberoftasks; i++)
00277         {
00278                 if (i != numberoftasks)
00279                         f_stream << "0, ";
00280                 else
00281                         f_stream << "0";
00282         }
00283 
00284         f_stream << "};\nint ";
00285 
00286         uint CPUs = system_ptr_->CPUs ();
00287 
00288         for (i = 1; i <= CPUs; i++)
00289         {
00290                 if (i != CPUs)
00291                         f_stream << "w" << i << " := 0, ";
00292                 else
00293                         f_stream << "w" << i << " := 0;\nclock globalclock;\n\n";
00294         }
00295 
00296         f_stream << "broadcast chan preempt, nullsink, nullsource";
00297 
00298         // Preempt from global to local
00299         SCHEDULER_MAP::const_iterator scheduler_iter;
00300         const SCHEDULER_MAP* scheduler_map = system_ptr_->scheduler_map ();
00301 
00302         i = 1;
00303 
00304         for (scheduler_iter = scheduler_map->begin (); scheduler_iter != scheduler_map->end (); scheduler_iter++)
00305         {
00306                 if (scheduler_iter->second->CPUs () > 0)
00307                 {
00308                         f_stream << ", preempt" << scheduler_iter->first;
00309                         ++i;
00310                 }
00311         }
00312 
00313         NODE_MAP::const_iterator node_iter;
00314 
00315         for (node_iter = timer_map.begin (); node_iter != timer_map.end (); node_iter++)
00316         {
00317                 f_stream << ", publish" << node_iter->first << "\n";
00318         }
00319 
00320         for (node_iter = task_map.begin (); node_iter != task_map.end (); node_iter++)
00321         {
00322                 f_stream << ", start" << node_iter->first << ", publish" << node_iter->first << ", run" << node_iter->first << "\n";
00323         }
00324 
00325         for (node_iter = channel_map.begin (); node_iter != channel_map.end (); node_iter++)
00326         {
00327                 f_stream << ", publish" << node_iter->first << "\n";
00328         }
00329 
00330 
00331         f_stream.flush ();
00332 
00333         // Generate Timer template
00334 
00335         f_stream << ";\n</declaration>\n<template>\n<name x=\"5\" y=\"5\">Timer</name>\n<parameter x=\"5\" y=\"20\">"
00336                 << "const int&amp; period, const int&amp; bcperiod, broadcast chan&amp; publishi</parameter>\n<declaration>clock ce;</declaration>\n"
00337                 << "<location id=\"id40\" x=\"448\" y=\"352\">\n<name x=\"432\" y=\"368\">timer</name>\n<label kind=\"invariant\""
00338                 << " x=\"408\" y=\"384\">ce &lt;= period</label>\n</location>\n<init ref=\"id40\"/>\n<transition>\n<source "
00339                 << "ref=\"id40\"/>\n<target ref=\"id40\"/>\n<label kind=\"guard\" x=\"408\" y=\"264\">ce &gt;= bcperiod</label>\n"
00340                 << "<label kind=\"synchronisation\" x=\"424\" y=\"280\">publishi!</label>\n<label kind=\"assignment\" x=\"432\" "
00341                 << "y=\"296\">ce := 0</label>\n<nail x=\"416\" y=\"328\"/>\n<nail x=\"448\" y=\"320\"/>\n<nail x=\"480\" y=\"328\"/>\n"
00342                 << "</transition>\n</template>\n";
00343 
00344         // Generate Task template
00345 
00346         f_stream << "<template>\n<name x=\"5\" y=\"5\">Task</name>\n<parameter x=\"5\" y=\"20\">const int&amp; pid, const int&amp; wcet, const int&amp; bcet, const int&amp; dl, const int&amp; pr, "
00347                 << "broadcast chan&amp; release, broadcast chan&amp; start, broadcast chan&amp; finish, broadcast chan&amp; preempt</parameter>\n<declaration>clock ce;\nclock cd;\nint et;\nint pre;\n"
00348                 << "</declaration>\n\n<location id=\"id0\" x=\"-128\" y=\"-256\">\n<name x=\"-136\" y=\"-240\">idle</name>\n</location>"
00349                 << "\n\n<location id=\"id1\" x=\"-32\" y=\"-352\">\n<name x=\"-40\" y=\"-344\">run</name>\n<label kind=\"invariant\" "
00350                 << "x=\"-56\" y=\"-328\">ce &lt;= pr</label>\n</location>\n\n<location id=\"id2\" x=\"64\" y=\"-448\">\n<name x=\"48\" "
00351                 << "y=\"-480\">error</name>\n<committed/>\n</location>\n\n<location id=\"id3\" x=\"64\" y=\"-256\">\n<name x=\"48\" "
00352                 << "y=\"-240\">wait</name>\n</location><location id=\"id18\" x=\"-80\" y=\"-304\">\n<name x=\"-128\" y=\"-320\">send</name>"
00353                 << "\n<committed/>\n</location>\n\n<location id=\"id4\" x=\"-128\" y=\"-448\">\n<name x=\"-138\" y=\"-478\">pass</name>\n"
00354                 << "<committed/>\n</location>\n<init ref=\"id0\"/>\n\n<transition>\n<source ref=\"id1\"/>\n<target ref=\"id3\"/>\n"
00355                 << "<label kind=\"synchronisation\" x=\"-8\" y=\"-352\">preempt?</label>\n<label kind=\"assignment\" x=\"8\" y=\"-336\">pre "
00356                 << "+= pr</label>\n<nail x=\"24\" y=\"-312\"/>\n</transition>\n\n<transition>\n<source ref=\"id3\"/>\n<target ref=\"id1\"/>"
00357                 << "\n<label kind=\"assignment\" x=\"-40\" y=\"-296\">ce := 0</label>\n<label kind=\"synchronisation\" x=\"-40\" "
00358                 << "y=\"-312\">start?</label>\n<nail x=\"16\" y=\"-296\"/>\n</transition>\n\n<transition>\n<source ref=\"id0\"/>\n"
00359                 << "<target ref=\"id3\"/>\n<label kind=\"synchronisation\" x=\"-64\" y=\"-272\">release?</label>\n<label kind=\"assignment\" "
00360                 << "x=\"-88\" y=\"-256\">cd := 0, en[pid] := 1,\net := 0, pre := 0</label>\n</transition>\n\n<transition>\n"
00361                 << "<source ref=\"id3\"/>\n<target ref=\"id2\"/>\n<label kind=\"guard\" x=\"0\" y=\"-392\">cd &gt;= dl - pre</label>\n"
00362                 << "<nail x=\"56\" y=\"-352\"/>\n</transition>\n\n<transition>\n<source ref=\"id3\"/>\n<target ref=\"id2\"/>\n"
00363                 << "<label kind=\"synchronisation\" x=\"-8\" y=\"-376\">release?</label>\n<nail x=\"72\" y=\"-352\"/>\n</transition>\n\n"
00364                 << "<transition>\n<source ref=\"id1\"/>\n<target ref=\"id2\"/>\n<label kind=\"synchronisation\" x=\"-40\" "
00365                 << "y=\"-432\">release?</label>\n<nail x=\"8\" y=\"-408\"/>\n</transition>\n\n<transition>\n<source ref=\"id1\"/>\n"
00366                 << "<target ref=\"id2\"/>\n<label kind=\"guard\" x=\"-40\" y=\"-416\">cd &gt;= dl - pre</label>\n<nail x=\"16\" y=\"-392\"/>\n"
00367                 << "</transition>\n\n<transition>\n<source ref=\"id18\"/>\n<target ref=\"id0\"/>\n<label kind=\"synchronisation\" "
00368                 << "x=\"-160\" y=\"-288\">finish!</label>\n<label kind=\"assignment\" x=\"-160\" y=\"-304\">en[pid] := 0</label>\n"
00369                 << "</transition>\n\n<transition>\n<source ref=\"id1\"/>\n<target ref=\"id4\"/>\n<label kind=\"guard\" x=\"-160\" "
00370                 << "y=\"-416\">ce &gt;= pr&amp;&amp;\net + ce &lt; wcet&amp;&amp;\ncd &lt; dl - pre</label>\n<nail x=\"-80\" y=\"-392\"/>\n</transition>\n\n"
00371                 << "<transition>\n<source ref=\"id4\"/>\n<target ref=\"id1\"/>\n<label kind=\"assignment\" x=\"-88\" y=\"-456\">et += pr,\n"
00372                 << "ce := 0</label>\n<nail x=\"-72\" y=\"-408\"/>\n</transition>\n\n<transition>\n<source ref=\"id1\"/>\n<target ref=\"id18\"/>\n"
00373                 << "<label kind=\"guard\" x=\"-160\" y=\"-360\">et + ce &gt;= bcet - pre</label>\n<label kind=\"synchronisation\" x=\"-128\" "
00374                 << "y=\"-344\">start!</label>\n</transition>\n</template>\n\n";
00375 
00376         // Generate non-preemptive Task template
00377 
00378         f_stream << "<template>\n<name x=\"5\" y=\"5\">NonpTask</name>\n<parameter x=\"5\" y=\"20\">const int&amp; pid, const int&amp; wcet, const int&amp; bcet, const int&amp; dl, broadcast "
00379                 << "chan&amp; release, broadcast chan&amp; start, broadcast chan&amp; finish</parameter>\n<declaration>clock ce;\nclock cd;\n</declaration>\n\n<location id=\"id13\" "
00380                 << "x=\"-128\" y=\"-256\">\n<name x=\"-136\" y=\"-240\">idle</name>\n</location>\n\n<location id=\"id14\" x=\"-128\" "
00381                 << "y=\"-448\">\n<name x=\"-136\" y=\"-480\">run</name>\n<label kind=\"invariant\" x=\"-144\" y=\"-432\">ce &lt;= wcet</label>\n"
00382                 << "</location>\n\n<location id=\"id15\" x=\"64\" y=\"-448\">\n<name x=\"48\" y=\"-480\">error</name>\n<committed/>\n"
00383                 << "</location>\n\n<location id=\"id16\" x=\"64\" y=\"-256\">\n<name x=\"48\" y=\"-240\">wait</name>\n</location>\n\n"
00384                 << "<location id=\"id17\" x=\"-128\" y=\"-352\">\n<name x=\"-168\" y=\"-376\">send</name>\n<committed/>\n</location>\n"
00385                 << "<init ref=\"id13\"/>\n\n<transition>\n<source ref=\"id13\"/>\n<target ref=\"id16\"/>\n<label kind=\"synchronisation\" "
00386                 << "x=\"-64\" y=\"-256\">release?</label>\n<label kind=\"assignment\" x=\"-88\" y=\"-240\">cd := 0, en[pid] := 1</label>\n"
00387                 << "</transition>\n\n<transition>\n<source ref=\"id16\"/>\n<target ref=\"id15\"/>\n<label kind=\"guard\" x=\"0\" "
00388                 << "y=\"-392\">cd &gt;= dl</label>\n<nail x=\"56\" y=\"-352\"/>\n</transition>\n\n<transition>\n<source ref=\"id16\"/>\n"
00389                 << "<target ref=\"id15\"/>\n<label kind=\"synchronisation\" x=\"-8\" y=\"-376\">release?</label>\n<nail x=\"72\" y=\"-352\"/>\n"
00390                 << "</transition>\n\n<transition>\n<source ref=\"id14\"/>\n<target ref=\"id15\"/>\n<label kind=\"synchronisation\" x=\"-64\" "
00391                 << "y=\"-480\">release?</label>\n<nail x=\"-32\" y=\"-456\"/>\n</transition>\n\n<transition>\n<source ref=\"id14\"/>\n"
00392                 << "<target ref=\"id15\"/>\n<label kind=\"guard\" x=\"-56\" y=\"-440\">cd &gt;= dl</label>\n<nail x=\"-32\" y=\"-440\"/>\n"
00393                 << "</transition>\n\n<transition>\n<source ref=\"id16\"/>\n<target ref=\"id14\"/>\n<label kind=\"synchronisation\" x=\"-64\" "
00394                 << "y=\"-352\">start?</label>\n<label kind=\"assignment\" x=\"-64\" y=\"-336\">ce := 0</label>\n</transition>\n\n"
00395                 << "<transition>\n<source ref=\"id14\"/>\n<target ref=\"id17\"/>\n<label kind=\"guard\" x=\"-112\" y=\"-392\">ce &gt;= bcet&amp;&amp;\n"
00396                 << "cd &lt; dl</label>\n<label kind=\"synchronisation\" x=\"-112\" y=\"-408\">start!</label>\n</transition>\n\n"
00397                 << "<transition>\n<source ref=\"id17\"/>\n<target ref=\"id13\"/>\n<label kind=\"synchronisation\" x=\"-120\" "
00398                 << "y=\"-320\">finish!</label>\n<label kind=\"assignment\" x=\"-120\" y=\"-304\">en[pid] := 0</label>\n</transition>\n"
00399                 << "</template>\n\n";
00400 
00401         // Generate Channel template
00402 
00403         f_stream << "<template>\n<name x=\"5\" y=\"5\">Channel</name>\n<parameter x=\"5\" y=\"20\">const int&amp; delay, const int&amp; bcdelay, const int&amp; lambdac, "
00404                 << "const int&amp; pid, broadcast chan&amp; release, broadcast chan&amp; publish, broadcast chan&amp; finish</parameter>\n<declaration>clock ce;\nint bufferc := 0;</declaration>\n\n"
00405                 << "<location id=\"id6\" x=\"320\" y=\"448\">\n<name x=\"304\" y=\"464\">idle</name>\n</location>\n\n"
00406                 << "<location id=\"id8\" x=\"512\" y=\"448\">\n<name x=\"504\" y=\"464\">wait</name>\n<label kind=\"invariant\" x=\"536\" "
00407                 << "y=\"464\">ce &lt;= delay</label>\n</location>\n<init ref=\"id6\"/>\n\n<transition>\n<source ref=\"id8\"/>\n"
00408                 << "<target ref=\"id8\"/>\n<label kind=\"synchronisation\" x=\"504\" y=\"400\">release?</label>\n<label "
00409                 << "kind=\"assignment\" x=\"504\" y=\"416\">bufferc++</label>\n<nail x=\"552\" y=\"432\"/>\n<nail x=\"552\" y=\"464\"/>\n"
00410                 << "</transition>\n\n<transition>\n<source ref=\"id8\"/>\n<target ref=\"id6\"/>\n<label kind=\"guard\" x=\"344\" "
00411                 << "y=\"456\">!en[pid] &amp;&amp; ce &gt;= bcdelay</label>\n<label kind=\"synchronisation\" x=\"408\" y=\"472\">publish!</label>\n"
00412                 << "<label kind=\"assignment\" x=\"352\" y=\"472\">bufferc--</label>\n<nail x=\"416\" y=\"456\"/>\n</transition>\n\n"
00413                 << "<transition>\n<source ref=\"id8\"/>\n<target ref=\"id6\"/>\n<label kind=\"guard\" x=\"376\" y=\"408\">en[pid]&amp;&amp;\n"
00414                 << "ce &gt;= bcdelay</label>\n<nail x=\"416\" y=\"440\"/>\n</transition>\n\n<transition>\n<source ref=\"id6\"/>\n"
00415                 << "<target ref=\"id8\"/>\n<label kind=\"synchronisation\" x=\"352\" y=\"368\">release?</label>\n<label "
00416                 << "kind=\"assignment\" x=\"352\" y=\"384\">bufferc++, ce := 0</label>\n<nail x=\"352\" y=\"400\"/>\n<nail x=\"480\" "
00417                 << "y=\"400\"/>\n</transition>\n\n<transition>\n<source ref=\"id6\"/>\n<target ref=\"id6\"/>\n<label kind=\"guard\" "
00418                 << "x=\"256\" y=\"416\">bufferc == 0</label>\n<label kind=\"synchronisation\" x=\"256\" y=\"400\">finish?</label>\n"
00419                 << "<nail x=\"280\" y=\"432\"/>\n<nail x=\"280\" y=\"464\"/>\n</transition>\n\n<transition>\n<source ref=\"id6\"/>\n"
00420                 << "<target ref=\"id8\"/>\n<label kind=\"guard\" x=\"352\" y=\"512\">bufferc &gt; 0</label>\n<label "
00421                 << "kind=\"synchronisation\" x=\"352\" y=\"496\">finish?</label>\n<label kind=\"assignment\" x=\"432\" y=\"512\">"
00422                 << "ce := 0</label>\n<nail x=\"352\" y=\"496\"/><nail x=\"480\" y=\"496\"/>\n</transition>\n</template>\n\n";
00423  
00424         // Generate Buffer template (local channel with 0 delay)
00425 
00426         f_stream << "<template>\n<name x=\"5\" y=\"5\">Buffer</name>\n<parameter x=\"5\" y=\"20\">const int&amp; lambdac, const int&amp; pid, broadcast "
00427                 << "chan&amp; release, broadcast chan&amp; publish, broadcast chan&amp; finish</parameter>\n<declaration>int bufferc := 0;</declaration>\n\n<location id=\"id5\" "
00428                 << "x=\"320\" y=\"448\">\n<name x=\"320\" y=\"464\">idle</name>\n</location>\n\n<location id=\"id7\" x=\"512\" y=\"448\">\n"
00429                 << "<name x=\"496\" y=\"464\">wait</name>\n\n<committed/></location>\n<init ref=\"id5\"/>\n\n<transition>\n"
00430                 << "<source ref=\"id5\"/>\n<target ref=\"id7\"/>\n<label kind=\"synchronisation\" x=\"408\" y=\"360\">release?</label>\n"
00431                 << "<label kind=\"assignment\" x=\"360\" y=\"376\">bufferc++</label>\n<label kind=\"guard\" x=\"360\" y=\"360\">!en[pid]"
00432                 << "</label>\n<nail x=\"352\" y=\"400\"/><nail x=\"480\" y=\"400\"/>\n</transition>\n\n<transition>\n<source ref=\"id5\"/>\n"
00433                 << "<target ref=\"id5\"/>\n<label kind=\"guard\" x=\"280\" y=\"384\">bufferc == 0</label>\n<label kind=\"synchronisation\" "
00434                 << "x=\"280\" y=\"368\">finish?</label>\n<nail x=\"304\" y=\"408\"/><nail x=\"280\" y=\"432\"/>\n</transition>\n\n"
00435                 << "<transition>\n<source ref=\"id5\"/>\n<target ref=\"id7\"/>\n<label kind=\"guard\" x=\"360\" y=\"480\">bufferc &gt; "
00436                 << "0</label>\n<label kind=\"synchronisation\" x=\"360\" y=\"464\">finish?</label>\n<nail x=\"352\" y=\"496\"/>\n"
00437                 << "<nail x=\"480\" y=\"496\"/>\n</transition>\n\n<transition>\n<source ref=\"id7\"/>\n<target ref=\"id5\"/>\n"
00438                 << "<label kind=\"synchronisation\" x=\"408\" y=\"408\">publish!</label>\n<label kind=\"assignment\" x=\"360\" "
00439                 << "y=\"424\">bufferc--</label>\n<label kind=\"guard\" x=\"360\" y=\"408\">!en[pid]</label><nail x=\"416\" "
00440                 << "y=\"440\"/></transition>\n\n<transition>\n<source ref=\"id5\"/><target ref=\"id5\"/>\n<label kind=\"guard\" "
00441                 << "x=\"280\" y=\"496\">en[pid]</label>\n<label kind=\"synchronisation\" x=\"328\" y=\"496\">release?</label>\n"
00442                 << "<label kind=\"assignment\" x=\"280\" y=\"512\">bufferc++</label>\n<nail x=\"280\" y=\"464\"/>\n<nail x=\"304\" y=\"488\"/>\n"
00443                 << "</transition>\n\n<transition>\n<source ref=\"id7\"/>\n<target ref=\"id5\"/>\n<label kind=\"guard\" x=\"392\" "
00444                 << "y=\"448\">en[pid]</label>\n<nail x=\"416\" y=\"456\"/>\n</transition>\n</template>\n\n";
00445 
00446         // Generate the schedulers
00447         i = 1;
00448 
00449         for (scheduler_iter = scheduler_map->begin (); scheduler_iter != scheduler_map->end (); scheduler_iter++)
00450         {
00451                 if (scheduler_iter->second->CPUs () > 0)
00452                 {
00453                         j = 1;
00454                         // Generate idle and select states
00455                         f_stream << "<template>\n<name x=\"5\" y=\"5\">" << scheduler_iter->first
00456                                 << "</name>\n<parameter x=\"5\" y=\"20\"/>\n<declaration/>\n<location id=\"id" << i*50 + 100 << "\" x=\"128\" y=\"256\">\n"
00457                                 << "<name x=\"120\" y=\"272\">idle</name>\n</location>\n<location id=\"id" << i*50 + 100 + 1 << "\" x=\"320\" y=\"256\">\n"
00458                                 << "<name x=\"288\" y=\"272\">select</name>\n<urgent/>\n</location>\n";
00459 
00460                         for (node_iter = task_map.begin (); node_iter != task_map.end (); node_iter++)
00461                         {
00462                                 if (node_iter->second->scheduler ()->id () == scheduler_iter->first)
00463                                 {
00464                                         // Generate states
00465                                         if (!lowestpriority (node_iter->second))
00466                                         {
00467                                                 f_stream << "<location id=\"id" << i*50 + 100 + j*2 << "\" x=\"512\" y=\"" << j*96 + 160 << "\">\n"
00468                                                 << "<name x=\"460\" y=\"" << j*96 + 180 << "\">schedule" << node_iter->first << "</name>\n"
00469                                                 << "</location>\n<location id=\"id" << i*50 + 100 + j*2 + 1 << "\" x=\"416\" y=\"" << j*96 + 160 << "\">\n"
00470                                                 << "<committed/>\n</location>\n";
00471                                         }
00472                                         else
00473                                         {
00474                                         // We can apply some reductions here - corresponding transitions will change
00475                                                 f_stream << "<location id=\"id" << i*50 + 100 + j*2 << "\" x=\"512\" y=\"" << j*96 + 160 << "\">\n"
00476                                                 << "<name x=\"460\" y=\"" << j*96 + 180 << "\">schedule" << node_iter->first << "</name>\n"
00477                                                 << "</location>\n";
00478                                         }
00479 
00480                                         ++j;
00481                                 }
00482                         }
00483 
00484                         f_stream << "<init ref=\"id" << i*50 + 100 << "\"/>\n";
00485 
00486                         // Generate guard for no enabled task on processor
00487                         f_stream << "<transition>\n<source ref=\"id" << i*50 + 100 + 1 << "\"/>\n<target ref=\"id" << i*50 + 100 << "\"/>\n"
00488                                 << "<label kind=\"guard\" x=\"112\" y=\"288\">";
00489 
00490                         k = 0; l = 0;
00491 
00492                         for (node_iter = task_map.begin (); node_iter != task_map.end (); node_iter++)
00493                         {
00494                                 if (node_iter->second->scheduler ()->id () == scheduler_iter->first)
00495                                 {
00496                                         if (l != 0)
00497                                                 f_stream << " &amp;&amp; ";
00498                                         else
00499                                                 l = 1;
00500                                         f_stream << "!en[" << k << "]";
00501                                 }
00502                                 ++k;
00503                         }
00504 
00505                         f_stream << "</label>\n<nail x=\"224\" y=\"272\"/>\n</transition>\n";
00506                         // Generation complete
00507 
00508                         j = 1;
00509 
00510                         for (node_iter = task_map.begin (); node_iter != task_map.end (); node_iter++)
00511                         {
00512                                 if (node_iter->second->scheduler ()->id () == scheduler_iter->first)
00513                                 {
00514                                         // Generate transitions for states
00515                                         f_stream << "<transition>\n<source ref=\"id" << i*50 + 100 << "\"/>\n<target ref=\"id" << i*50 + 100 + 1 << "\"/>\n"
00516                                                 << "<label kind=\"synchronisation\" x=\"136\" y=\"" << j*96 + 124 << "\">";
00517 
00518                                         if (node_iter->second->get_source (&task_map, &channel_map, &timer_map) != NULL)
00519                                                 // We found an ancestor other than a Channel
00520                                                 f_stream << "publish" << node_iter->second->get_source (&task_map, &channel_map, &timer_map)->id ();
00521                                         else
00522                                                 // The ancestor is a Channel
00523                                                 f_stream << "start" << node_iter->first;
00524 
00525                                         f_stream << "?</label>\n<nail x=\"224\" y=\"" << j*96 + 160 << "\"/>\n</transition>\n";
00526 
00527                                         if (!lowestpriority (node_iter->second))
00528                                         {
00529                                                 f_stream << "<transition>\n<source ref=\"id" << i*50 + 100 + 1 << "\"/>\n<target ref=\"id" << i*50 + 100 + j*2 + 1 << "\"/>\n"
00530                                                 << "<label kind=\"guard\" x=\"320\" y=\"" << j*96 + 112 << "\">"
00531                                                 << create_fixedpriority_guard (&task_map, scheduler_iter->first, node_iter->second)
00532                                                 << "</label>\n<label kind=\"synchronisation\" x=\"320\" y=\"" << j*96 + 128 << "\">preempt" 
00533                                                 << scheduler_iter->first << "!</label>\n</transition>\n";
00534 
00535                                                 f_stream << "<transition>\n<source ref=\"id" << i*50 + 100 + 2*j+1 << "\"/>\n<target ref=\"id" << i*50 + 100 + j*2 << "\"/>\n"
00536                                                 << "<label kind=\"synchronisation\" x=\"464\" y=\"" << j*96 + 112 << "\">run" << node_iter->first 
00537                                                 << "!</label>\n</transition>\n";
00538                                         }
00539                                         else
00540                                         {
00541                                         // Corresponding transition reductions for state space reduction
00542                                                 f_stream << "<transition>\n<source ref=\"id" << i*50 + 100 + 1 << "\"/>\n<target ref=\"id" << i*50 + 100 + j*2 << "\"/>\n"
00543                                                 << "<label kind=\"guard\" x=\"320\" y=\"" << j*96 + 112 << "\">"
00544                                                 << create_fixedpriority_guard (&task_map, scheduler_iter->first, node_iter->second)
00545                                                 << "</label>\n<label kind=\"synchronisation\" x=\"320\" y=\"" << j*96 + 128 << "\">run" << node_iter->first 
00546                                                 << "!</label>\n<nail x=\"416\" y=\"" << j*96 + 160 << "\"/>\n</transition>\n";
00547                                         }
00548 
00549                                         f_stream << "<transition>\n<source ref=\"id" << i*50 + 100 + 2*j << "\"/>\n<target ref=\"id" << i*50 + 100 + 1 << "\"/>\n"
00550                                                 << "<label kind=\"synchronisation\" x=\"336\" y=\"" << j*96 + 168 << "\">run" << node_iter->first
00551                                                 << "?</label>\n<nail x=\"404\" y=\"" << j*96 + 184 << "\"/>\n</transition>\n";
00552 
00553                                         // Transitions for Timer preemptions
00554                                         k = 1;
00555                                         NODE_MAP::const_iterator node_iter2;
00556 
00557                                         // We can reduce some transitions here
00558                                         if (!highestpriority (node_iter->second))
00559                                         {
00560                                                 for (node_iter2 = timer_map.begin (); node_iter2 != timer_map.end (); node_iter2++)
00561                                                 {
00562                                                         // Create transition
00563                                                         if ((node_iter2->second->priority () < node_iter->second->priority ()) &&       // Smaller value = higher priority
00564                                                                  (node_iter2->second->scheduler () == node_iter->second->scheduler ())) // They are on the same processor
00565                                                         f_stream << "<transition>\n<source ref=\"id" << i*50 + 100 + 2*j << "\"/>\n<target ref=\"id" << i*50 + 100 + 1 << "\"/>\n"
00566                                                                 << "<label kind=\"synchronisation\" x=\"336\" y=\"" << j*96 + 5*k + 164 << "\">publish" << node_iter2->first
00567                                                                 << "?</label>\n<nail x=\"" << 404 - 5*k << "\" y=\"" << j*96 + 5*k + 184 << "\"/>\n</transition>\n";
00568                                                         ++k;
00569                                                 }
00570 
00571                                                 for (node_iter2 = task_map.begin (); node_iter2 != task_map.end (); node_iter2++)
00572                                                 {
00573                                                         // Create transition for preemptions
00574                                                         if ((node_iter2->second->priority () < node_iter->second->priority ()) &&       // Smaller value = higher priority
00575                                                                  (node_iter2->second->scheduler () == node_iter->second->scheduler ())) // They are on the same processor
00576                                                         {
00577                                                                 if (node_iter2->second->get_source (&task_map, &channel_map, &timer_map))
00578                                                                 // We found a higher priority Task initiated by a (possibly remote) Channel
00579                                                                 // This could cause preemptions...
00580                                                                 {
00581                                                                         f_stream << "<transition>\n<source ref=\"id" << i*50 + 100 + 2*j << "\"/>\n<target ref=\"id" << i*50 + 100 + 1 << "\"/>\n"
00582                                                                         << "<label kind=\"synchronisation\" x=\"336\" y=\"" << j*96 + 5*k + 164 << "\">start" << node_iter2->first
00583                                                                         << "?</label>\n<nail x=\"" << 404 - 5*k << "\" y=\"" << j*96 + 5*k + 184 << "\"/>\n</transition>\n";
00584                                                 
00585                                                                         ++k;
00586                                                                 }
00587                                                         }
00588                                                 }
00589                                         }
00590 
00591                                         ++j;
00592                                 }
00593                         }
00594 
00595                         f_stream << "</template>\n\n";
00596                         ++i;
00597                 }
00598         }
00599         f_stream.close ();
00600 }
00601 
00602 };
00603 

Generated on Fri Jul 27 18:30:03 2007 for DREAM by  doxygen 1.5.1