Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

PsnPvmSvm.cxx

Go to the documentation of this file.
00001 /*
00002  * This file is part of openMask © INRIA, CNRS, Universite de Rennes 1 1993-2002, thereinafter the Software
00003  * 
00004  * The Software has been developped within the Siames Project. 
00005  * INRIA, the University of Rennes 1 and CNRS jointly hold intellectual property rights
00006  * 
00007  * The Software has been registered with the Agence pour la Protection des
00008  * Programmes (APP) under registration number IDDN.FR.001.510008.00.S.P.2001.000.41200
00009  *  
00010  * This file may be distributed under the terms of the Q Public License
00011  * version 1.0 as defined by Trolltech AS of Norway and appearing in the file
00012  * LICENSE.QPL included in the packaging of this file.
00013  *
00014  * Licensees holding valid specific licenses issued by INRIA, CNRS or Université de Rennes 1 
00015  * for the software may use this file in accordance with that specific license
00016  *
00017  */
00018 #ifdef _PVM
00019 #include <unistd.h>
00020 #include <stdio.h>
00021 #include <PsnPvmSvm.h>
00022 
00023 #include <Psn.h>
00024 #include <pvm3.h>
00025 #include <PsnProcess.h>
00026 #include <PsnPvmSvmLink.h>
00027 #include <PsnPvmMessage.h>
00028 #include <PsController.h>
00029 
00030 int PsnPvmSvm::pvmDataEncoding = PvmDataDefault ;
00031 int PsnPvmSvm::pvmSpawnFlags = PvmTaskHost ;
00032 //--------------------------------------------------------------------
00033 
00034 PsnPvmSvm::PsnPvmSvm (PsNameToPointerMap<PsnProcess> * tab, const PsDate & latence, int argc, char * argv [])
00035    : PsnSvm (tab, latence),
00036      _argc ( argc),
00037      _argv ( argv )
00038 {
00039   _siteId = pvm_mytid () ;
00040 }
00041 
00042 //--------------------------------------------------------------------
00043 
00044 PsnPvmSvm::~PsnPvmSvm () 
00045 {
00046    // do not wait for output of spawned tasks to be written
00047    pvm_catchout (0) ;
00048    
00049    // signal end of pvm to the pvm deamon
00050    pvm_exit () ;
00051 
00052 }
00053 
00054 void PsnPvmSvm::joinSvmGroup ( string & groupName ) 
00055 {
00056   int resul = pvm_joingroup ( const_cast<char *> (groupName.c_str()) ) ;
00057   if ( resul < 0 )
00058     {
00059       cerr<<"PsnPvmSvm::joinSvmGroup ERROR: ";
00060       switch ( resul )
00061         {
00062         case PvmSysErr: 
00063           cerr<<"pvmd was not started or has crashed.";
00064           break;
00065         case PvmBadParam:
00066           cerr<<"giving a NULL group name.";
00067           break;
00068         case PvmDupGroup:
00069           cerr<<"trying to join a group you are allready in.";
00070           break;
00071         default:
00072           cerr<<"unexpected error: "<<resul;
00073         }
00074       if (PsController::warningLevel >=  PsController::FatalWarnings) 
00075         {             
00076           exit (2) ;
00077         }
00078       cerr<<endl;
00079     }
00080 }
00081 
00082 
00083 void PsnPvmSvm::groupBarrier (string groupName, int numberToJoin)
00084 {
00085    //   cerr<<"PsnPvmSvm::groupBarrier: Waiting for "<<_numberOfSlaves<<" in pvm group named _"<<groupName.c_str()<<"_"<<endl;
00086   int resul = pvm_barrier ( const_cast<char *> (groupName.c_str()), numberToJoin) ;
00087   //cerr<<"PsnPvmSvm::groupBarrier: Waiting done"<<endl;
00088   if ( resul < 0 )
00089     {
00090       cerr<<"PsnPvmSvm::groupBarrier ERROR: ";
00091       switch ( resul )
00092         {
00093         case PvmSysErr: 
00094           cerr<<"pvmd was not started or has crashed.";
00095           break;
00096         case PvmBadParam:
00097           cerr<<"giving a numberToJoin < 1.";
00098           break;
00099         case PvmNoGroup:
00100           cerr<<"giving a non-existent group name.";
00101           break;
00102         case PvmNotInGroup:
00103           cerr<<"calling process is not in specified group.";
00104           break;
00105         default:
00106           cerr<<"unexpected error: "<<resul;
00107         }
00108       if (PsController::warningLevel >=  PsController::FatalWarnings) 
00109         {             
00110           exit (2) ;
00111         }
00112       cerr<<endl;
00113     }
00114 }
00115 
00116 
00117 
00118 void PsnPvmSvm::broadcastToGroup (string groupName, PsnPvmMessage::MessageTag tag)
00119 {
00120   int resul = pvm_bcast ( const_cast<char *> (groupName.c_str()), tag ) ;
00121   if ( resul < 0 )
00122     {
00123       cerr<<"PsnPvmSvm::broadcastToGroup ERROR: ";
00124       switch ( resul )
00125         {
00126         case PvmSysErr: 
00127           cerr<<"pvmd was not started or has crashed.";
00128           break;
00129         case PvmBadParam:
00130           cerr<<"giving a negative message tag.";
00131           break;
00132         case PvmNoGroup:
00133           cerr<<"giving a non-existent group name.";
00134           break;
00135         default:
00136           cerr<<"unexpected error: "<<resul;
00137         }
00138       if (PsController::warningLevel >=  PsController::FatalWarnings) 
00139         {             
00140           exit (2) ;
00141         }
00142       cerr<<endl;
00143     }
00144 }
00145 
00146 void PsnPvmSvm::initBeforeMessagePacking ()
00147 {
00148   int resul = pvm_initsend ( PsnPvmSvm::pvmDataEncoding ) ;
00149   if ( resul < 0 )
00150     {
00151       cerr<<"PsnPvmSvm::initBeforeMessagePacking ERROR: ";
00152       switch ( resul )
00153         {
00154         case PvmBadParam:
00155           cerr<<"giving a invalid encoding value.";
00156           break;
00157         case PvmNoMem:
00158           cerr<<"Malloc has failed. There is not enough memory to create the buffer";
00159           break;
00160         default:
00161           cerr<<"unexpected error: "<<resul;
00162         }
00163       if (PsController::warningLevel >=  PsController::FatalWarnings) 
00164         {             
00165           exit (2) ;
00166         }
00167       cerr<<endl;
00168     }
00169 }
00170 
00171 int PsnPvmSvm::nonblockingReceive (PsnPvmMessage::MessageTag tag) 
00172 {
00173 #ifdef _DEBUGPVMMESS
00174   cerr<<"PsnPvmSvm::nonblockingReceive ("<<tag<<")" <<endl;
00175 #endif
00176   int res = 0 ;
00177   int bufid = pvm_nrecv (-1, tag) ;
00178   while ( bufid > 0)
00179     {
00180       ++res ;
00181       bufid = pvm_nrecv (-1, tag) ;
00182     }
00183   if ( bufid < 0 )
00184     {
00185       cerr<<"PsnPvmSvm::nonblockingReceive ERROR: ";
00186       switch ( bufid )
00187         {
00188         case PvmBadParam:
00189           cerr<<"giving a invalid encoding tid value or msgtag.";
00190           break;
00191         case PvmSysErr:
00192           cerr<<"pvmd not responding.";
00193           break;
00194         default:
00195           cerr<<"unexpected error: "<<bufid;
00196         }
00197       if (PsController::warningLevel >=  PsController::FatalWarnings) 
00198         {             
00199           exit (2) ;
00200         }
00201       cerr<<endl;
00202    }
00203   return res ;
00204 }
00205 
00206 
00207 
00208 pair<PsnPvmMessage::MessageTag, int> 
00209 PsnPvmSvm::waitForAnyRequests (PsnPvmIncomingMessage & receiveBuffer) 
00210 {
00211   pair<PsnPvmMessage::MessageTag, int> result ;
00212   
00213   int bufid = pvm_recv ( -1, -1 ) ; //receive anything
00214 
00215   if ( bufid < 0 ) 
00216     {
00217       cerr<<"PsnSvm::waitForAnyRequests ERROR ";
00218       switch (bufid)
00219         {
00220         case PvmBadParam:
00221           cerr<<"giving an invalid tid value, or msgtag < -1";
00222           break;
00223         case PvmSysErr:
00224           cerr<<"pvmd not responding";
00225           break;
00226         default:
00227           cerr<<"unexpected error";
00228           if (PsController::warningLevel >=  PsController::FatalWarnings) 
00229             {         
00230               exit (2) ;
00231             }
00232         }
00233       cerr<<endl;
00234     }
00235 
00236   int bytes ;
00237   int senderSiteId ;
00238   int msgtag ;
00239   int info = pvm_bufinfo( bufid, &bytes , &msgtag , &result.second  );
00240   result.first = static_cast<PsnPvmMessage::MessageTag>(msgtag) ;
00241   if ( info < 0 ) 
00242     {
00243       cerr<<"PsnSvm::waitForAnyRequests ERROR in pvm_bufinfo ";
00244       switch (info)
00245         {
00246         case PvmBadParam:
00247           cerr<<"invalid argument";
00248           break;
00249         case PvmNoSuchBuf:
00250           cerr<<"specified buffer does not exist";
00251           break;
00252         default:
00253           cerr<<"unexpected error";
00254           if (PsController::warningLevel >=  PsController::FatalWarnings) 
00255             {         
00256               exit (2) ;
00257             }
00258         }
00259       cerr<<endl;
00260     }
00261 
00262   receiveBuffer.initialise ( bufid ) ;
00263   
00264   return result ;
00265 }
00266 
00267 
00268 
00269 //--------------------------------------------------------------------
00270 
00271 int PsnPvmSvm::getSiteId () {
00272   assert ( _siteId >= 0 ) ;
00273   return _siteId ; 
00274 }
00275 
00276 //--------------------------------------------------------------------
00277 
00278 void PsnPvmSvm::addNewWorkstation (const PsName & m) {
00279    char * mac [2] ; // Machine a ajouter
00280    int res ; // Resultat du add_host
00281    int infos [2] ; // Informations sur chaque host
00282    int tentative = 0 ; // Numero de la tentative
00283    int nbTentative = 40 ; // On essaie 40 fois
00284 
00285    // here, const casting because pvm uses a C interface without const
00286    mac [0] = const_cast<char *> (m.getCString ()) ;
00287    mac [1] = (char *)NULL ;
00288 
00289    while (tentative < nbTentative) 
00290       {
00291          cout << "Tentative number " << tentative+1
00292               << " for machine " << mac [0] <<endl;
00293       res = pvm_addhosts (mac, 1, infos) ;
00294       if (res < 1) { // On a une erreur
00295          tentative++;
00296 
00297          if (infos[0] != PvmDupHost) 
00298            { 
00299              if (tentative >= nbTentative) 
00300                {
00301                  cerr << "Type d'erreur : " << res << endl;
00302                  cerr << "Infos[0] : " << infos[0] << endl;
00303                  cerr << "Machine : " << mac [0] << ", " << mac [1] << endl;
00304                  PsController::error( "PsnPvmSvm::addNewWorkstation: pb pour ajouter une machine");
00305                } 
00306              else 
00307                {
00308                  sleep (5) ;
00309                }
00310            } 
00311          else 
00312            { // workstation wasn't added because it is allready present !
00313              // no need to try more
00314              tentative = nbTentative;
00315            }
00316       } 
00317       else 
00318         { // On n'a pas d'erreur, on arrete d'essayer
00319           tentative = nbTentative;
00320           ++_numberOfSlaves ;
00321         }
00322    }
00323    cout << "Machine " << mac [0] << " added" << endl ;           
00324    //cout << "status of machine: "<<pvm_mstat(mac [0])<<endl;
00325 }
00326 
00327 //--------------------------------------------------------------------
00328 
00329 int PsnPvmSvm::getParentSiteId () {
00330    int tidCtrlGlo = pvm_parent () ;
00331    // options PVM:
00332    //pvm_setopt (PvmSelfTraceTid, tidCtrlGlo) ; 
00333    //pvm_setopt (PvmSelfTraceCode, 666) ; 
00334    //pvm_setopt (PvmSelfOutputTid, tidCtrlGlo) ; 
00335    //pvm_setopt (PvmSelfOutputCode, 667) ; 
00336    //pvm_catchout (stdout) ;
00337    // Message au format XDR
00338    pvm_initsend (pvmDataEncoding) ;
00339    if (tidCtrlGlo == PvmNoParent ) 
00340      {
00341        return 0 ;
00342      } 
00343    else 
00344      {
00345        assert ( tidCtrlGlo != 0 ) ; //for coherance
00346        return tidCtrlGlo ;
00347      }
00348 }
00349 
00350 //--------------------------------------------------------------------
00351 
00352 int PsnPvmSvm::spawnProcess (PsnProcess * p) 
00353 {
00354    assert ( _argv[_argc] == NULL ) ;
00355    //   char * argv [5] ;
00356    int tidCtrlLoc ;
00357 //     istrstream is (fConfig.getCString (), strlen (fConfig.getCString ())) ;
00358 //     argv [0] = new char [256] ;
00359 //     argv [1] = new char [256] ;
00360 //     argv [2] = new char [256] ;
00361 //     argv [3] = new char [256] ;
00362 //     is >> argv [0] >> argv [1] >> argv [2] >> argv [3];
00363 //     argv [4] = (char *)NULL ;
00364    int res = pvm_spawn (const_cast<char *>(_argv[0]), const_cast<char **>(&_argv[1]), pvmSpawnFlags,
00365                         (char*)(p->getHostMachineName ().getCString ()), 1, &tidCtrlLoc) ;
00366    if (res != 1) 
00367       {
00368          cout << "Executable : " << _argv[0] << endl ;
00369          //p->Executable ().getCString ()
00370          char ** argv = &_argv[1] ;
00371          for ( int i = 0 ; i < _argc-1 ; ++i) 
00372             {
00373                cout << "_argv ["<<i<<"] : " << argv[i] << endl ;
00374             }
00375          cout << "on machine: " << p->getHostMachineName ().getCString () << endl ;
00376          cout << "status of machine: "<<pvm_mstat(const_cast<char *>(p->getHostMachineName ().getCString ()))<<endl;
00377          cout << "tidCtrlLoc: " << tidCtrlLoc << endl ;
00378          cout << "Number of tasks started : " << res << endl ;
00379          PsController::error ("PsnPvmSvm::spawnProcess: spawn problem") ;
00380    }
00381    return (int)tidCtrlLoc ;
00382 }
00383 
00384 
00385 //--------------------------------------------------------------------
00386 
00387 void PsnPvmSvm::removeWorkstation (const PsName & m) 
00388 {
00389    int res ;
00390    char * mac [2] ;
00391    mac [0]= (char *)(m.getCString ()) ;
00392    mac [1] = (char *)NULL ;
00393    
00394    pvm_delhosts (mac, 1, &res) ;
00395 }
00396 
00397 //--------------------------------------------------------------------
00398 
00399 PsnSvmLink * PsnPvmSvm::createSvmLink (const int & d) 
00400 {
00401    PsnPvmSvmLink * canal = new PsnPvmSvmLink (d) ;
00402    return (PsnSvmLink*)canal;       
00403 }
00404 
00405 //--------------------------------------------------------------------
00406 #endif

logo OpenMask

Documentation generated on Mon Nov 25 15:25:01 2002

Generated with doxygen 1.2.12 by Dimitri van Heesch ,   1997-2001