Main Page | Class Hierarchy | Compound List | File List | Compound Members | File Members

cosynetwork.cc

Go to the documentation of this file.
00001 /*--------------------------------------------------------------------
00002  *
00003  * (C) Copyright Koninklijke Philips Electronics NV 2006. 
00004  * All rights reserved. This software is licensed under the terms of
00005  * version 2.1 of the GNU Lesser General Public License as published 
00006  * by the Free Software Foundation. For licensing and warranty
00007  * information, see the file COPYING in the main directory.
00008  *
00009  *------------------------------------------------------------------*/
00010 
00011 #include <sys/types.h>
00012 #include "cosynetwork.h"
00013 #include "cosyprocess.h"
00014 #include "cosyfifo.h"
00015 #include "cosyselect.h"
00016 #include "rte.h"
00017 #include "rteport.h"
00018 #include "networkimpl.h"
00019 #include "processimpl.h"
00020 #include "portimpl.h"
00021 #include "fifoimpl.h"
00022 #include "portbase.h"
00023 #include "os.h"
00024 #include "taskapi.h"
00025 #include "semaphoreapi.h"
00026 #include "utilbase.h"
00027 #include <assert.h>
00028 #include <string>
00029 
00030 bool  cosyNetwork::growingFifos = true;
00031 bool  cosyNetwork::dd           = true;
00032 
00033 cosyNetwork::cosyNetwork(NetworkImpl& n, Os& o, cosyRte& r) : 
00034   rteNetwork(n),
00035   os(o),
00036   task(0),
00037   zero1(0), zero2(0)
00038 { 
00039   rte = &r;
00040 
00041   // construct all fifos
00042   for (unsigned int i=0; i<api()->nrFifos(); ++i)
00043   {
00044     FifoImpl* f = (FifoImpl*)api()->getFifo(i);
00045     
00046     OutPortBases ops;
00047     getFarOutPorts(f,ops);
00048 
00049     InPortBases ips;
00050     getFarInPorts(f,ips);
00051     
00052     assert(ops.size() == 1);
00053     OutPortImpl* op = (OutPortImpl*)*ops.begin();
00054     
00055     std::vector<const InPortBase*>::iterator ip;
00056     for(ip = ips.begin(); ip != ips.end(); ++ip)
00057     {
00058       cosyFifo* fifo = new cosyFifo(*f, r); 
00059       cf.push_back(fifo);
00060       co.push_back(new rteOutPort(*op,*fifo));
00061       ci.push_back(new rteInPort(*((InPortImpl*)*ip),*fifo));        
00062     }   
00063   }
00064 
00065   // construct all subnetworks
00066   for (unsigned int i=0; i<api()->nrNetworks(); i++)
00067   {
00068     cn.push_back(new cosyNetwork(*(NetworkImpl*)api()->getNetwork(i),os, r));
00069   }
00070 
00071   // construct all processes
00072   for (unsigned int i=0; i<api()->nrProcesses(); i++)
00073   {
00074     cp.push_back(new cosyProcess(*(ProcessImpl*)api()->getProcess(i), r));
00075   }
00076 }
00077 
00078 cosyNetwork::~cosyNetwork()
00079 { 
00080   if (task)
00081   {
00082     delete task;
00083   }
00084 
00085   // delete all processes
00086   cosyProcesses::iterator j;
00087   for (j=cp.begin(); j!=cp.end(); ++j)
00088   {
00089     delete *j;
00090   }
00091 
00092   // delete all subnetworks
00093   cosyNetworks::iterator k;
00094   for (k=cn.begin(); k!=cn.end(); ++k)
00095   {
00096     delete *k;
00097   }
00098 
00099   // delete all fifos
00100   cosyFifos::iterator i;
00101   for (i=cf.begin(); i!=cf.end(); ++i)
00102   {
00103     delete *i;
00104   }
00105 
00106   // delete all output ports
00107   cosyOutPorts::iterator op;
00108   for (op=co.begin(); op!=co.end(); ++op)
00109   {
00110     delete *op;
00111   }
00112 
00113   // delete all input ports
00114   cosyInPorts::iterator ip;
00115   for (ip=ci.begin(); ip!=ci.end(); ++ip)
00116   {
00117     delete *ip;
00118   }
00119 }
00120 
00121 void cosyNetwork::run()
00122 {
00123   // start all processes
00124   cosyProcesses::iterator j;
00125   for (j=cp.begin(); j!=cp.end(); ++j)
00126   {
00127     (*j)->start();
00128   }
00129   
00130   // start all subnetworks
00131   cosyNetworks::iterator k;
00132   for (k=cn.begin(); k!=cn.end(); ++k)
00133   {
00134     (*k)->run();
00135   }
00136 }
00137 
00138 void cosyNetwork::join()
00139 {
00140   // join all processes
00141   cosyProcesses::iterator j;
00142   for (j=cp.begin(); j!=cp.end(); ++j)
00143   {
00144     (*j)->join();
00145   }
00146   
00147   // join all subnetworks
00148   cosyNetworks::iterator k;
00149   for (k=cn.begin(); k!=cn.end(); ++k)
00150   {
00151     (*k)->join();
00152   }
00153 }
00154 
00155 void cosyNetwork::kill()
00156 {
00157   // kill all processes
00158   cosyProcesses::iterator j;
00159   for (j=cp.begin(); j!=cp.end(); ++j)
00160   {
00161     (*j)->kill();
00162   }
00163   
00164   // kill all subnetworks
00165   cosyNetworks::iterator k;
00166   for (k=cn.begin(); k!=cn.end(); ++k)
00167   {
00168     (*k)->kill();
00169   }
00170 }
00171 
00172 void handler1(void* arg)
00173 {
00174   cosyNetwork* n = (cosyNetwork*)arg;
00175   if (!n->growFifo())
00176   {
00177     if (n->deadlock())
00178     {
00179       n->rte->cerr() << "YAPI > Deadlock, since all processes have blocked:" << std::endl;
00180     } else {
00181       n->rte->cerr() << "YAPI > Finished, but some processes have not terminated:" << std::endl;
00182     }
00183     if (cosyNetwork::dd) 
00184     {
00185       n->printProcessStatus();
00186       n->printFifoStatus();
00187     }
00188     n->os.setDeadlockHandler(fatal_func,n);
00189     n->task = new Task(clean_func,n);
00190     n->task->start();
00191   }
00192 }
00193 
00194 void handler2(void* arg)
00195 {
00196   cosyNetwork* n = (cosyNetwork*)arg;
00197         if (!n->growFifo())
00198   {
00199     if (n->deadlock())
00200     {
00201       n->task = new Task(zero0_func,n);
00202       n->task->start();
00203     } else {
00204       n->os.setDeadlockHandler(fatal_func,n);
00205       n->task = new Task(clean_func,n);
00206       n->task->start();
00207     }
00208   }
00209 }
00210 
00211 void fatal_func(void* arg)
00212 {
00213   cosyNetwork* n = (cosyNetwork*)arg;
00214   n->rte->cerr() << "YAPI > Fatal error occurred while simulating process network ";
00215   n->rte->cerr() << n->api()->fullName() << std::endl;
00216 }
00217 
00218 void clean_func(void* arg)
00219 {
00220   cosyNetwork* n = (cosyNetwork*)arg;
00221   n->kill();
00222   n->task->exit();
00223 }
00224 
00225 void zero0_func(void* arg)
00226 {
00227   cosyNetwork* n = (cosyNetwork*)arg;
00228   if (n->zero1) n->zero1->kill();
00229   if (n->zero2) n->zero2->kill();
00230   n->zero1 = new Task(zero1_func,n);
00231   n->zero2 = new Task(zero2_func,n);
00232   n->zero1->start();
00233   n->zero2->start();
00234   n->task->exit();
00235 }
00236 
00237 void zero1_func(void* arg)
00238 {
00239   cosyNetwork* n = (cosyNetwork*)arg;
00240   n->zero2->join();
00241 }
00242 
00243 void zero2_func(void* arg)
00244 {
00245   cosyNetwork* n = (cosyNetwork*)arg;
00246   n->zero1->join();
00247 }
00248 
00249 void cosyNetwork::start()
00250 {
00251   // Deadlock = all processes are blocked and none has finished
00252 
00253   // When deadlocked run null process 
00254   // os.setDeadlockHandler(handler2,this);
00255 
00256   // When deadlocked terminate network
00257   os.setDeadlockHandler(handler1,this);
00258   
00259   run();
00260   join();
00261 }
00262 
00263 bool cosyNetwork::growFifo()
00264 {
00265   if (!cosyNetwork::growingFifos)
00266     return false;
00267 
00268   unsigned int i;
00269   for (i=0; i<api()->nrFifos(); i++)
00270   {
00271     cosyFifo* f = (cosyFifo*)((FifoImpl*)api()->getFifo(i))->rte();
00272     if (f->grow())
00273       return true;
00274   }
00275 
00276   for (i=0; i<api()->nrNetworks(); i++)
00277   {
00278     cosyNetwork* n = (cosyNetwork*)((NetworkImpl*)api()->getNetwork(i))->rte();
00279     if (n->growFifo())
00280     return true;
00281   }
00282   return false;
00283 }
00284 
00285 bool cosyNetwork::deadlock()
00286 {
00287   unsigned int i;
00288   for (i=0; i<api()->nrProcesses(); i++)
00289   {
00290     cosyProcess* p = (cosyProcess*)((ProcessImpl*)api()->getProcess(i))->rte();
00291     if (p->finished())
00292       return false;
00293   }
00294 
00295   for (i=0; i<api()->nrNetworks(); i++)
00296   {
00297     cosyNetwork* n = (cosyNetwork*)((NetworkImpl*)api()->getNetwork(i))->rte();
00298     if (!n->deadlock())
00299       return false;
00300   }
00301   return true;
00302 }
00303 
00304 void cosyNetwork::printFifoMetrics(Table& t, const FifoMetric* m, 
00305                                    unsigned int n, bool title)
00306 {
00307   for (unsigned int i=0; i<api()->nrFifos(); i++)
00308   {
00309     FifoImpl* fifo = (FifoImpl*)api()->getFifo(i);
00310     for (unsigned int j=0; j<fifo->nrRteFifos(); j++)
00311     {
00312       cosyFifo* f = (cosyFifo*)fifo->rte(j);
00313 
00314       if ((i+j==0) && title)
00315       {
00316         t << "";
00317         for (unsigned int k=0; k<n; k++)
00318         {
00319           t << f->getMetricName(m[k]);
00320         }
00321       }
00322       if (fifo->nrRteFifos() == 1)
00323         t << f->api()->fullName();
00324       else
00325       { 
00326         char buf[32];
00327         sprintf(buf, "[%d]", j);
00328         std::string s = f->api()->fullName();
00329         s += buf;
00330         t << s.c_str();
00331       }
00332       for (unsigned int k=0; k<n; k++)
00333       {
00334         t << f->getMetricValue(m[k]);
00335       }
00336     }
00337   }
00338 
00339   for (unsigned int i=0; i<api()->nrNetworks(); i++)
00340   {
00341     cosyNetwork* s = (cosyNetwork*)((NetworkImpl*)api()->getNetwork(i))->rte();
00342     s->printFifoMetrics(t, m, n, false);
00343   }
00344 }
00345 
00346 void cosyNetwork::printFifoStatus()
00347 {
00348   const FifoMetric wm[] = {
00349     MinSize, MaxSize,
00350     Size, Room, Data,
00351     TokensWritten,
00352     TokensRead,
00353     PendingWriteTokens,
00354     PendingReadTokens,
00355     NeededWriteTokens,
00356     NeededReadTokens
00357   };
00358 
00359   Table t(12, "Fifo Status");
00360   t.align(0, Table::left);
00361   for (unsigned int j=0; j<11; j++)
00362   {
00363     t.align(j+1, Table::right);
00364   }
00365   printFifoMetrics(t, wm, 11);
00366 
00367   std::ostream& stream = rte->cerr();
00368   t.print(stream);
00369 }
00370 
00371 void cosyNetwork::printCommunicationWorkload()
00372 {
00373   const FifoMetric wm[] = {
00374     Size,
00375     TokenSize,
00376     TokensWritten,
00377     WriteCalls,
00378     TokensPerWrite,
00379     TokensRead,
00380     ReadCalls,
00381     TokensPerRead
00382   };
00383 
00384   api()->commWorkload->align(0, Table::left);
00385   for (unsigned int j=0; j<8; j++)
00386   {
00387     api()->commWorkload->align(j+1, Table::right);
00388   }
00389   printFifoMetrics(*api()->commWorkload, wm, 8);
00390 }
00391 
00392 void cosyNetwork::printProcessStatus(Table& t)
00393 {
00394   for (unsigned int i=0; i<api()->nrFifos(); i++)
00395   {
00396     FifoImpl* fifo = (FifoImpl*)api()->getFifo(i);
00397     for (unsigned int j=0; j<fifo->nrRteFifos(); j++)
00398     {
00399       cosyFifo* f = (cosyFifo*)fifo->rte(j);
00400 
00401       std::string s = f->api()->fullName();
00402       if (fifo->nrRteFifos()>1)
00403       {
00404         char buf[32];
00405         sprintf(buf, "[%d]", j);
00406         s += buf;
00407       }
00408  
00409       // FifoStat::printProcessStatus:
00410       if (f->sel && f->rs) {
00411         t << f->api()->srcPort()->parentComponent()->fullName();
00412         t << "select";
00413         t << s.c_str();
00414       } else if (f->sel && f->ws) {
00415         t << f->getDst()->api()->parentComponent()->fullName();
00416         t << "select";
00417         t << s.c_str();
00418       } else if (f->block && f->wn) {
00419         t << f->api()->srcPort()->parentComponent()->fullName();
00420         t << "write";
00421         t << s.c_str();
00422       } else if (f->block && f->rn) {
00423         t << f->getDst()->api()->parentComponent()->fullName();
00424         t << "read";
00425         t << s.c_str();
00426       }
00427     }
00428   }
00429 
00430   for (unsigned int i=0; i<api()->nrNetworks(); i++)
00431   {
00432     cosyNetwork* n = (cosyNetwork*)((NetworkImpl*)api()->getNetwork(i))->rte();
00433     n->printProcessStatus(t);
00434   }
00435 }
00436 
00437 void cosyNetwork::printProcessStatus()
00438 {
00439   Table t(3, "Blocked processes");
00440   t.align(0, Table::left);
00441   t.align(1, Table::left);
00442   t.align(2, Table::left);
00443   t << "Process" << "by" << "on Fifo";
00444   printProcessStatus(t);
00445   t.print(rte->cerr());
00446 }
00447 
00448 void cosyNetwork::printComputationWorkload(Table& t)
00449 {
00450   unsigned int i;
00451 
00452   for (i=0; i<api()->nrProcesses(); i++)
00453   {
00454     cosyProcess* p = (cosyProcess*)((ProcessImpl*)api()->getProcess(i))->rte();
00455 
00456     t << p->api()->fullName() << "" << "";
00457     Counters::iterator i;
00458     for (i = p->cntr.begin(); i != p->cntr.end(); i++)
00459     {
00460       t << "" << (*i).name << (*i).count;
00461     }
00462   }
00463 
00464   for (i=0; i<api()->nrNetworks(); i++)
00465   {
00466     cosyNetwork* n = (cosyNetwork*)((NetworkImpl*)api()->getNetwork(i))->rte();
00467     n->printComputationWorkload(t);
00468   }
00469 
00470 }
00471 
00472 void cosyNetwork::printComputationWorkload()
00473 {
00474   api()->compWorkload->align(0, Table::left);
00475   api()->compWorkload->align(1, Table::left);
00476   api()->compWorkload->align(2, Table::right);
00477   *api()->compWorkload << "Process" << "Instruction" << "Count";
00478   printComputationWorkload(*api()->compWorkload);
00479 }

Generated on Wed Feb 15 14:52:38 2006 for yapi by doxygen 1.3.2