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

PsReactGlobalController.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 _REACT
00019 #include <PsReactGlobalController.h>
00020 #include <PsReactController.h>
00021 #include <PsArbreSimul.h>
00022 #include <PsSimulatedObject.h>
00023 #include <PsCalculus.h>
00024 #include <vector>
00025 
00026 PsReactGlobalController * PsReactGlobalController::controleurUnique =NULL;
00027 frs_t * PsReactGlobalController::frs =NULL;
00028 
00029 // PsnControlLocal::PsnControlLocal
00030 //--------------------------------------------------------
00031 PsReactGlobalController::PsReactGlobalController(const PsName & processName, PsObjectDescriptor* scenario,PsKernelObjectAbstractFactory * aFactory) : PsController(aFactory)
00032 {
00033   PsReactGlobalController::controleurUnique=this;
00034   PsController::stop=monError;  
00035   arbreObjets= scenario;
00036   nbFils=atoi(processName.getCString());
00037   idObjet=_simulationTree.find(PSNOMRAC);
00038   idObjet->setPointerToSimulatedObject(this);
00039   controleur=this;
00040   // initialisations du controleur global
00041   // a faire avant les init de objets de calcul...
00042   processNameessus="ControleurReactGlobal";
00043   
00044   // initialisation de l'état du controleur
00045   *_computeStatePointer=PsnReferenceObjectHandle::running;
00046     
00047 }
00048 
00049 class AgregatTriable {
00050 public:
00051   PsObjectDescriptor * arbreSimul;
00052   int poids;
00053   AgregatTriable() {};
00054   AgregatTriable(PsObjectDescriptor * id) {
00055     arbreSimul=id;
00056     poids=id->getNbDescendants()+1; //pas de modules de poids nul.
00057   }
00058   friend int operator < (const AgregatTriable &Source1,const AgregatTriable &Source2) {
00059       return Source1.poids>Source2.poids;
00060   }
00061   friend istream &operator >> (istream &flot, AgregatTriable at) {
00062     return flot;
00063   };
00064   friend ostream & operator<< (ostream & flot, const AgregatTriable at) {
00065      flot<<at.arbreSimul->get()->Nom()<<" de poids "<<at.poids<<endl;
00066     return flot;
00067   }
00068 };
00069 
00070 
00071 PsCalculus * PsReactGlobalController::createCalculus () {
00072 
00073   /* Partition de l'arbre de simulation entre les différents processus
00074    * L'algorithme est le suivant :
00075    * On obtient une liste des modules et des sous-arbres pouvant être calculé en parallèle toutesLesSeq
00076    * On associe un poids à chacun (le nombre des descendants + 1)
00077    * On trie la liste obtenue par ordre décroissant de poids
00078    * On maintient à jour une liste des poids par processus (tabPoids)
00079    * On affecte le module ou le sousarbre de plus grand poids non-encore affecté à un processus au processus ayant le moins de poids.
00080    */
00081 
00082   PsString processus("ProcCtrlReact"); //pour fabriquer des noms de processus des controleurs fils
00083   PsString nomObjet("ObjCtrlReact");//pour fabriquer les noms des controleurs fils
00084   char cpt('0'); //pour construire des noms uniques
00085   PsString unique;//idem
00086   PsString tmp1;
00087   PsObjectDescriptor * idTmp;//pour construire les identifiants des controleurs fils
00088   PsObjectDescriptor * arbreTmp;//pour construire les arbre des controleurs fils
00089   vector <PsObjectDescriptor * > * lesFils;//La liste des fils de la racine
00090 
00091 
00092   //initialisation des structures de données utilisées.
00093   lesFils=new vector<PsObjectDescriptor *>;
00094   int tabPoids[nbFils];              //la table des poids qu'il faut maintenir
00095   for(int i=0;i<nbFils;i++) {
00096     tabPoids[i]=0;
00097     idTmp=new PsObjectDescriptor((nomObjet+((char)(cpt+i))),
00098                          "ControleurReactLocal",
00099                          processus+((char)(cpt+i)),
00100                          0,
00101                          0,
00102                          FALSE);
00103 #ifdef _DEBUG
00104     cout<<"nom généré : "<<idTmp->Nom()<<endl;
00105 #endif
00106     arbreTmp=new PsObjectDescriptor(idTmp);
00107     lesFils->push_back(arbreTmp);
00108   }
00109 
00110   //construction de la liste des modules et des sous-arbres parallèles
00111   PsList <PsObjectDescriptor *> * toutesLesSeq=_simulationTree.listeUniteSequentielles();
00112   PsList <PsObjectDescriptor *>::iterator itrl;
00113   PsList <AgregatTriable> * listeSeq;//La liste trie selon leur poids des modules et des sous-arbres parallèles
00114   listeSeq = new PsList <AgregatTriable>;
00115   for (itrl=toutesLesSeq->begin();itrl!=toutesLesSeq->end();itrl++) {
00116     AgregatTriable * temp;
00117     temp=new AgregatTriable(*itrl);
00118     listeSeq->insert(*temp);
00119   }
00120   listeSeq->sort();
00121 #ifdef _DEBUGPAR
00122   cout<<"Liste des poids "<<endl;
00123   listeSeq->afficher();
00124 #endif
00125   //L'affectation aux processeurs
00126   for (PsList <AgregatTriable>::iterator elemCour=listeSeq->begin();
00127        elemCour!=listeSeq->end();
00128        elemCour++) {
00129     int indicePlusFaiblePoids=0;
00130     int plusFaiblePoids=tabPoids[0];
00131     for (i=1;i<nbFils;i++) {
00132       if (tabPoids[i]<plusFaiblePoids) indicePlusFaiblePoids=i;
00133     }
00134     tabPoids[indicePlusFaiblePoids]+=elemCour->poids;
00135 
00136 //      unique=(char)cpt+indicePlusFaiblePoids;
00137 //      tmp1=process+unique;
00138     if(elemCour->arbreSimul->el->Sequence()) {
00139       elemCour->arbreSimul->ChangerProcessusSousArbre((*lesFils)[indicePlusFaiblePoids]->el->Nom());
00140     }
00141     else {
00142       elemCour->arbreSimul->ChangerProcessus((*lesFils)[indicePlusFaiblePoids]->el->Nom());
00143     }
00144   }
00145 
00146   //rebranchement de l'arbre de simulation
00147   //les fils de la racine deviennent les controleurs react locaux
00148   vector <PsObjectDescriptor * > * listeftmp=_simulationTree.echangerFils(lesFils);
00149   vector <PsObjectDescriptor * >::iterator iter; 
00150   for(iter=lesFils->begin();iter!=lesFils->end();iter++) {
00151     (*iter)->echangerFils(listeftmp); //les fils des controleurs sont les anciens fils de la racine
00152   }
00153 
00154   /* calcul de la frequency du controleur (lcm des freqs de ref.)
00155    * Obtention de la liste des modules
00156    * Calcul de _cycleFrequency, _stepFrequency et surtout _stepPeriod, nbMinor
00157    */
00158   PsList<PsFrequency> * listeFreq= new PsList<PsFrequency>;
00159   _simulationTree.listeToutesFrequencys(listeFreq);
00160 #ifdef _DEBUG
00161   listeFreq->afficher();
00162 #endif
00163   PsList<PsFrequency>::iterator pListe;
00164   PsFloat facUB = facSecUnite(UBASE);  
00165   int freq;
00166   _stepFrequency= 1;
00167   _cycleFrequency=0;
00168   for (pListe= listeFreq->begin();
00169        pListe != listeFreq->end(); 
00170        pListe++)
00171     {
00172       freq=pListe->getValue();
00173       if (freq!=0) {//si freq=0, c'est la frequency non initialisé d'un des controleurs
00174         _cycleFrequency=gcd(freq,_cycleFrequency);
00175         _stepFrequency=(int)((freq*_stepFrequency.getValue())/gcd(freq,_stepFrequency.getValue()));  //lcm(freq,_stepFrequency);
00176       }
00177     }
00178   _stepPeriod= int(1000./_stepFrequency);
00179   nbMinor= _stepFrequency/_cycleFrequency;
00180   // calcul du pas de temps 
00181   dt=  (PsDate) ( (1./_stepFrequency) * facUB);   
00182   /* Creation des PsncontroleurReactLocal
00183    * createCalculus
00184    */
00185   for (i=0;i<nbFils;i++) {
00186     PsObjectDescriptor * arbreTmp;
00187     arbreTmp=(*lesFils)[i];
00188     arbreTmp->get()->frequency=_stepFrequency;
00189     PsReactController * tmp=new PsReactController(arbreTmp,_stepPeriod,nbMinor,this,i+1,kernelObjectFactory);
00190     arbreTmp->get()->setPointerToSimulatedObject(tmp);
00191     tmp->createCalculus();
00192   }
00193   return NULL;
00194 }
00195 
00196 
00197 
00198 //----------------------------------------------------------
00199 // desctructeur
00200 
00201 PsReactGlobalController::~PsReactGlobalController() {
00202   delete barStart;
00203   delete barFrsStart;
00204 }
00205 
00206 void PsReactGlobalController::init() {
00207   PsObjectDescriptor::iterator i;
00208   int nbDesc=_simulationTree.getNbDescendants();
00209   nbDesc=(int)((nbDesc-nbFils)/nbFils);
00210   barFrsStart=new PsnBarrier(nbFils+1);
00211   barStart=new PsnBarrier(nbDesc+nbFils+1);
00212 #ifdef _DEBUG
00213   cout<<"nombres de threads attendus à la barriere de synchro : "
00214       <<nbDesc+nbFils+1
00215       <<endl;
00216 #endif
00217   for (i=_simulationTree.begin();
00218        i!=_simulationTree.end();
00219        i++) {
00220     //initialisation de l'alias sur barStart
00221     ((PsReactController *)(*i)->get()->getPointerToSimulatedObject())->barStart=barStart;
00222     (*i)->get()->getPointerToSimulatedObject()->traiterEvt();
00223     (*i)->get()->getPointerToSimulatedObject()->init();
00224   }
00225 }
00226 void PsReactGlobalController::run() {
00227    advanceSimulatedDate();
00228    compute();
00229 }
00230 
00231 void PsReactGlobalController::compute() {
00232   PsObjectDescriptor::iterator i;
00233   int ret;
00234   barFrsStart->Sync();
00235 #ifdef _DEBUG
00236   cout<<"PsReactGlobalController::compute::passage de barFrsStart"<<endl;
00237 #endif
00238   barStart->Sync();
00239 #ifdef _DEBUG
00240   cout<<"PsReactGlobalController::compute::passage de barStart"<<endl;
00241 #endif
00242   for (i=_simulationTree.begin();
00243        i!=_simulationTree.end();
00244        i++) {
00245      ret=pthread_join(((PsReactController *)(*i)->get()->getPointerToSimulatedObject())->id_pthread_controleur,0);
00246      if (ret)
00247         {
00248            error("PsnControlLocal : run : join failed");
00249         }
00250      else {
00251         cout<<"thread controleur terminé"<<endl;
00252      }
00253   }
00254 }
00255 
00256 int  PsReactGlobalController::NbFils() {
00257   return nbFils;
00258 }
00259 const PsEvenement & PsReactGlobalController::nouvelEvt (const PsEvenement & evenement) {
00260   switch(evenement.evt) {
00261   case Mask_STOP:
00262   case Mask_DELETE:
00263   case Mask_SUSPEND:
00264     monError();
00265     break;
00266   default:
00267     error("événement système non géré");
00268   }
00269   return evenement;
00270 }
00271 
00272 void PsReactGlobalController::monError() {
00273    //un seul frs_stop est nécessaire
00274    //frs_destroy sur le controleur maitre doit être fait en dernier
00275   PsObjectDescriptor::iterator i;
00276   frs_stop(frs);//arrêt de la simulation
00277   frs_t * frsneedsDelete;
00278   for (i=controleurUnique->_simulationTree.begin();
00279        i!=controleurUnique->_simulationTree.end();
00280        i++) {
00281     ((PsReactController *)(*i)->get()->getPointerToSimulatedObject())->*_computeStatePointer=PsnReferenceObjectHandle::stopped;
00282     frsneedsDelete=((PsReactController *)(*i)->get()->getPointerToSimulatedObject())->frs;
00283     if(frsneedsDelete!=frs) {
00284        frs_destroy(frsneedsDelete);
00285     }
00286   }
00287   frs_destroy(frs); //on détruit le FRS maitre en dernier
00288   exit(1);
00289 }
00290 
00291 //  #ifdef _REACT
00292 //  #define frs_abort(x) exit(x)
00293 //  bool PsReactGlobalController::fin=FALSE;
00294 //  PsnSemaphore PsReactGlobalController::sem_fin_clavier=PsnSemaphore(0);
00295 //  frs_t * PsReactGlobalController::frs=NULL;
00296 
00297 //  void PsnControlLocal::run()
00298 //  {
00299 //    // Phase de preparation de la simulation
00300 //    //======================================
00301 //    //mise en place de la barrière de synchro qui permet d'attendre que tous les threads soient placés sur leur file d'exécution avant le démarrage, c'est a dire tous les modules plus le temps, le time la gui et le controleur
00302 //  #ifdef _PSGUI1
00303 //    bar=new PsnBarrier(nb_modules+4);
00304 //  #else
00305 //    bar=new PsnBarrier(nb_modules+3);
00306 //  #endif
00307 //  #ifdef _PSGUI1 //dans le cas des processus légers
00308   
00309 //    // attente de l'ordre utilisateur de demarrage de la simulation
00310 //    while(*_computeStatePointer==PsnReferenceObjectHandle::initial){ 
00311 //      // gestion des demandes de l'utilisateur au niveau controle
00312 //      appliIlv->gestEvtUI();
00313 //      // pour tous les referentiels gestion de l'interface utilisateur
00314 //      PsnListeModuleElem * pListe;
00315 //      for (pListe= _referenceObjectsList->superListBegin(); pListe!=NULL ; pListe=superListNext(pListe)){
00316 //        (*pListe).listeElem->objetSimul()->Calcul()->runUserInterfaceDuringInit();
00317 //      }
00318 //    }
00319 //  #endif
00320 //  #ifdef _SPROC
00321 //    id_thread_controleur=sproc(Thread_controleur,PR_SALL, (void *)this);
00322 //    if(id_thread_controleur== -1) {
00323 //      perror("PsnControlLocal :: run :: impossible de créer le thread controleur");
00324 //      exit(1);
00325 //    }
00326 //  #else //pas de visu donc utilisation des threads posix
00327 //    // Le thread lancant le FRS doit avoir la porté d'un thread system : initialisation des attributs
00328 //    int ret=pthread_attr_init(&attributs_pthread);
00329 //    if (ret) {
00330 //      perror("impossible d'initialiser les attributs du thread");
00331 //    } 
00332 //    ret=pthread_attr_setscope(&attributs_pthread, PTHREAD_SCOPE_SYSTEM);
00333 //    if (ret) {
00334 //      perror("Impossible de créer des threads system");
00335 //    }
00336 //    // Mise en place du FRS
00337 //    ret = pthread_create(&id_pthread_controleur,
00338 //                     &attributs_pthread,
00339 //                     (void *(*)(void *)) Thread_controleur,
00340 //                     this);
00341 //    if (ret) {
00342 //      error("PsnControlLocal : run : impossible de créer le thread_controleur");
00343 //      frs_abort(1);
00344 //    }
00345 //  #endif //cas react - gui
00346 //    cout << "PsnControlLocal : run : fin de l'initialisation"<<endl;
00347 //  #endif
00348 
00349 //  #ifdef _REACT
00350 //  #ifdef _SPROC
00351 //    int ret=1;
00352 //  #ifdef _DEBUG
00353 //    int pid=0;
00354 //    cout<<"PsnControlLocal::run::on va attendre"<<endl;
00355 //    pid=wait(&ret);
00356 //    cout<<"PsnControlLocal::run::on a termin'e avec le thread controleur "<<pid<<endl;
00357 //  #else
00358 //    wait(&ret);
00359 //  #endif
00360 //    if (ret == -1) { 
00361 //      perror("PsnControlLocal :: run :: impossible d'attendre la fin du controleur ");
00362 //    }
00363 //  #else
00364 //    if (ret=pthread_join(id_pthread_controleur,0)) {
00365 //      error("PsnControlLocal : run : join failed");
00366 //    }
00367 //  #endif
00368 //    cout<<"PsnControlLocal : run : fin de la simulation"<<endl;
00369 //    sem_fin_clavier.V(); //gestion du SIGINT
00370 //  } //run
00371 
00372 //  //  void PsnControlLocal::computeNextSimulationStepGUI() {
00373 //  //  #ifdef _REACT
00374 //  //    if (pause) {
00375 //  //      frs_stop(frs);
00376 //  //      do {
00377 //  //        runUserInterface();
00378 //  //      }
00379 //  //      while(pause);
00380 //  //      frs_resume(frs);
00381 //  //    }
00382 //  //  #else
00383 //  //    if (pause==FALSE){
00384 //  //      computeNextSimulationStep();
00385 //  //    }
00386 //  //  #endif
00387 //  //  }
00388 
00389 //  // Le corps du thread chargé de gérer le FRS et d'initialiser tout.
00390 //  #ifdef _SPROC
00391 //  void PsnControlLocal::Thread_controleur(void *controleurv) {
00392 //  #else
00393 //  void *PsnControlLocal::Thread_controleur(void *controleurv) {
00394 //  #endif
00395 //    PsNameToPointerMap<PsnReferenceObjectHandle>::iterator pTab;
00396 //    int ret;  
00397 //    int minor;
00398 //    int freq;
00399 //  #ifndef _SPROC
00400 //    pthread_attr_t attributs_pthread;
00401 //  #endif
00402 //    PsnControlLocal *controleur=(PsnControlLocal *)controleurv;
00403 //  #ifndef _SPROC
00404 //    ret=pthread_attr_init(&attributs_pthread);
00405 //    if (ret) {
00406 //      perror("PsnControlLocal : Thread_controleur : impossible d'initialiser les attributs du thread");
00407 //    } 
00408 //    ret=pthread_attr_setscope(&attributs_pthread, PTHREAD_SCOPE_SYSTEM);
00409 //    if (ret) {
00410 //      perror("PsnControlLocal : Thread_controleur : Impossible de créer des threads system");
00411 //    }
00412 //  #endif
00413 //      /* 
00414 //       * Creation du frs controleur maitre
00415 //       * cpu = 1
00416 //       * source d'interruption = CCTIMER
00417 //       * nb de minor frames = nbminor
00418 //       * frs esclaves : aucun
00419 //       * period = _stepPeriod [ms]
00420 //       */
00421 //    cout<<"PsnControlLocal : Thread_controleur : params de frs create master "<<controleur->_stepPeriod*1000<<" et "<<controleur->nbMinor<<endl;
00422 //    controleur->frs = frs_create_master(3,     //numero du CPU de APP (le frame sheduler)
00423 //                                    FRS_INTRSOURCE_CCTIMER,
00424 //                                    controleur->_stepPeriod*1000,
00425 //                                    controleur->nbMinor,
00426 //                                    0);
00427 //    if(controleur->frs==NULL) {
00428 //      perror("PsnControlLocal : ThreadControleur : impossible de creer le frs");
00429 //      exit(0);
00430 //    }
00431 //    cout <<"PsnControlLocal : Thread_controleur : frame scheduler crée"<<endl;
00432 
00433 
00434 //  #ifdef _SPROC
00435 //    controleur->id_thread_time=sproc(Thread_Time,PR_SALL,(void *) controleur);
00436 //    if(controleur->id_thread_time==-1) {
00437 //      controleur->finFrs();
00438 //      perror("PsnControlLocal :: Thread_Controleur :: Impossible de creer le thread time");
00439 //      exit(0);
00440 //    }  
00441 //  #ifdef _DEBUG
00442 //    cout <<"PsnControlLocal : Thread_controleur : thread time crée "<<endl;
00443 //  #endif
00444 //    for(minor=0;minor<controleur->nbMinor;minor++) {
00445 //      ret=frs_enqueue(controleur->frs,
00446 //                  controleur->id_thread_time,
00447 //                  minor,
00448 //                  FRS_DISC_RT);
00449 //      //cout<<"PsnControlLocal : Thread_controleur : mise en file Thread_Time"<<endl;
00450 //      if (ret) {
00451 //        perror("PsnControlLocal : Thread_controleur : Impossible de mettre le Thread time dans la file d'execution");
00452 //        exit(0);
00453 //      }
00454 //    }
00455 //  #else
00456 //    //creation du thread Thread_time pour la gestion du temps
00457 //    ret=pthread_create(&(controleur->id_pthread_time),
00458 //                   &attributs_pthread,
00459 //                   Thread_Time,
00460 //                   (void *) controleur);
00461 //    if (ret) {
00462 //      perror("PsnControlLocal : Thread_controleur : Impossible de creer le Thread Time");
00463 //      pthread_exit(0);
00464 //    }
00465 //  #ifdef _DEBUG
00466 //    cout <<"PsnControlLocal : Thread_controleur : thread time crée "<<endl;
00467 //  #endif
00468 //    //placement de ce thread en tête de toutes les files d'exécution
00469 //    for(minor=0;minor<controleur->nbMinor;minor++) {
00470 //      ret=frs_pthread_enqueue(controleur->frs,
00471 //                          controleur->id_pthread_time,
00472 //                          minor,
00473 //                          FRS_DISC_RT);
00474 //      //cout<<"PsnControlLocal : Thread_controleur : mise en file Thread_Time"<<endl;
00475 //      if (ret) {
00476 //        perror("PsnControlLocal : Thread_controleur : Impossible de mettre le Thread time dans la file d'execution");
00477 //        pthread_exit(0);
00478 //      }
00479 //    }
00480 //  #endif
00481 //    //creation du thread Thread_fin gérant la fin de la simulation
00482 //  #ifdef _SPROC
00483 //    controleur->id_thread_fin=sproc(Thread_Fin,PR_SALL,(void *) controleur);
00484 //    if(controleur->id_thread_fin==-1) {
00485 //      controleur->finFrs();
00486 //      perror("PsnControlLocal : Thread_controleur : creation du Thread_Fin impossible");
00487 //      frs_abort(1);
00488 //    }
00489 //  #ifdef _DEBUG
00490 //    cout <<"PsnControlLocal : Thread_controleur : thread fin crée avec l'id "<<controleur->id_thread_controleur<<endl;
00491 //  #endif
00492 //    //placement de ce thread un fois par frame majeure
00493 //    //disc est la discipline qui permet a un thread de s'éxécuter en avance si il le peut
00494 //    int disc= FRS_DISC_RT | FRS_DISC_UNDERRUNNABLE | FRS_DISC_OVERRUNNABLE | FRS_DISC_CONT;
00495 //    for(minor=0;minor<controleur->nbMinor-1;minor++) {
00496 //      ret=frs_enqueue(controleur->frs,
00497 //                  controleur->id_thread_fin,
00498 //                  minor,
00499 //                  disc);
00500 //      if (ret) {
00501 //        controleur->finFrs();
00502 //        perror("PsnControlLocal : Thread_controleur : Impossible de mettre le Thread fin dans la file d'execution");
00503 //        exit(0);
00504 //      }
00505 //    }
00506 //    ret=frs_enqueue(controleur->frs,
00507 //                controleur->id_thread_fin,
00508 //                controleur->nbMinor-1,
00509 //                FRS_DISC_RT);
00510 //    //cout<<"PsnControlLocal : Thread_controleur : mise en file Thread_Fin rt"<<endl;
00511 //    if (ret) {
00512 //      controleur->finFrs();
00513 //      perror("PsnControlLocal : Thread_controleur : Impossible de mettre le Thread_Fin dans la file d'execution");
00514 //      exit(0);
00515 //    }
00516 //  #else
00517 //    ret=pthread_create(&(controleur->id_pthread_fin),
00518 //                   &attributs_pthread,
00519 //                   Thread_Fin,
00520 //     (void *) controleur);
00521 //    if(ret) {
00522 //      error("PsnControlLocal : Thread_controleur : creation du Thread_Fin impossible");
00523 //      frs_abort(1);
00524 //    }
00525 //  #ifdef _DEBUG
00526 //    cout <<"PsnControlLocal : Thread_controleur : thread fin crée avec l'id "<<id_pthread<<endl;
00527 //  #endif
00528 //    //placement de ce thread un fois par frame majeure
00529 //    //disc est la discipline qui permet a un thread de s'éxécuter en avance si il le peut
00530 //    int disc= FRS_DISC_RT | FRS_DISC_UNDERRUNNABLE | FRS_DISC_OVERRUNNABLE | FRS_DISC_CONT;
00531 //    for(minor=0;minor<controleur->nbMinor-1;minor++) {
00532 //      ret=frs_pthread_enqueue(controleur->frs,
00533 //                          controleur->id_pthread_fin,
00534 //                          minor,
00535 //                          disc);
00536 //      //      cout<<"PsnControlLocal : Thread_controleur : mise en file Thread_fin  disc"<<endl;
00537 //      if (ret) {
00538 //        error("PsnControlLocal : Thread_controleur : Impossible de mettre le Thread fin dans la file d'execution");
00539 //        pthread_exit(0);
00540 //      }
00541 //    }
00542 //    ret=frs_pthread_enqueue(controleur->frs,
00543 //                        controleur->id_pthread_fin,
00544 //                        controleur->nbMinor-1,
00545 //                        FRS_DISC_RT);
00546 //    //cout<<"PsnControlLocal : Thread_controleur : mise en file Thread_Fin rt"<<endl;
00547 //    if (ret) {
00548 //      error("PsnControlLocal : Thread_controleur : Impossible de mettre le Thread_Fin dans la file d'execution");
00549 //      pthread_exit(0);
00550 //    }
00551 //  #endif  
00552 //    //pour tous les modules, creation du thread et placement sur les files d'éxécution.
00553 //    for (pTab= controleur->_referenceObjectsMap.begin(); pTab!= controleur->_referenceObjectsMap.end(); pTab++)
00554 //    {
00555 //      cout<<"Mise en file de : "<<(*pTab).second->objetSimul()->Nom().getCString()<<endl;
00556 //  #ifdef _SPROC
00557 //      (*pTab).second->objetSimul()->id_thread_calcul=sproc((*pTab).second->objetSimul()->Start_Thread,
00558 //                                                       PR_SALL,
00559 //                                                       (void *) (*pTab).second->objetSimul());
00560 //      if((*pTab).second->objetSimul()->id_thread_calcul == -1) {
00561 //        error("PsnControlLocal : Thread_controleur : creation d'un Thread calcul impossible");
00562 //        frs_abort(1);
00563 //      }
00564 //      freq=(*pTab).second->objetSimul()->getObjectDescriptor().Frequency();
00565 //      int nbExecParMajor=int(controleur->_stepFrequency/freq);
00566 //      for(minor=0;minor<controleur->nbMinor;minor++) {
00567 //        if (minor%nbExecParMajor==nbExecParMajor-1) {//il faut une execution temps réel
00568 //      ret=frs_enqueue(controleur->frs,
00569 //                      (*pTab).second->objetSimul()->id_thread_calcul,
00570 //                      minor,
00571 //                      FRS_DISC_RT);
00572 //      //cout<<"PsnContrlLocal mise en file calcul rt"<<endl;
00573 //      if (ret) {
00574 //        error("Impossible de mettre un Thread calcul dans la file d'execution");
00575 //        exit(0);
00576 //      }
00577 //        }
00578 //        else {
00579 //      ret=frs_enqueue(controleur->frs,
00580 //                      (*pTab).second->objetSimul()->id_thread_calcul,
00581 //                      minor,
00582 //                      disc);
00583 //      //cout<<"PsnControlLocal : Thread_controleur : mise en file calcul disc"<<endl;
00584 //              if (ret) {
00585 //        error("Impossible de mettre un Thread calcul dans la file d'execution");
00586 //        exit(0);
00587 //      }//if (ret)
00588 //        }//else
00589 //      }//for minor
00590 //  #else
00591 //      ret=pthread_create(&((*pTab).second->objetSimul()->id_pthread_calcul),
00592 //                     &attributs_pthread,
00593 //                         (*pTab).second->objetSimul()->Start_Thread,
00594 //                         (void *) (*pTab).second->objetSimul());
00595 
00596 //      if(ret) {
00597 //        error("PsnControlLocal : Thread_controleur : creation d'un Thread calcul impossible");
00598 //        frs_abort(1);
00599 //      }
00600 //      freq=(*pTab).second->objetSimul()->getObjectDescriptor().Frequency();
00601 //      int nbExecParMajor=int(controleur->_stepFrequency/freq);
00602 //      for(minor=0;minor<controleur->nbMinor;minor++) {
00603 //        if (minor%nbExecParMajor==nbExecParMajor-1) {//il faut une execution temps réel
00604 //      ret=frs_pthread_enqueue(controleur->frs,
00605 //                              (*pTab).second->objetSimul()->id_pthread_calcul,
00606 //                              minor,
00607 //                              FRS_DISC_RT);
00608 //      //cout<<"PsnContrlLocal mise en file calcul rt"<<endl;
00609 //      if (ret) {
00610 //        error("Impossible de mettre un Thread calcul dans la file d'execution");
00611 //        pthread_exit(0);
00612 //      }
00613 //        }
00614 //        else {
00615 //      ret=frs_pthread_enqueue(controleur->frs,
00616 //                              (*pTab).second->objetSimul()->id_pthread_calcul,
00617 //                              minor,
00618 //                              disc);
00619 //      //cout<<"PsnControlLocal : Thread_controleur : mise en file calcul disc"<<endl;
00620 //              if (ret) {
00621 //        error("Impossible de mettre un Thread calcul dans la file d'execution");
00622 //        pthread_exit(0);
00623 //      }//if (ret)
00624 //        }//else
00625 //      }//for minor
00626 //  #endif
00627 //    }//for tous les objets de simulation
00628 //  #ifdef _PSGUI1
00629 //  #ifdef _SPROC
00630 //    controleur->id_thread_gui=sproc(Thread_Gui,PR_SALL,(void *) controleur);
00631 //    if(controleur->id_thread_gui==-1) {
00632 //      controleur->finFrs();
00633 //      perror("PsnControlLocal :: Thread_Controleur :: Impossible de creer le thread gui");
00634 //      exit(0);
00635 //    }  
00636 //  #ifdef _DEBUG
00637 //    cout <<"PsnControlLocal : Thread_controleur : thread gui crée "<<endl;
00638 //  #endif
00639 //  //    for(minor=0;minor<controleur->nbMinor;minor++) {
00640 //  //      ret=frs_enqueue(controleur->frs,
00641 //  //                      controleur->id_thread_gui,
00642 //  //                      minor,
00643 //  //                      FRS_DISC_BACKGROUND);
00644 //  //      //cout<<"PsnControlLocal : Thread_controleur : mise en file Thread_Time"<<endl;
00645 //  //      if (ret) {
00646 //  //        perror("PsnControlLocal : Thread_controleur : Impossible de mettre le Thread time dans la file d'execution");
00647 //  //        exit(0);
00648 //  //      }
00649 //  //    }
00650 //  #else
00651 //    //creation du thread Thread_time pour la gestion du temps
00652 //    ret=pthread_create(&(controleur->id_pthread_gui),
00653 //                   &attributs_pthread,
00654 //                   Thread_Gui,
00655 //                   (void *) controleur);
00656 //    if (ret) {
00657 //      perror("PsnControlLocal : Thread_controleur : Impossible de creer le Thread Time");
00658 //      pthread_exit(0);
00659 //    }
00660 //  #ifdef _DEBUG
00661 //    cout <<"PsnControlLocal : Thread_controleur : thread gui crée "<<endl;
00662 //  #endif
00663 //    ///On ne place pas ce thread sur le frame scheduler pour qu'il puisse l'arreter et surtout pour le redémarrer. D'où commentaire des 14 lignes suivantes.
00664 
00665 //  //placement de ce thread en tête de toutes les files d'exécution
00666 //  //    for(minor=0;minor<controleur->nbMinor;minor++) {
00667 //  //      ret=frs_pthread_enqueue(controleur->frs,
00668 //  //                              controleur->id_pthread_gui,
00669 //  //                              minor,
00670 //  //                              FRS_DISC_BACKGROUND);
00671 //  //      //cout<<"PsnControlLocal : Thread_controleur : mise en file Thread_Time"<<endl;
00672 //  //      if (ret) {
00673 //  //        perror("PsnControlLocal : Thread_controleur : Impossible de mettre le Thread gui dans la file d'execution");
00674 //  //        pthread_exit(0);
00675 //  //      }
00676 //  //    }
00677 //  #endif //creation du controleur de gui
00678 //  #endif
00679 
00680 
00681 //    //on démarre le frs
00682 //  #ifdef _DEBUG
00683 //    cout<<"PsnControlLocal : Thread_controleur : synchro normale de mise en file"<<endl;
00684 //  #endif
00685 //    controleur->bar->Sync();
00686 //    cout<<"frame scheduler running\n";
00687 //    if (frs_start(controleur->frs)<0) {
00688 //      perror("PsnControlLocal : Thread_controleur : démarrage du frs impossible ");
00689 //      exit(0);
00690 //    }
00691 //  #ifdef _SPROC
00692 //    wait(&ret); 
00693 //    cout <<"PsnControlLocal :: Tread_controleur :: on n'attend rien"<<endl; 
00694 //    if (ret == -1) {
00695 //      perror("PsnControlLocal :: Thread_controleur :: impossible d'attendre la fin de tous les fils");
00696 //    }
00697 //    wait(&ret); 
00698 //    if (ret == -1) {
00699 //      perror("PsnControlLocal :: Thread_controleur :: impossible d'attendre la fin de tous les fils");
00700 //    }
00701 //    for (pTab= controleur->_referenceObjectsMap.begin(); pTab!= controleur->_referenceObjectsMap.end(); pTab++) {
00702 //      wait(&ret);  
00703 //      if (ret == -1) {
00704 //        perror("PsnControlLocal :: Thread_controleur :: impossible d'attendre la fin de tous les fils");
00705 //      }
00706 //      cout <<"fini\n";
00707 //    }
00708 //    exit(0);
00709 //  #else
00710 //    if (ret=pthread_join(controleur->id_pthread_fin,0)) {
00711 //      error("PsnControlLocal : thread_controleur : join thread_fin failed");
00712 //    }
00713 //    if (ret=pthread_join(controleur->id_pthread_time,0)) {
00714 //      error("PsnControlLocal : thread_controleur : join thread_time failed");
00715 //    }
00716 //    for (pTab= controleur->_referenceObjectsMap.begin(); pTab!= controleur->_referenceObjectsMap.end(); pTab++) {
00717 //      if (ret=pthread_join((*pTab).second->objetSimul()->id_pthread_calcul,0)) {
00718 //        error("PsnControlLocal : thread_controleur : join des threads_calcul impossible");
00719 //      }
00720 //      cout <<"fini\n";
00721 //    }
00722 //    pthread_exit(0);
00723 //    return((void *)controleur);
00724 //  #endif    
00725 //  }//Thread_Controleur
00726 
00727 //  // Le corps du thread chargé de gérer la date de la simulation.
00728 //  // Ce thread doit être le premier à être exécuté dans chaque minor frame sur chaque Frame scheduler
00729 //  #ifdef _SPROC
00730 //  void PsnControlLocal::Thread_Time(void *controleurv) {
00731 //  #else
00732 //  void *PsnControlLocal::Thread_Time(void *controleurv) {
00733 //  #endif
00734 //    int previous_minor; //permet de controler la réussite de frs_yield
00735 //    int localfin=TRUE;
00736 //    PsnControlLocal *controleur=(PsnControlLocal *)controleurv;
00737 //    //On attend que tous les threads soient dans la file d'execution
00738 //  #ifdef _DEBUG
00739 //    cout<<"Thread Time :: synchronisation normale"<<endl;
00740 //  #endif
00741 //    controleur->bar->Sync(); 
00742 //   //On signale au frs qu'on est prêt
00743 //    if(frs_join(controleur->frs) < 0) {
00744 //      //si on arrive jusqu'ici, c'est mal parti
00745 //      perror("PsnControlLocal : Thread_time : pas réussi à joindre le Frame Scheduler");
00746 //      quitterThread(0);
00747 //    }
00748 //    do { //à chaque pas de simulation, compute la date.
00749 //  #ifdef _DEBUG
00750 //      cout<<"calcul du temps"<<endl;
00751 //  #endif
00752 //      controleur->_numberOfSimulatedSteps++;
00753 //      controleur->date=controleur->date + controleur->dt;  
00754 //      previous_minor=frs_yield();
00755 //      if(previous_minor<0)  {
00756 //        //on revient de cet appel de procedure seulement au prochain pas de simulation 
00757 //        if(!fin) {
00758 //      perror("PsnControlLocal : Thread_time : frs_yield() a échoué");
00759 //      quitterThread(0);
00760 //        }
00761 //      }
00762 //      if (fin) localfin=FALSE;
00763 //    } while(localfin);
00764 //  #ifdef _DEBUG
00765 //    cout<<"Output du thread time"<<endl;
00766 //  #endif
00767 //    quitterThread(0);
00768 //  #ifndef _SPROC
00769 //    return (controleur); //ça evite des warnings
00770 //  #endif
00771 //  }
00772 
00773 
00774 //   //Le thread charge de gérer la gui si elle existe
00775 //  #ifdef _SPROC
00776 //   void PsnControlLocal::Thread_Gui(void *controleurv) {
00777 //  #else
00778 //   void *PsnControlLocal::Thread_Gui(void *controleurv) {
00779 //  #endif
00780 //  #ifdef _PSGUI1
00781 //     int previous_minor;
00782 //    PsnControlLocal *controleur=(PsnControlLocal *)controleurv;
00783 //    //on attend que tous les threads soient dans leurs files d'execution
00784 //    controleur->bar->Sync();
00785 
00786 //    //on se join au frame scheduler (cette stratégie est discutable)
00787 //  //    if(frs_join(controleur->frs) < 0) {
00788 //  //      //si on arrive jusqu'ici, c'est mal parti
00789 //  //      cout<<"PsnControlLocal : Thread_Gui : pas réussi à joindre le Frame Scheduler : je continue en solo"<<endl;
00790 //  //    }
00791 //    do {
00792 //  //      if((previous_minor=frs_yield())<0)  {    
00793 //  //        //on revient de cet appel de procedure seulement au prochain pas de simulation 
00794 //  //        perror("PsnControlLocal : Thread_Gui : frs_yield() a échoué");
00795 //  //      }
00796 //      // gestion des demandes de l'utilisateur au niveau controle
00797 //      controleur->computeNextSimulationStepGUI(); //anc :exec_GUI();
00798 //      controleur->runUserInterface();
00799 //    } while(!(fin&&controleur->fini));
00800 //    fin=TRUE;
00801   
00802 //  #ifndef _SPROC
00803 //    return((void *)controleur);
00804 //  #endif
00805 //  #endif //de _PSGUI1  
00806 //  }
00807 
00808 //  // Le thread charge de gérer la terminaison.
00809 //  #ifdef _SPROC
00810 //  void PsnControlLocal::Thread_Fin(void *controleurv) {
00811 //  #else
00812 //  void *PsnControlLocal::Thread_Fin(void *controleurv) {
00813 //  #endif
00814 //    int previous_minor;  //permet de controler la réussite de frs_yield
00815 //    PsnControlLocal *controleur=(PsnControlLocal *)controleurv;
00816 //    //on attend que tous les threads soient dans la file d'execution
00817 //  #ifdef _DEBUG
00818 //    cout<<"synchronisation normale pour le thread_Fin"<<endl;
00819 //  #endif
00820 //    controleur->bar->Sync();
00821 //    //cout<<"PsnControlLocal : Thread_Fin avant join"<<endl;
00822 //    if(frs_join(controleur->frs) < 0) {
00823 //      //si on arrive jusqu'ici, c'est mal parti
00824 //      error("PsnControlLocal : Thread_Fin : pas réussi à joindre le Frame Scheduler");
00825 //      frs_destroy(controleur->frs);
00826 //      exit(0);//seul lui peut arreter : si il plante il faut tout arreter avant que ce soit impossible
00827 //    }
00828 //    do {
00829 //  #ifdef _DEBUG
00830 //      cout<<"controle de la fin"<<endl;
00831 //  #endif
00832 //      previous_minor=frs_yield();
00833 //      if(previous_minor<0)  {    
00834 //        //on revient de cet appel de procedure seulement au prochain pas de simulation 
00835 //        perror("PsnControlLocal : Thread_Fin : frs_yield() a échoué");
00836 //        exit(0);//seul lui peut arreter : si il plante il faut tout arreter
00837 //      }
00838 //      if (controleur->fini) {fin=TRUE;};
00839 //    } while(!fin);
00840 //    //arrivé ici, il faut terminer la simulation...  
00841 //    cout<<"PsnControlLocal : Thread_fin : on termine la simulation"<<endl;
00842 //    frs_stop(controleur->frs);
00843 //    frs_destroy(controleur->frs);
00844 //    controleur->Output();
00845 //    quitterThread(0);
00846 //  #ifndef _SPROC
00847 //    return((void *)controleur);
00848 //  #endif
00849 //  }
00850 
00851 
00852 
00853 #endif

logo OpenMask

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

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