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
| Documentation generated on Mon Nov 25 15:25:01 2002 |
Generated with doxygen 1.2.12 by Dimitri van Heesch , 1997-2001 |