Main Page | Modules | Class Hierarchy | Class List | File List | Class Members | File Members | Related Pages | Examples

acverifier.cpp

00001 /********************************************************/
00002 /* ac_verifier.cpp: The ArchC co-verification engine    */
00003 /* Author: Sandro Rigo                                  */
00004 /* Starting Date: 10-10-2003                            */
00005 /*                                                      */
00006 /********************************************************/
00008 
00016 
00017 
00018 
00019 #include <stdlib.h>
00020 #include <errno.h>
00021 #include <sys/types.h>
00022 #include <sys/ipc.h>
00023 #include <sys/msg.h>
00024 #include <sys/wait.h>
00025 #include <unistd.h>
00026 #include <string.h>
00027 #include <iostream>
00028 
00029 #include "ac_msgbuf.H"
00030 
00031 #define REFERENCE_MODEL 0
00032 #define DUV_MODEL 1
00033 #define AC_ERROR( msg )    cerr<< "ArchC ERROR: " << msg  <<'\n'
00034 #define AC_MSG( msg )      cerr<< "ArchC: " << msg  <<'\n'
00035 
00036 //#define DDEBUG
00037 //#define DEBUG
00038 using namespace std;
00039 
00040 char ACVersion[] = "0.9-beta";
00041 //This is the maximal number of unmatched logs accepted before aborting co-verification
00042 static const unsigned int AC_MAX_UNMATCHED = 20000;
00043 
00044 //These variables will be used to control and access message queues
00045 //and child processes
00046 key_t ref_key, duv_key;
00047 int ref_msqid, duv_msqid;
00048 pid_t ref_pid, duv_pid;
00049 struct msqid_ds ref_info, duv_info;
00050 
00051 //Device list for both models
00052 struct dev_list *ref_devlist = NULL, *duv_devlist = NULL;
00053 struct start_msgbuf ref_sbuf, duv_sbuf;
00054 struct dev_loglist *loglist = NULL;
00055 
00056 
00057 
00058 
00059 //Debugging printf function
00060 #ifdef DEBUG
00061 #include <stdarg.h>
00062 inline int dprintf(const char *format, ...)
00063 {
00064   int ret;
00065 
00066         va_list args;
00067         va_start(args, format);
00068         ret = vfprintf(stderr, format, args);
00069         va_end(args);
00070   return ret;
00071 }
00072 #else
00073 inline void dprintf(const char *format, ...) {}
00074 #endif
00075 
00076 //Defining DDEBUG will produce a real verbose verifier
00077 #ifdef DDEBUG
00078 #include <stdarg.h>
00079 inline int ddprintf(const char *format, ...)
00080 {
00081   int ret;
00082 
00083         va_list args;
00084         va_start(args, format);
00085         ret = vfprintf(stderr, format, args);
00086         va_end(args);
00087   return ret;
00088 }
00089 #else
00090 inline void ddprintf(const char *format, ...) {}
00091 #endif
00092 
00093 
00094 //Function Prototypes
00095 void CheckOptions(int model);
00096 void ListInit(struct dev_list** model_devlist, int msqid, start_msgbuf *sbuf );
00097 void CheckListConsistency(void);
00098 void AddLog( long type, change_log log, int device );
00099 void MatchLogs( void);
00100 
00101 //void DoIt(void);
00102 void DoItOntheFly(void);
00103 void FinishIt(void);
00104 void ChangeDump( struct dev_loglist *pllist );
00105 
00106 /* Display the command line options accepted by ArchC verifier. */
00107 static void DisplayHelp (){
00108   printf ("==================================================\n");
00109   printf (" This is ArchC Verifier for ArchC version %s\n", ACVersion);
00110   printf ("==================================================\n\n");
00111   printf ("Usage: ac_verifier REF_model DUV_model APP [--ref_args=arguments] [--duv_args=arguments]\n\n");
00112   printf ("    Where:\n\n");
00113   printf ("    --> \"REF_model\" and \"DUV_model\" stand for the path to the executable files\n");
00114   printf ("         of each model respectively.\n\n");
00115         printf ("    --> \"APP\" stands for the running application file. You must specify the application \n");
00116         printf ("         to be loaded using --load or --load_obj options, like in regular ArchC simulations.\n\n");        
00117         printf ("    --> \"arguments\" stands for the set of arguments to be passed to the running application. \n");
00118         printf ("         It must be specified both for the reference and duv models.\n");         
00119         printf ("         You may specify different arguments for the two models. Like different names for\n");         
00120         printf ("         output files that you want to compare after the simulation, for example.\n");         
00121   printf ("\n\n");
00122 }
00123 
00125 // This function is called when we need
00126 // to force termination of all three processes
00127 // ac_verifier, ref and duv
00129 void ABORT(){
00130 
00131         cerr << "Aborting co-verification ..." << endl;
00132 
00133         //Deleting message queues
00134         if (msgctl(ref_msqid, IPC_RMID, NULL) == -1) {
00135                 perror("msgctl");
00136                 cerr << "Could not delete Ref model msg queue."<<endl;
00137         }
00138 
00139         if (msgctl(duv_msqid, IPC_RMID, NULL) == -1) {
00140                 perror("msgctl");
00141                 cerr << "Could not delete Ref model msg queue."<<endl;
00142         }
00143 
00144         if (kill(ref_pid, 15)== -1) {
00145                 perror("kill");
00146                 cerr << "Could not terminate Ref model process."<<endl;
00147         }
00148 
00149         if (kill(duv_pid, 15)== -1) {
00150                 perror("kill");
00151                 cerr << "Could not terminate DUV model process."<<endl;
00152         }
00153 
00154         exit(1);
00155 }
00156 
00157 
00159 // This is the main function.
00160 // It will handle command-line arguments and
00161 // create message queues.
00163 int main(int argc, char *argv[])
00164 {
00165                 char *ref_argv[argc], *duv_argv[argc];
00166                 int j,i, nargs; 
00167                 int ref_status, duv_status;
00168                 ++argv, --argc;  /* skip over program name */
00169 
00170 
00171                 //The user asked for help ...
00172                 if( !argv[0] || !strcmp(argv[0], "--help") || !strcmp(argv[0], "-h")){
00173                         DisplayHelp();
00174                         return 0;
00175                 }
00176 
00177                 //We need at least 3 arguments:
00178                 //1. Path for the reference model
00179                 //2. Path for the duv model
00180                 //3. Path for the running application .
00181                 if( argc < 3 ){
00182                         AC_ERROR("Invalid number of arguments.");
00183                         cerr << "   Try running ac_verifier --help for more information." <<endl;
00184                         exit(1);
00185                 }
00186 
00187                 if( (strncmp( argv[2], "--load_obj=", 11)) && (strncmp( argv[2], "--load=", 7)) ){
00188                         AC_ERROR("Invalid argument! Third argument must be the running application file.");
00189                         cerr << "   You must use --load or --load_obj options, just as it is done with any ArchC model." <<endl;
00190                         cerr << "   Try running ac_verifier --help for more information." <<endl;
00191                         exit(1);
00192                 }
00193 
00194 
00195 
00196                 //Creating message queues.
00197     if ((ref_key = ftok(argv[0], 'A')) == -1) {
00198         perror("ftok");
00199         exit(1);
00200     }
00201                 dprintf("Reference model queue key: %d\n",ref_key);
00202 
00203     if ((duv_key = ftok(argv[1], 'A')) == -1) {
00204         perror("ftok");
00205         exit(1);
00206     }
00207                 dprintf("DUV model queue key: %d\n",duv_key);
00208 
00209     if ((ref_msqid = msgget(ref_key, 0666 | IPC_CREAT)) == -1) {
00210         perror("msgget");
00211         exit(1);
00212     }
00213     
00214     if ((duv_msqid = msgget(duv_key, 0666 | IPC_CREAT)) == -1) {
00215         perror("msgget");
00216         exit(1);
00217     }
00218 
00219 
00220                 /* Preparing arguments to be passed for both models */
00221 
00222                 //Storing program name and application to be runned
00223                 ref_argv[0] = (char*) malloc( sizeof(char)*strlen(argv[0])+1 );
00224                 duv_argv[0] = (char*) malloc( sizeof(char)*strlen(argv[1])+1 );
00225                 ref_argv[1] = (char*) malloc( sizeof(char)*strlen(argv[2])+1 );
00226                 duv_argv[1] = (char*) malloc( sizeof(char)*strlen(argv[2])+1 );
00227 
00228                 ref_argv[0] = strcpy(ref_argv[0],argv[0]);
00229                 duv_argv[0] = strcpy(duv_argv[0],argv[1]);
00230                 ref_argv[1] = strcpy(ref_argv[1],argv[2]);
00231                 duv_argv[1] = strcpy(duv_argv[1],argv[2]);
00232 
00233                 dprintf("REF: %s  running %s\n", ref_argv[0], ref_argv[1]);
00234                 dprintf("DUV: %s  running %s\n", duv_argv[0], duv_argv[1]);
00235 
00236                 nargs=argc-3; //Number of remaining arguments to be processed
00237 
00238                 if ( !nargs ){
00239                                 dprintf("Running app has no args\n");
00240                                 ref_argv[2] = NULL;
00241                                 duv_argv[2] = NULL;
00242                 }                               
00243                         
00244                 argv+=3;
00245                 i=0;
00246                 while( i <nargs ){ //This means that we have arguments to pass to the running app
00247                         
00248                         if( !strncmp( argv[i], "--ref_args=", 11) ){
00249                                 
00250                                 //Storing Reference model running app args
00251                                 dprintf("Storing Reference model running app args\n");
00252                                 ref_argv[2] = (char*)malloc(strlen(argv[i]) - 10); //1st arg is after the '=' signal
00253                                 strcpy(ref_argv[2], argv[i]+11);
00254                                 i++;
00255                                 j=3;
00256                                 dprintf("Storing  arg %s\n", ref_argv[2]);
00257 
00258                                 while( (i<nargs) && (strncmp( argv[i], "--duv_args=", 11) )){
00259                                         
00260                                         ref_argv[j] = (char*)malloc(strlen(argv[i])+1);
00261                                         strcpy(ref_argv[j], argv[i]);                                   
00262                                         dprintf("Storing  arg %s\n", ref_argv[j]);
00263                                         i++;
00264                                         j++;
00265                                 }
00266                                 dprintf("Reference running application will receive %d arguments\n", j-2);
00267                                 ref_argv[j] = NULL;
00268                         }
00269 
00270                         if( !strncmp( argv[i], "--duv_args=", 11) ){  //There are duv model args
00271                                 
00272                                 //Storing DUV model running app args
00273                                 dprintf("Storing DUV model running app args\n");
00274                                 duv_argv[2] = (char*)malloc(strlen(argv[i]) - 10); //1st arg is after the '=' signal
00275                                 strcpy(duv_argv[2], argv[i]+11);
00276                                 i++;
00277                                 j=3;
00278                                 dprintf("Storing  arg %s\n", duv_argv[2]);
00279                                 
00280                                 while( (i<nargs) && (strncmp( argv[i], "--ref_args=", 11) )){
00281                                         duv_argv[j] = (char*)malloc(strlen(argv[i])+1);
00282                                         strcpy(duv_argv[j], argv[i]);                                   
00283                                         dprintf("Storing  arg %s\n", duv_argv[j]);
00284                                         i++;
00285                                         j++;
00286                                 }
00287                                 dprintf("DUV running application will receive %d arguments\n", j-2);
00288                                 duv_argv[j] = NULL;
00289                         }
00290                 }               
00291 
00292                 //Checking if both models were generated with the -v version.
00293                 //Running  models with --version option.
00294                 if( !(ref_pid = fork()) ){
00295                         execv(ref_argv[0], " --version 2>refout.tmp");
00296                 }
00297                 else{
00298                         if( !(duv_pid = fork()) ){
00299                                 execv(duv_argv[0], " --version 2>duvout.tmp");
00300                         }
00301                         else{
00302                                 //Waiting for the ref model to terminate
00303                                 waitpid(ref_pid,&ref_status,0);
00304 
00305                                 CheckOptions( REFERENCE_MODEL );
00306 
00307                                 //Waiting for the duv model to terminate
00308                                 waitpid(duv_pid,&duv_status,0);
00309 
00310                                 CheckOptions( DUV_MODEL );
00311                         }
00312                 }
00313 
00314 
00315                 //Now everything was checked. Let's start the co-verification process
00316                 //
00317 
00318                 /* Creating process for both models */
00319                 if( !(ref_pid = fork()) ){
00320                         execv(ref_argv[0], ref_argv);
00321                 }
00322                 else{
00323                         if( !(duv_pid = fork()) ){
00324                                 execv(duv_argv[0], duv_argv);
00325                         }
00326                         else{
00327 
00328                                 //Initializing both device lists
00329                                 dprintf("REFERENCE MODEL QUEUE (%d) INITIALIZATION:\n\n",ref_msqid);
00330                                 ListInit(&ref_devlist, ref_msqid, (struct start_msgbuf*)&ref_sbuf);
00331                                 dprintf("DUV MODEL QUEUE (%d) INITIALIZATION:\n\n",duv_msqid);
00332                                 ListInit(&duv_devlist, duv_msqid, (struct start_msgbuf*)&duv_sbuf);
00333 
00334                                 //Device list of both models (ref and duv) must have the same devices (number and names)
00335                                 CheckListConsistency();
00336 
00337                                 DoItOntheFly();
00338 
00339                                 waitpid(ref_pid,&ref_status,0);
00340 
00341                                 //TODO:Padronizar saida de erro
00342                                 if(!WIFEXITED(ref_status)){
00343                                         cerr << "Reference model returned with error"  <<endl;
00344                                         if(WIFSIGNALED(ref_status))
00345                                                 cerr << "Signal : " << WTERMSIG(ref_status)<<endl;
00346                                 }
00347 
00348                                 waitpid(duv_pid,&duv_status,0);
00349 
00350                                 if(!WIFEXITED(duv_status)){
00351                                         cerr << "DUV  model returned with error" << endl;
00352                                         if(WIFSIGNALED(duv_status))
00353                                                 cerr << "Signal : " << WTERMSIG(duv_status)<<endl;
00354                                 }
00355                         }
00356                 }
00357 
00358                 //Finalizing co-verification process
00359                 FinishIt();
00360 
00361                 //Run the co-verification....
00362     printf("Co-verification finished.\n");
00363 
00364                 //Deleting message queues
00365     if (msgctl(ref_msqid, IPC_RMID, NULL) == -1) {
00366         perror("msgctl");
00367         exit(1);
00368     }
00369 
00370     if (msgctl(duv_msqid, IPC_RMID, NULL) == -1) {
00371         perror("msgctl");
00372         exit(1);
00373     }
00374 
00375     return 0;
00376 }
00377 
00378 
00380 // Initialize the device list
00381 //
00382 // This function will get the first 
00383 // messages (see protocol bellow) incoming from a model and 
00384 // initialize its device list.
00386 
00388 // ArchC co-verification protocol:
00389 //
00390 // 1st MSG          : Number of devices being checked (N)
00391 // 2nd ... (N+1) MSG: Name of each device
00392 // (N+2) ...        : Update logs
00393 //
00394 // Type 1 are control messages
00395 // Type 2 are devices names do be verified
00396 // Type 3 ...  are types created for each device to be verified
00398 
00399 void ListInit( struct dev_list** model_devlist, int msqid, start_msgbuf *sbuf ){
00400 
00401         struct dev_msgbuf dbuf;
00402         struct dev_list *pdevlist;
00403         int i;
00404 
00405 
00406         //Processing first message...
00407         if (msgrcv(msqid, sbuf, sizeof(struct start_msgbuf), 0, 0) == -1) {
00408                 perror("msgrcv");
00409                 ABORT();
00410         }
00411         
00412         //First message must tell the number of devices to be supervised
00413         if( sbuf->mtype != 1 ){
00414                 AC_ERROR("Invalid initialization message: expecting type 1 (control), got type " << sbuf->mtype );
00415                 ABORT();
00416         }
00417                 
00418         dprintf("-->Number of devices: %d\n",sbuf->ndevice);
00419 
00420         //2nd ... (N+1) messages must tell the name of the devices to be supervised
00421         for( i=0; i< sbuf->ndevice;i++){
00422                 if (msgrcv(msqid, &dbuf, sizeof(dbuf), 0, 0) == -1) {
00423                         perror("msgrcv");
00424                         ABORT();
00425                 }
00426 
00427                 if( dbuf.mtype != 2 ){
00428                         AC_ERROR("Invalid initialization message: expecting type 2 (device), got type " << dbuf.mtype);
00429                         ABORT();
00430                 }
00431 
00432                 //Appending to the ref model device list.
00433                 pdevlist = new (struct dev_list);
00434                 pdevlist->dbuf = dbuf;
00435                 pdevlist->next = *model_devlist;
00436                 *model_devlist = pdevlist;
00437 
00438                 dprintf("-->Device (%d) name: %s\n", i+1,pdevlist->dbuf.name);
00439         }
00440 
00441 }
00442 
00444 // This function checks the consistency of//
00445 // device lists. Both ref and duv must be //
00446 // verifying the same storage devices     //
00448 void CheckListConsistency( ){
00449 
00450         struct dev_list *p1;
00451         struct dev_list *p2;
00452         struct dev_loglist *pll;
00453         unsigned next_type = 2 + ref_sbuf.ndevice;
00454 
00455         if( !ref_devlist || !duv_devlist ){
00456                 AC_ERROR("Uninitialized device lists.");
00457                 ABORT();
00458         }
00459 
00460         //First check the number of devices
00461         if( ref_sbuf.ndevice != duv_sbuf.ndevice ){
00462                 AC_ERROR("Uninitialized device lists.");
00463                 ABORT();
00464         }
00465 
00466         //Now check device names.
00467         for (p1 = ref_devlist; p1; p1=p1->next ){
00468 
00469                 for( p2 = duv_devlist; p2; p2=p2->next) {
00470                         if( !strcmp(p1->dbuf.name,p2->dbuf.name))
00471                                 break;
00472                 }
00473                 if( !p2 ){
00474                         //Didn't find p1 storage in duv's list
00475                         AC_ERROR("Device lists are not consistent. DUV model does not have a "<< p1->dbuf.name <<" device.");
00476                         ABORT();
00477                 }
00478 
00479                 //Everything is OK for this device, so create its log list
00480                 pll = new (struct dev_loglist);
00481                 pll->type = next_type--;  //Device list was created in inverted order, so first type to be processed is the last sent by the models
00482                 strcpy(pll->name, p1->dbuf.name);
00483                 pll->next = loglist;
00484                 loglist = pll;
00485                 dprintf("Adding device list for %s with type %d\n",pll->name,pll->type);
00486         }
00487                 
00488         dprintf("CheckListConsistency passed successfully.\n");
00489         
00490 }
00491 
00492 
00494 // The main co-verification loop
00496 void DoItOntheFly(){
00497 
00498         struct log_msgbuf lbuf;
00499         bool ref_finished=0, duv_finished=0;
00500         int ref_status, duv_status;
00501         int i;
00502 
00503         //Keep "listening" to the models and comparing update logs
00504         while( !ref_finished || !duv_finished ){
00505 
00506                 if( !ref_finished ){
00507                         
00508                         if (msgctl(ref_msqid, IPC_STAT, &ref_info) == -1) {
00509         perror("msgctl");
00510         ABORT();
00511                         }
00512                         
00513                         ddprintf("REF QUEUE INFO:\nr-w: %03o, cbytes= %1u, qnum= %1u, qbytes = %1u\n",
00514                                                         ref_info.msg_perm.mode & 0777, ref_info.msg_cbytes, ref_info.msg_qnum, ref_info.msg_qbytes);
00515                         
00516                         i = ref_info.msg_qnum;
00517 
00518                         //If there is nothing on the queue, the child may have exited. Check it
00519                         if( !i){
00520                                 waitpid(ref_pid,&ref_status,WNOHANG);
00521                                 if(WIFEXITED(ref_status)){
00522                                         dprintf("Matching logs ... Empty queue! Reference model exited!");
00523                                         if(WIFSIGNALED(ref_status))
00524                                                 dprintf("Signal :%d ", WTERMSIG(ref_status));
00525                                         ref_finished = 1;
00526                                 }
00527                         }
00528 
00529                         //Consuming ref queue msgs
00530                         while (i) {
00531 
00532                                 //Listening to Reference model
00533                                 if (msgrcv(ref_msqid, &lbuf, sizeof(struct log_msgbuf), 0, 0) == -1) {
00534                                         perror("msgrcv");
00535                                         ABORT();
00536                                 }
00537                                 //              cerr << "Log received from ref: ";
00538                                 //              cerr << lbuf.log <<endl;
00539                                 if( lbuf.log.time == -1 ){
00540                                         ref_finished = 1;
00541                                         dprintf("Reference model has finished\n");
00542                                 }
00543                                 else{
00544                                         //Append to the device list
00545                                         AddLog(lbuf.mtype, lbuf.log, 0 );
00546                                 }
00547                                 i--;
00548                         }
00549                 }
00550 
00551                 if(!duv_finished){
00552 
00553                         //Gathering info about ref and duv queues
00554                         if (msgctl(duv_msqid, IPC_STAT, &duv_info) == -1) {
00555         perror("msgctl");
00556         ABORT();
00557                         }
00558                 
00559                         ddprintf("DUV QUEUE INFO:\nr-w: %03o, cbytes= %1u, qnum= %1u, qbytes = %1u\n",
00560                                                         duv_info.msg_perm.mode & 0777, duv_info.msg_cbytes, duv_info.msg_qnum, duv_info.msg_qbytes);
00561                         
00562                         i = duv_info.msg_qnum;
00563                         //If there is nothing on the queue, the child may have exited. Check it
00564                         if( !i){
00565                                 waitpid(duv_pid,&duv_status,WNOHANG);
00566                                 
00567                                 if(WIFEXITED(duv_status)){
00568                                         dprintf("Matching logs ... Empty queue! DUV  model exited!");
00569                                         if(WIFSIGNALED(duv_status))
00570                                                 dprintf("Signal : ", WTERMSIG(duv_status));
00571                                         
00572                                         duv_finished =1;
00573                                 }
00574                         }
00575 
00576                         //Consuming duv queue msgs
00577                         while (i) {
00578 
00579                                 //Listening to DUV model
00580                                 if (msgrcv(duv_msqid, &lbuf, sizeof(struct log_msgbuf), 0, 0) == -1) {
00581                                         perror("msgrcv");
00582                                         ABORT();
00583                                 }
00584                                 //              cerr << "Log received from DUV: ";
00585                                 //              cerr << lbuf.log <<endl;
00586                                 if( lbuf.log.time == -1 ){
00587                                         duv_finished = 1;
00588                                         dprintf("DUV model has finished\n");
00589                                 }
00590                                 else{
00591                                         
00592                                         //Append to the device list
00593                                         AddLog(lbuf.mtype, lbuf.log, 1 );
00594                                 }
00595                                 i--;
00596                         }
00597                 }
00598 
00599                 MatchLogs();
00600                 
00601         }
00602 }
00603 
00604 // //////////////////////////////////////
00605 // // The main co-verification loop
00606 // //////////////////////////////////////
00607 // void DoIt(){
00608 
00609 //      struct log_msgbuf lbuf;
00610 //      int received =0;
00611 //      int i;
00612 //      bool ref_finished;
00613 
00614 //      //Keep "listening" to the models and comparing update logs
00615 //      for(;;){
00616 
00617 //              //Gathering info about ref and duv queues
00618 //     if (msgctl(duv_msqid, IPC_STAT, &duv_info) == -1) {
00619 //         perror("msgctl");
00620 //         ABORT();
00621 //     }
00622                 
00623 //     if (msgctl(ref_msqid, IPC_STAT, &ref_info) == -1) {
00624 //         perror("msgctl");
00625 //         ABORT();
00626 //     }
00627                 
00628 //              dprintf("REF QUEUE INFO:\nr-w: %03o, cbytes= %1u, qnum= %1u, qbytes = %1u\n",
00629 //                                              ref_info.msg_perm.mode & 0777, ref_info.msg_cbytes, ref_info.msg_qnum, ref_info.msg_qbytes);
00630 
00631 //              dprintf("DUV QUEUE INFO:\nr-w: %03o, cbytes= %1u, qnum= %1u, qbytes = %1u\n",
00632 //                                              duv_info.msg_perm.mode & 0777, duv_info.msg_cbytes, duv_info.msg_qnum, duv_info.msg_qbytes);
00633 
00634 //              if( ref_info.msg_cbytes >= 0.9*ref_info.msg_qbytes ){
00635                         
00636 //                      i = ref_info.msg_cbytes;
00637                         
00638 //                      cerr << "Log received from ref: "<< i <<" messages"<<endl;
00639 //                      while(i){
00640 //                              //Listening to Reference model
00641 //                              if (msgrcv(ref_msqid, &lbuf, sizeof(struct log_msgbuf), 0, 0) == -1) {
00642 //                                      perror("msgrcv");
00643 //                                      ABORT();
00644 //                              }
00645 
00646 //                              if( lbuf.log.time == -1 ){
00647 //                                      ref_finished = 1;
00648 //                               cerr << "Reference model has finished ";
00649 //                              //                                              cerr << lbuf.log <<endl;
00650 //                              }
00651 //                              //Append to the device list
00652 //                              AddLog(lbuf.mtype, lbuf.log, 0 );
00653 //                              i--;
00654 //                      }
00655 //                      received = 1;
00656 //              }
00657                 
00658 //              if( duv_info.msg_cbytes >= 0.9* duv_info.msg_qbytes ){
00659                         
00660 //                      i = duv_info.msg_cbytes;
00661                         
00662 //                      cerr << "Log received from duv: "<< i <<" messages"<<endl;
00663 //                      while(i){
00664 //                              //Listening to DUV model
00665 //                              if (msgrcv(duv_msqid, &lbuf, sizeof(struct log_msgbuf), 0, 0) == -1) {
00666 //                                      perror("msgrcv");
00667 //                                      ABORT();
00668 //                              }
00669 //                              //      cerr << "Log received from DUV: ";
00670 //                              //      cerr << lbuf.log <<endl;
00671                                 
00672 //                              //Append to the device list
00673 //                              AddLog(lbuf.mtype, lbuf.log, 1 );
00674 //                              i--;
00675 //                      }
00676 //                      received = 1;
00677 //              }
00678                 
00679 //              //Check consistency
00680 //              if( received ){
00681 //                      MatchLogs();
00682 //                      received =0;
00683 //              }
00684                 
00685 //      }
00686 // }
00687 
00689 // Add an update log to the corresponding
00690 // list.
00691 // device = 0 indicates operation on ref log
00692 // device = 1 indicates operation on duv log
00694 void AddLog( long type, change_log log, int device ){
00695 
00696         struct dev_loglist *pllist;
00697 
00698 
00699         for( pllist = loglist; pllist; pllist=pllist->next){
00700 
00701                 if( type == pllist->type ){
00702 
00703                         if( device )
00704                                 pllist->duv_log.push_back(log);
00705                         else
00706                                 pllist->ref_log.push_back(log);
00707 
00708                         break;
00709                 }
00710         }
00711 
00712         if( !pllist )
00713                 AC_ERROR("Invalid type ("<<type<<") in log message. Update ignored");
00714         
00715 }
00716 
00717 
00719 // Match reference and duv update logs
00721 void MatchLogs( ){
00722 
00723         struct dev_loglist *pllist;
00724   log_list::iterator refitor;
00725   log_list::iterator duvitor;
00726         bool flag,error=0;
00727 
00728         for( pllist = loglist; pllist; pllist=pllist->next){
00729 
00730                 if( pllist->duv_log.size() &&  pllist->ref_log.size()){
00731 
00732                         pllist->duv_log.sort();
00733                         pllist->ref_log.sort();
00734                         ddprintf("BEFORE MATCHING...\n");
00735                         ddprintf("Device %s -> Log size:  %d ref and %d duv\n", pllist->name, pllist->ref_log.size(), pllist->duv_log.size());
00736                         
00737 #ifdef DDEBUG
00738                         ChangeDump( pllist);
00739 #endif
00740                         refitor = pllist->ref_log.begin();
00741                         while( refitor != pllist->ref_log.end() ){
00742                                 
00743                                 duvitor = pllist->duv_log.begin();
00744                                 flag = false;
00745                                 
00746                                 while( /*(refitor->time == duvitor->time) &&*/ (duvitor != pllist->duv_log.end())){
00747                                         if( refitor->addr == duvitor->addr &&
00748                                                         refitor->value == duvitor->value ){
00749                                                 
00750                                                 refitor = pllist->ref_log.erase( refitor );
00751                                                 duvitor = pllist->duv_log.erase( duvitor );
00752                                                 flag = true;
00753                                                 break;
00754                                         }
00755                                         duvitor++;
00756                                 }
00757                                 //When we had a match, the iterator was incremented by the erase method
00758                                 if(!flag)
00759                                         refitor++;
00760                         }
00761 
00762                         ddprintf("AFTER MATCHING...\n");
00763                         ddprintf("Device %s -> Log size:  %d ref and %d duv\n", pllist->name, pllist->ref_log.size(), pllist->duv_log.size());
00764                         //Test if we already had too many erros (unmatched logs)
00765                         if( pllist->ref_log.size() >= AC_MAX_UNMATCHED || pllist->duv_log.size() >= AC_MAX_UNMATCHED )
00766                                 error = 1;
00767                 }
00768         }
00769         if(error){
00770                 dprintf("Too many erros founded. Aborting ...\n");
00771                 FinishIt();
00772                 ABORT();
00773         }
00774 }
00775 
00776 
00778 // Final Check to the reference and duv update logs
00780 void FinishIt(){
00781 
00782         struct dev_loglist *pllist;
00783 
00784         for( pllist = loglist; pllist; pllist=pllist->next){
00785 
00786                 if( pllist->duv_log.size() ||  pllist->ref_log.size()){
00787         
00788                         AC_ERROR("Co-verification FAILED. Reference and DUV models have inconsistent update logs for device "<< pllist->name);
00789                         cerr <<endl;
00790                         ChangeDump( pllist );
00791                 }
00792         }
00793 }
00794 
00796 // Dump logs on the err output. Used when co-verification
00797 // finds inconsistencies between two models
00799 void ChangeDump( struct dev_loglist *pllist ) {
00800 
00801   log_list::iterator itor;
00802         
00803     
00804   if(  pllist->ref_log.size() ){
00805                 cerr <<endl << endl;
00806     cerr << "**************** ArchC Change log *****************\n";
00807     cerr << "* Reference Model         Device: "<< pllist->name << endl;
00808     cerr << "***************************************************\n";
00809     cerr << "*        Address         Value          Time      *\n";
00810     cerr << "***************************************************\n";
00811       
00812     for( itor = pllist->ref_log.begin(); itor != pllist->ref_log.end(); itor++)  
00813       cerr << "*  " << *itor << "     *" << endl;
00814       
00815     cerr << "***************************************************\n";
00816   }
00817 
00818   if(  pllist->duv_log.size() ){
00819                 cerr <<endl << endl;
00820     cerr << "**************** ArchC Change log *****************\n";
00821     cerr << "* DUV Model         Device: "<< pllist->name << endl;
00822     cerr << "***************************************************\n";
00823     cerr << "*        Address         Value          Time      *\n";
00824     cerr << "***************************************************\n";
00825       
00826     for( itor = pllist->duv_log.begin(); itor != pllist->duv_log.end(); itor++)  
00827       cerr << "*  " << *itor << "     *" << endl;
00828       
00829     cerr << "***************************************************\n";
00830   }
00831 
00832 }
00833 
00835 // Check if both models were generated with the correct 
00836 // command-line options. For now, the only obligatory
00837 // option is -v
00839 void CheckOptions( int model ) {
00840 
00841         ifstream input;
00842   string read;
00843         char *filename;
00844         char* p;
00845         bool erro;
00846 
00847         if(model == REFERENCE_MODEL)
00848                 filename = "refout.tmp";
00849         else
00850                 filename = "duvout.tmp";
00851 
00852         input.open(filename);
00853 
00854   if(!input){
00855     AC_ERROR("Could not open input file: " << filename);
00856     AC_ERROR("Command-line option checker aborted.");
00857     exit(1);
00858   }
00859                 
00860         getline(input, read);
00861         if( p = strstr( read.c_str(), "(")){
00862                 
00863                 if( strstr( p, "-v") ||strstr( p, "-v)") )
00864                         return;
00865         }
00866 
00867         //If we got here, the command-line options were incorrect.      
00868         if(model == REFERENCE_MODEL)
00869                 AC_ERROR("Reference Model is not prepared for co-verification.\n");
00870         else
00871                 AC_ERROR("DUV Model is not prepared for co-verification.\n");
00872 
00873         AC_MSG("   Run acpp with the -v option for generating models on co-verification mode");
00874         exit(1);
00875                                 
00876 }

Generated on Thu Jun 24 08:30:05 2004 for ArchC by doxygen 1.3.4