00001
00002
00003
00004
00005
00006
00007
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
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
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
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
00086 cosyProcesses::iterator j;
00087 for (j=cp.begin(); j!=cp.end(); ++j)
00088 {
00089 delete *j;
00090 }
00091
00092
00093 cosyNetworks::iterator k;
00094 for (k=cn.begin(); k!=cn.end(); ++k)
00095 {
00096 delete *k;
00097 }
00098
00099
00100 cosyFifos::iterator i;
00101 for (i=cf.begin(); i!=cf.end(); ++i)
00102 {
00103 delete *i;
00104 }
00105
00106
00107 cosyOutPorts::iterator op;
00108 for (op=co.begin(); op!=co.end(); ++op)
00109 {
00110 delete *op;
00111 }
00112
00113
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
00124 cosyProcesses::iterator j;
00125 for (j=cp.begin(); j!=cp.end(); ++j)
00126 {
00127 (*j)->start();
00128 }
00129
00130
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
00141 cosyProcesses::iterator j;
00142 for (j=cp.begin(); j!=cp.end(); ++j)
00143 {
00144 (*j)->join();
00145 }
00146
00147
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
00158 cosyProcesses::iterator j;
00159 for (j=cp.begin(); j!=cp.end(); ++j)
00160 {
00161 (*j)->kill();
00162 }
00163
00164
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
00252
00253
00254
00255
00256
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
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 }