simfaudes.cpp

Go to the documentation of this file.
00001 
00199 #include "libfaudes.h"
00200 
00201 using namespace faudes;
00202 
00203 
00204 // fix windows/mingw definition 
00205 #ifdef FAUDES_WINEXTRA
00206 #define sleep(sec) Sleep((sec) * 1000)
00207 #define usleep(usec) Sleep((usec) / 1000)
00208 #endif
00209 
00210 
00211 // print usage info and exit
00212 void usage_exit(const std::string& message="") {
00213   std::cout << "simfaudes: " << message << std::endl;
00214   std::cout << "" << std::endl;
00215   std::cout << "simfaudes: usage: " << std::endl;
00216   std::cout << "  simfaudes [-q][-v][-i][-bc] [-bt <nnn>][-bs <nnn>] [-l <logfile>] [-ls] [-le] [-lt] <simfile> " << std::endl;
00217   std::cout << "where " << std::endl;
00218   std::cout << "  <simfile>: simulation configuration file" << std::endl;
00219   std::cout << "" << std::endl;
00220   std::cout << "  -q:  less console output " << std::endl;
00221   std::cout << "  -qq: absolutely no console output " << std::endl;
00222   std::cout << "  -v:  more console output" << std::endl;
00223   std::cout << "  -vv: event more console output" << std::endl;
00224   std::cout << "  -i: interactive mode " << std::endl;
00225   std::cout << "" << std::endl;
00226   std::cout << "  -bc: break on condition" << std::endl;
00227   std::cout << "  -bt <nnn>: break on time <nnn> " << std::endl;
00228   std::cout << "  -bs <nnn>: break on step <nnn> " << std::endl;
00229   std::cout << "" << std::endl;
00230   std::cout << "  -l <logfile>: log to <logfile> " << std::endl;
00231   std::cout << "  -ls: log states" << std::endl;
00232   std::cout << "  -le: log events" << std::endl;
00233   std::cout << "  -lt: log time" << std::endl;
00234   std::cout << "  -la: log all" << std::endl;
00235   std::cout << "  -t <nnn>: fifo trace buffer length <nnn> " << std::endl;
00236   std::cout << "" << std::endl;
00237   std::cout << "  -d <devfile>: use io device configured from file" << std::endl;
00238   std::cout << "" << std::endl;
00239   std::cout << "" << std::endl;
00240   exit(-1);
00241 }
00242 
00243 // parse commandline, read executor and run executor
00244 int main(int argc, char* argv[])
00245 {
00246   // some parameters
00247   std::string mMark ="% simfaudes: ========================================= ";
00248 
00249   // default behaviour
00250   int mConsoleOut=0;
00251   bool mInteractive=false;
00252   std::string mSimFile="";
00253   std::string mDevFile="";
00254   bool mBreakCondition=false;
00255   tpTime::Type mBreakTime=tpTime::Max;
00256   int mBreakStep=-1;
00257   std::string mLogFile="";
00258   int mLogMode=0;
00259   int mTraceLength=5;
00260 
00261   // primitive commad line parsing
00262   for(int i=1; i<argc; i++) {
00263     std::string option(argv[i]);
00264     // option: quiet
00265     if((option=="-q") || (option=="--quiet")) {
00266       mConsoleOut=-1;
00267       continue;
00268     }
00269     // option: more quiet
00270     if((option=="-qq") || (option=="--quietquiet")) {
00271       mConsoleOut=-2;
00272       continue;
00273     }
00274     // option: verbose
00275     if((option=="-v") || (option=="--verbose")) {
00276       mConsoleOut=1;
00277       continue;
00278     }
00279     // option: more verbose
00280     if((option=="-vv") || (option=="--verboseverbose")) {
00281       mConsoleOut=2;
00282       continue;
00283     }
00284     // option: interactive
00285     if((option=="-i") || (option=="--interactive")) {
00286       mInteractive=true;
00287       continue;
00288     }
00289     // option: io device
00290     if((option=="-d") || (option=="--device")) {
00291       i++; if(i>=argc) usage_exit();
00292       mDevFile=argv[i];
00293       continue;
00294     }
00295     // option: break condition
00296     if((option=="-bc") || (option=="--breakcondition")) {
00297       mBreakCondition=true;
00298       continue;
00299     }
00300     // option: break time
00301     if((option=="-bt") || (option=="--breaktime")) {
00302       i++; if(i>=argc) usage_exit();
00303       mBreakTime=(tpTime::Type) ToIdx(argv[i]);
00304       continue;
00305     }
00306     // option: break step
00307     if((option=="-bs") || (option=="--breakstep")) {
00308       i++; if(i>=argc) usage_exit();
00309       mBreakStep=(int) ToIdx(argv[i]);
00310       continue;
00311     }
00312     // option: log file
00313     if((option=="-l") || (option=="--logfile")) {
00314       i++; if(i>=argc) usage_exit();
00315       mLogFile=argv[i];
00316       continue;
00317     }
00318     // option: log states
00319     if((option=="-ls") || (option=="--logstates")) {
00320       mLogMode |= LoggingExecutor::States;
00321       continue;
00322     }
00323     // option: log events
00324     if((option=="-le") || (option=="--logevents")) {
00325       mLogMode |= LoggingExecutor::Events;
00326       continue;
00327     }
00328     // option: log time
00329     if((option=="-lt") || (option=="--logtime")) {
00330       mLogMode |= LoggingExecutor::Time;
00331       continue;
00332     }
00333     // option: log all
00334     if((option=="-la") || (option=="--logall")) {
00335       mLogMode |= 0xff;
00336       continue;
00337     }
00338     // option: trace
00339     if((option=="-t") || (option=="--trace")) {
00340       i++; if(i>=argc) usage_exit();
00341       mTraceLength=(int) ToIdx(argv[i]);
00342       continue;
00343     }
00344     // option: help
00345     if((option=="-?") || (option=="--help")) {
00346       usage_exit();
00347       continue;
00348     }
00349     // option: unknown
00350     if(option.c_str()[0]=='-') {
00351       usage_exit("unknown option "+ option);
00352       continue;
00353     }
00354     // filename
00355     if(mSimFile!="")
00356       usage_exit("more than one filname specified" );
00357     mSimFile=option;
00358   }
00359 
00360   // insist in filename
00361   if(mSimFile=="")
00362       usage_exit("you must specify a filename" );
00363 
00364   // dont have both, interactive and sync physics
00365   if(mDevFile!="" && mInteractive) 
00366       usage_exit("you must not specify both interactive and synchrone mode");
00367   
00368   // instantiate executor          
00369   DeviceExecutor mExecutor;
00370 
00371   // read configuration          
00372   mExecutor.Read(mSimFile);
00373   mExecutor.Reset();
00374 
00375   // report configuration
00376   if(mConsoleOut>=1) {
00377     std::cout << mMark << "dumping configuration"  << std::endl;
00378     // generators
00379     for(Idx i=0; i< mExecutor.Size(); i++) {
00380       std::cout << mMark << "found generator #" << i+1 << std::endl;
00381       mExecutor.At(i).Generator().Write();
00382     }
00383     // event attributes
00384     for(EventSet::Iterator eit=mExecutor.Alphabet().Begin();  
00385         eit!=mExecutor.Alphabet().End(); eit++) {
00386       std::cout << mMark << "found event attributes for \"" << 
00387          mExecutor.EventName(*eit) << "\"" << std::endl;
00388       std::cout << mExecutor.Alphabet().Attribute(*eit).ToString() << std::endl;
00389     }
00390     // conditions
00391     for(ProposingExecutor::ConditionIterator cit=mExecutor.ConditionsBegin();  
00392         cit!=mExecutor.ConditionsEnd(); cit++) {
00393       std::cout << mMark << "found simulation condition \"" << 
00394          mExecutor.Conditions().SymbolicName(*cit) << "\"" << std::endl;
00395       std::cout << mExecutor.Condition(*cit).ToString() << std::endl;
00396     }
00397   }
00398 
00399 
00400   // initialze log file
00401   if(mLogFile!="") {
00402     mExecutor.LogOpen(mLogFile,mLogMode | LoggingExecutor::Statistics);
00403   }
00404   if(mLogFile=="" && mLogMode!=0) {
00405     TokenWriter* ptw= new TokenWriter(TokenWriter::Stdout);
00406     mExecutor.LogOpen(*ptw, mLogMode | LoggingExecutor::Statistics);
00407   }
00408 
00409   // set trace buffer
00410   mExecutor.TraceClear(mTraceLength);
00411 
00412   // ************************************************  synchronous prep
00413   if(mDevFile!="") {
00414 #ifdef FAUDES_PLUGIN_IODEVICE
00415 
00416     // create device from file
00417     vDevice* dev=vDevice::FromFile(mDevFile);
00418 
00419     
00420 #ifdef FAUDES_IODEVICE_SIMPLENET
00421 #ifdef FAUDES_WINEXTRA
00422     // if its a net device on windows, initialise winsocks
00423     if(dynamic_cast<nDevice*>(dev)) {
00424       WSADATA wsaData;
00425       if(WSAStartup(MAKEWORD(2,2), &wsaData)!=0) {
00426         usage_exit("cannot start winsock (network error)");
00427       }
00428     }
00429 #endif
00430 #endif
00431 
00432     // report
00433     std::cout << mMark << "Execute via IO device: \""<< dev->Name() << "\"" << std::endl;
00434 
00435     // assign device to executor ad wait for startuo to complete
00436     mExecutor.Devicep(dev);
00437     if(mBreakTime==tpTime::UnDef)  mBreakTime=tpTime::Max;
00438     mExecutor.DeviceStart();
00439     dev->Reset(); // flush buffer
00440     while(dev->Status()!=vDevice::Up) {
00441       std::cout << mMark << "Starting IO device \""<< dev->Name() << "\" Status: " << dev->StatusString() << std::endl;
00442       sleep(1);
00443     }
00444     dev->CurrentTime(0); // sync time
00445     std::cout << mMark << "IO device \""<< dev->Name() << "\" is Up" << std::endl;
00446 #else
00447     // cannot run device without plugin
00448     usage_exit("cannot load device \""+mDevFile+"\": device plugin not present");
00449 #endif
00450   } 
00451 
00452 
00453   // ************************************************* interactive loop
00454   bool mRunning=true;
00455   bool mInterTemp=mInteractive;
00456   SimConditionSet mSatisfied;
00457   mSatisfied.Name("SatisfiedConditions");
00458   while(mRunning) {
00459     // report current state
00460     if(mConsoleOut>=2) {
00461       std::cout << mMark << "current state:" << std::endl;
00462       std::cout << mExecutor.CurrentParallelTimedStateStr() << std::endl;
00463     }  
00464     // report current state
00465     if(mConsoleOut>=0 && mConsoleOut<2) {
00466       std::cout << mMark << "current state:" << std::endl;
00467       std::cout << mExecutor.CurrentParallelStateStr() << std::endl;
00468     }  
00469     // report current time
00470     if(mConsoleOut>=1) {
00471       std::cout << mMark << "current time:" << std::endl;
00472       std::cout << "<Time> " << mExecutor.CurrentTime() << " </Time>" << std::endl;
00473       std::cout << "<Step> " << mExecutor.CurrentStep() << " </Step>" << std::endl;
00474     }  
00475     // report current time
00476     if(mConsoleOut==0) {
00477       std::cout << mMark << "current time:" << std::endl;
00478       std::cout << "<Time> " << mExecutor.CurrentTime() << " </Time>" << std::endl;
00479     }  
00480     // report satisfied conditions
00481     if(mConsoleOut>=0) {
00482       mSatisfied.Clear();
00483       for(ProposingExecutor::ConditionIterator cit=mExecutor.ConditionsBegin();  
00484           cit!=mExecutor.ConditionsEnd(); cit++) {
00485         if(mExecutor.Condition(*cit).Satisfied()) mSatisfied.Insert(*cit);
00486       }
00487       if(mSatisfied.Size()>0) {
00488         std::cout << mMark << "found conditions satisfied:" << std::endl;
00489         std::cout << mSatisfied.ToString() << std::endl;
00490       }
00491     }
00492     // report internal state
00493     if(mConsoleOut>=2) {
00494       std::cout << mMark << "simulation event states:" << std::endl;
00495       std::cout << mExecutor.EventStatesToString() << std::endl;
00496     }
00497     // report enabled transitions
00498     if(mConsoleOut>=1) {
00499       std::cout << mMark << "enabled events:" << std::endl;
00500       std::cout << mExecutor.EnabledEvents().ToString() << std::endl;
00501       std::cout << mMark << "enabled interval:" << std::endl;
00502       std::cout << mExecutor.EnabledInterval().Str() << std::endl;
00503       std::cout << mMark << "enabled time:" << std::endl;
00504       std::cout << mExecutor.EnabledTime().Str() << std::endl;
00505     }  
00506     // test break: time up
00507     if(mExecutor.CurrentTime() >= tpTime::Max) {
00508       if(mConsoleOut>=-1) std::cout << mMark << "time is up" << std::endl;
00509       mInterTemp=false;
00510       mRunning=false;
00511       break;
00512     }
00513     // test break: condition
00514     if(mExecutor.BreakCondition() && (mBreakCondition || mInteractive)) {
00515      if(mConsoleOut>=-1) std::cout << mMark << "break condition triggered" << std::endl;
00516       mInterTemp=mInteractive;
00517       mRunning=mInteractive;
00518     }
00519     // test break: time
00520     if(mBreakTime!=tpTime::UnDef)
00521     if(mExecutor.CurrentTime() >= mBreakTime) {
00522       if(mConsoleOut>=-1) std::cout << mMark << "break time reached" << std::endl;
00523       mInterTemp=mInteractive;
00524       mRunning=mInteractive;
00525     }
00526     // test break: step
00527     if(mBreakStep>=0)
00528     if(mExecutor.CurrentStep() >= mBreakStep) {
00529       if(mConsoleOut>=-1) std::cout << mMark << "break step reached" << std::endl;
00530       mInterTemp=mInteractive;
00531       mRunning=mInteractive;
00532     }
00533     // test break: synchronous device
00534     if(!mExecutor.IsSynchronous()) {
00535       if(mConsoleOut>=-1) std::cout << mMark << "device out of sync" << std::endl;
00536       mInterTemp=false;
00537       mRunning=false;
00538       break;
00539     }
00540     // proposed action
00541     TimedEvent mPropTrans=mExecutor.ProposeNextTransition();
00542     if(mConsoleOut>=0) {
00543       std::cout << mMark << "proposed action:" << std::endl;
00544       if(mPropTrans.Time>0) 
00545         std::cout << "<ProposedTime> " << mPropTrans.Time << " </ProposedTime>" << std::endl;
00546       if(mPropTrans.Event!=0) 
00547         std::cout << "<ProposedEvent> " << mExecutor.EventName(mPropTrans.Event)  << " </ProposedEvent>" << std::endl;
00548       if((mPropTrans.Time<=0) && (mPropTrans.Event==0) )
00549         std::cout << "+DeadLock+" << std::endl;
00550     }
00551     // record transition
00552     Idx mEvent=0;
00553     // ask choice
00554     while(mInterTemp) {
00555        std::cout << mMark << "enter command:" << std::endl;
00556        std::string line;
00557        std::getline(std::cin,line);
00558        // separate cmd from arg
00559        std::string choice;
00560        std::string param;
00561        std::istringstream sline(line);
00562        sline >> choice;
00563        sline >> param;
00564        // convert to int
00565        int ichoice =-1;
00566        std::istringstream schoice(choice);
00567        schoice >> ichoice;
00568        if(!schoice) ichoice=-1;
00569        int iparam =-1;
00570        std::istringstream sparam(param);
00571        sparam >> iparam;
00572        if(!sparam) iparam=-1;
00573        // convert to symbol
00574        std::string nchoice;
00575        if(choice.length()>2)
00576        if(choice.at(0)=='"' && choice.at(choice.length()-1)== '"')
00577          nchoice=choice.substr(1,choice.length()-2);
00578        // switch cases
00579        bool err=false;
00580        if(choice=="x" || choice == "exit") {
00581          mRunning=false;
00582        } else
00583        if(choice=="p" || choice=="proposal" || choice=="") {
00584          mExecutor.ExecuteTime(mPropTrans.Time);
00585          if(mExecutor.ExecuteEvent(mPropTrans.Event)) 
00586            mEvent=mPropTrans.Event;
00587        } else
00588        if(choice=="r" || choice=="run") {
00589          mInterTemp=false;
00590        } else
00591        if(choice=="v" || choice=="revert") {
00592          int step = mExecutor.CurrentStep()-1;
00593          if(iparam!=-1) step=iparam;
00594          std::cout << mMark << "revert to step " << step << std::endl;
00595          mExecutor.RevertToStep(step);          
00596        } else
00597        if(choice=="t" || choice=="trace") {
00598          std::cout << mMark << "system trace" << std::endl;
00599          mExecutor.TraceWrite();
00600          continue;
00601        } else
00602        if(mExecutor.Alphabet().Exists(nchoice)) {
00603          if(mExecutor.ExecuteEvent(mExecutor.EventIndex(nchoice)))
00604            mEvent=mExecutor.EventIndex(nchoice);
00605        } else
00606        if(ichoice>0) {
00607          mExecutor.ExecuteTime(ichoice);
00608        } else
00609        if(mExecutor.Alphabet().Exists(choice)) {
00610          if(mExecutor.ExecuteEvent(mExecutor.EventIndex(nchoice)))
00611            mEvent=mExecutor.EventIndex(nchoice);
00612        } else {
00613          std::cout << mMark << "simfaudes interactive mode" << std::endl;
00614          std::cout << "%"  << std::endl;
00615          std::cout << "%  execute time and/or transitions"  << std::endl;
00616          std::cout << "%  * <nn> to pass a specified duration <nn> (excl brackets)" << std::endl;
00617          std::cout << "%  * \"event\" to execute an event (incl quotes)" << std::endl;
00618          std::cout << "%  * [P] or [Ret] to execute the recent proPosal " << std::endl;
00619          std::cout << "%"  << std::endl;
00620          std::cout << "%  show trace and revert"  << std::endl;
00621          std::cout << "%  * [T] to show a Trace of recent events and states" << std::endl;
00622          std::cout << "%  * [V] <nn> to reVert to step <nn> (obmit <nn> for one step backward) "<< std::endl;
00623          std::cout << "%"  << std::endl;
00624          std::cout << "%  other"  << std::endl;
00625          std::cout << "%  * [X] to eXit" << std::endl<< std::endl;
00626          err=true;
00627        }
00628        if(!err) break;
00629     }  
00630     // execute proposal
00631     if(!mInterTemp && mDevFile=="") {
00632        mExecutor.ExecuteTime(mPropTrans.Time);
00633        if(mExecutor.ExecuteEvent(mPropTrans.Event))
00634          mEvent=mPropTrans.Event;
00635     }
00636 #ifdef FAUDES_PLUGIN_IODEVICE
00637     // sync step
00638     if(mDevFile!="") {
00639       mEvent=mExecutor.SyncStep();
00640       mExecutor.SyncTime();
00641     }
00642 #endif
00643     // report event
00644     if(mConsoleOut>=0 && mEvent!=0) {
00645       std::cout << mMark << "execute event:" << std::endl;
00646       std::cout << "<ExecutedEvent> " << mExecutor.EventName(mEvent)  << " </ExecutedEvent>"
00647         << std::endl;
00648     }  
00649 
00650   } // loop: while mRunning
00651 
00652 
00653   // report statistics
00654   if(mConsoleOut>=-1) {
00655     std::cout << std::endl;
00656     for(ProposingExecutor::ConditionIterator cit=mExecutor.ConditionsBegin();  
00657         cit!=mExecutor.ConditionsEnd(); cit++) {
00658       if(!mExecutor.Condition(*cit).IsEnabled()) continue;
00659       std::cout << mMark << "statistics for simulation condition \"" << 
00660          mExecutor.Conditions().SymbolicName(*cit) << "\"" << std::endl;
00661       mExecutor.Condition(*cit).mSamplesPeriod.Compile();
00662       std::cout << mExecutor.Condition(*cit).mSamplesPeriod.Str();
00663       mExecutor.Condition(*cit).mSamplesDuration.Compile();
00664       std::cout << mExecutor.Condition(*cit).mSamplesDuration.Str() << std::endl;
00665     }
00666   }
00667 
00668   // close log file
00669   mExecutor.LogClose();
00670 
00671   // reset incl device if such  
00672   mExecutor.Reset();
00673 
00674   // testing: can we actually stop the device?
00675   mExecutor.DeviceStop();
00676 
00677 
00678   return 0;
00679 }

Generated on Mon Nov 10 08:13:15 2008 for libFAUDES 2.11v by  doxygen 1.4.4