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

PsReactController.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 <PsReactController.h>
00020 #include <PsReactGlobalController.h>
00021 #include <PsnPthreadSemaphore.h>
00022 #include <PsnDoubleListElement.h>
00023 #include <PsnDoubleList.h>
00024 #include "PsnReactFrameScheduler.h"
00025 
00026 #define frs_abort(x) exit(x);
00027 
00028 //--------------------------------------------------------
00029 
00030 PsReactController::PsReactController(PsObjectDescriptor* arbreSimul, 
00031                                        int minorTim, 
00032                                        int nbMino,
00033                                        PsController * control,
00034                                        int cpuAutiliser,PsKernelObjectAbstractFactory * aKernelObjectFactory) : PsController(aKernelObjectFactory), barInit(2)
00035 {
00036   cpu=cpuAutiliser;
00037   arbreObjets=arbreSimul;
00038   //Mise à jour de l'idObjet
00039   IdObjet(arbreSimul->get());
00040   arbreSimul->get()->setPointerToSimulatedObject(this);
00041   controleur=control;
00042   nbMinor=nbMino;
00043   _stepPeriod=minorTim;
00044 // initialisations du controleur local
00045 // a faire avant les init de objets de calcul...
00046   processNameessus= arbreSimul->get()->Nom();
00047 
00048 // initialisation de l'état du controleur
00049   *_computeStatePointer=PsnReferenceObjectHandle::running;
00050 #ifdef _DEBUG
00051   cout<<"creation du controleur React de nom "
00052       <<Nom()
00053       <<endl;
00054 #endif
00055 }
00056 
00057 //--------------------------------------------------------
00058 
00059 PsnSemaphore * PsReactController::newSemaphore(int i) {
00060 #ifdef _DEBUG
00061   cout<<"PsReactController::newSemaphore("<<i<<") debut"<<endl;
00062 #endif
00063   PsnSemaphore * ns=new PsnPthreadSemaphore(i);
00064   return ns;
00065 }
00066 
00067 //--------------------------------------------------------
00068 
00069 PsReactController::~PsReactController() {
00070   pthread_attr_destroy(&attributs_pthread);
00071 }
00072 
00073 //--------------------------------------------------------
00074 
00075 void PsReactController::reactToControlledObjectsSystemEvents() {
00076    int ret;
00077    PsnDoubleListElement * prec;
00078    PsEvenement courant;
00079    PsSimulatedObject * objetDest;
00080    PsObjectDescriptor * idObjetDest;
00081    listeEvtControleur->premier();
00082    while(!(listeEvtControleur->fin())) {
00083      courant=listeEvtControleur->get();
00084      //on recupère la référence sur l'objet
00085      objetDest=getPointerToSimulatedObjectNamed(courant.destinataire);
00086      idObjetDest=objetDest->IdObjet();
00087      //on le gère
00088      switch(courant.evt){
00089      case Mask_RESTART:
00090        if (idObjetDest->etat==PsnReferenceObjectHandle::stopped) {
00091          idObjetDest->etat=PsnReferenceObjectHandle::running;
00092          TraiterEvtObj(objetDest);
00093          _objectsNeedingActivationList[indiceFile]->remove(idObjetDest);
00094          objetDest->reInit();
00095          _scheduler->schedule((PsnReferenceObjectHandle *)objetDest->ObjectHandle());
00096        }//du test sur l'état
00097        break;
00098      case Mask_RESUME:
00099 #ifdef _DEBUGEVT
00100        cout<<courant.destinataire<<" va être redémarré"<<endl;
00101 #endif
00102        if (idObjetDest->etat==PsnReferenceObjectHandle::suspended) {
00103           idObjetDest->etat=PsnReferenceObjectHandle::running;
00104           TraiterEvtObj(objetDest);
00105           _objectsNeedingActivationList[indiceFile]->remove(idObjetDest);
00106           //on sait que c'est un référentiel 
00107           _scheduler->schedule((PsnReferenceObjectHandle *)objetDest->ObjectHandle());
00108        }
00109        break;
00110      case Mask_SUSPEND:
00111 #ifdef _DEBUGEVT
00112         cout<<courant.destinataire<<" va être suspendu"<<endl;
00113 #endif
00114         if(idObjetDest->etat==PsnReferenceObjectHandle::running) {
00115            idObjetDest->etat=PsnReferenceObjectHandle::suspended;
00116            TraiterEvtObj(objetDest);
00117            _scheduler->unschedule((PsnReferenceObjectHandle *)objetDest->ObjectHandle());
00118         }      
00119         break;
00120      case Mask_STOP:
00121         if(idObjetDest->etat==PsnReferenceObjectHandle::running) {
00122            idObjetDest->etat=PsnReferenceObjectHandle::stopped;
00123            TraiterEvtObj(objetDest);
00124            objetDest->fin();
00125            _scheduler->unschedule((PsnReferenceObjectHandle *)objetDest->ObjectHandle());
00126         }      
00127        break;
00128      case Mask_START:
00129         processStartEventOf(objetDest);
00130        break;
00131      case Mask_DELETE:
00132        if(idObjetDest->etat==PsnReferenceObjectHandle::stopped) {
00133          idObjetDest->etat=PsnReferenceObjectHandle::destroyed;
00134 //  #ifdef _DYNOS
00135 //       detruireDynOS(objetDest->Nom());
00136 //  #endif
00137          cerr<<"WARNING:PsController::reactToControlledObjectsSystemEvents traitement incomplet de DELETE"<<endl;
00138          //il faut oter le descripteur d'objet de _objectsNeedingActivationList
00139        }
00140        break;
00141      default:
00142        cerr<<"WARNING:PsController::reactToControlledObjectsSystemEvents evenement système non géré"<<endl;
00143      }
00144      //on le supprime de la liste des événements à gérér.
00145      listeEvtControleur->supprimerDebut();
00146      listeEvtControleur->premier();
00147    }
00148 }
00149 
00150 
00151 //--------------------------------------------------------
00152 
00153 frs_t * PsReactController::Frs() {
00154   return frs;
00155 }
00156 
00157 //--------------------------------------------------------
00158 
00159 PsCalculus * PsReactController::createCalculus () {
00160   createControlledObjects();
00161   scheduleControlledObjects();
00162   nbModules=_referenceObjectsMap.size();
00163   cout<<"PsReactController : "
00164       <<processNameessus
00165       <<" createCalculus : nbModules à gérer detectés : "
00166       <<nbModules
00167       <<endl;
00168   // initialisation des signaux pour récupérer le signal underrun et le signal overrun.
00169   if (cpu==1) capture_signal(); //c'est une fonction statique : une seule execution suffit
00170   // calcul du pas de temps 
00171   PsFloat facUB = facSecUnite(UBASE);  
00172   _stepFrequency=_simulationTree.get()->Frequency();
00173   dt=  (PsDate) ( (1./_stepFrequency.getValue()) * facUB.getValue());
00174   
00175 #if defined(_DEBUG)
00176   cdebug<< endl<<"freq controleur: " <<_stepFrequency<< " dt: " <<dt<< endl;
00177 #endif
00178   return NULL;
00179 }
00180 
00181 //--------------------------------------------------------
00182 
00183 
00184 void PsReactController::init() {
00185   //Creation du thread controleur
00186   // Le thread lancant le FRS doit avoir la porté d'un thread system : initialisation des attributs
00187   int ret=pthread_attr_init(&attributs_pthread);
00188   if (ret) {
00189     perror("impossible d'initialiser les attributs du thread");
00190   } 
00191   ret=pthread_attr_setscope(&attributs_pthread, PTHREAD_SCOPE_SYSTEM);
00192   if (ret) {
00193     perror("Impossible de créer des threads system");
00194   }
00195   // Mise en place du FRS
00196   ret = pthread_create(&id_pthread_controleur,
00197                        &attributs_pthread,
00198                        (void *(*)(void *)) Thread_controleur,
00199                        this);
00200   if (ret) {
00201     error("PsnControlLocal : run : impossible de créer le thread_controleur");
00202     frs_abort(1);
00203   }
00204 
00205   //synchronisation avec la fin de la creation de tous les threads
00206   barInit.Sync();
00207   //  PsController::init();
00208 }
00209 
00210 //--------------------------------------------------------
00211 
00212 void *PsReactController::Thread_controleur(void *controleurv) {
00213   PsReactController * ceControleur=(PsReactController *)controleurv;
00214   ceControleur->threadControleur();
00215   return((void *)ceControleur);
00216 }
00217  
00218 //--------------------------------------------------------
00219 
00220 PsSimulatedObject *
00221 PsReactController::getPointerToSimulatedObjectNamed (const PsName & nom) 
00222 {
00223   PsSimulatedObject * resultat;
00224   PsnReferenceObjectHandle * refRes;
00225   // hypothese : c'est un referentiels de ce controleur (recherche rapide)
00226   refRes=_referenceObjectsMap.refObjet(nom);
00227 
00228   resultat= ((PsnObjectHandle*)(_referenceObjectsMap.getObjectOfIndex(nom)) )->objetSimul();
00229   if (refRes==NULL) {//il faut chercher dans l'arbre des objets
00230      resultat=_simulationTree.find(nom)->getPointerToSimulatedObject();
00231   }
00232   else {
00233      resultat=((PsnObjectHandle*)refRes)->objetSimul();
00234   }
00235   if(resultat==NULL) {
00236      cout<<"WARNING : PsReactController::getPointerToSimulatedObjectNamed trouve NULL"<<endl;
00237   }
00238   return resultat;
00239 }
00240  
00241 //--------------------------------------------------------
00242 
00243 void PsReactController::threadControleur() {
00244   PsNameToPointerMap<PsnReferenceObjectHandle>::iterator pTab;
00245   int ret;  
00246   int minor;
00247   int freq;
00248   pthread_attr_t attributs_pthread;
00249 
00250   ret=pthread_attr_init(&attributs_pthread);
00251   if (ret) {
00252     perror("PsnControlLocal : threadControleur : impossible d'initialiser les attributs du thread");
00253   } 
00254   ret=pthread_attr_setscope(&attributs_pthread, PTHREAD_SCOPE_SYSTEM);
00255   if (ret) {
00256     perror("PsnControlLocal : threadControleur : Impossible de créer des threads system");
00257   }
00258   /* 
00259    * Creation du frs si cpu = 1, il s'agit du frs maitre, sinon il s'agit d'un frs esclave.
00260    * cpu = cpu
00261    * source d'interruption = CCTIMER
00262    * nb de minor frames = nbminor
00263    * frs esclaves : controleur->nbFils-1
00264    * period = _stepPeriod [ms]
00265    */
00266   cout<<"PsReactController : threadControleur de "
00267       <<Nom()
00268       <<" : params de frs create master "
00269       <<_stepPeriod*1000
00270       <<" et "
00271       <<nbMinor
00272       <<" et "
00273       <<((PsReactGlobalController *)controleur)->NbFils()-1 
00274       <<" esclave(s) sur le cpu "
00275       <<cpu<<endl;
00276   if (cpu==1) {
00277     frs = frs_create_master(cpu,     //numero du CPU de APP (le frame sheduler)
00278                             FRS_INTRSOURCE_CCTIMER,
00279                             _stepPeriod*1000,
00280                             nbMinor,
00281                             ((PsReactGlobalController *)controleur)->NbFils()-1);
00282     PsReactGlobalController::frs=frs; 
00283   }
00284   else {
00285     frs = frs_create_slave(cpu,     //numero du CPU de APP (le frame sheduler)
00286                            PsReactGlobalController::frs);
00287   }
00288   if(frs==NULL) {
00289     perror("PsReactController : ThreadControleur : impossible de creer le frs");
00290     exit(0);
00291   }
00292   annulerSignalSIGRTMIN();
00293   cout <<"PsReactController : threadControleur : "
00294        <<Nom()
00295        <<" :frame scheduler créé"<<endl;
00296   
00297   //creation du thread Thread_time pour la gestion du temps
00298   ret=pthread_create(&(id_pthread_time),
00299                      &attributs_pthread,
00300                      Thread_Time,
00301                      (void *) this);
00302   if (ret) {
00303     perror("PsReactController : threadControleur : Impossible de creer le Thread Time");
00304     pthread_exit(0);
00305   }
00306 #ifdef _DEBUG
00307   cout <<"PsReactController : threadControleur : "
00308        <<Nom()
00309        << "thread time crée "<<endl;
00310 #endif
00311   //placement de ce thread en tête de toutes les files d'exécution
00312   for(minor=0;minor<nbMinor;minor++) {
00313     ret=frs_pthread_enqueue(frs,
00314                             id_pthread_time,
00315                             minor,
00316                             FRS_DISC_RT);
00317     if (ret) {
00318       perror("PsReactController : threadControleur : Impossible de mettre le Thread time dans la file d'execution");
00319       pthread_exit(0);
00320     }
00321   }
00322   //disc est la discipline qui permet a un thread de s'éxécuter en avance si il le peut
00323   //int disc= FRS_DISC_RT | FRS_DISC_UNDERRUNNABLE | FRS_DISC_OVERRUNNABLE | FRS_DISC_CONT;
00324   
00325   //pour tous les modules, creation du thread et placement sur les files d'éxécution.
00326   for (pTab= _referenceObjectsMap.begin(); pTab!= _referenceObjectsMap.end(); pTab++)
00327     {
00328       ret=pthread_create(&((*pTab).second->objetSimul()->id_pthread_calcul),
00329                          &attributs_pthread,
00330                          (*pTab).second->objetSimul()->Start_Thread,
00331                          (void *) (*pTab).second->objetSimul());
00332       
00333       if(ret) {
00334         error("PsReactController : threadControleur : creation d'un Thread calcul impossible");
00335         frs_abort(1);
00336       }
00337       //Placer les thread sur les files du controleur : c'est fait lors de la reception du Mask_START
00338     }
00339 #ifdef _DEBUGPAR
00340   cdebug<<"Placement, sur le cpu "<<cpu<<" des objets suivants : "<<endl;
00341   for (pTab= _referenceObjectsMap.begin(); pTab!= _referenceObjectsMap.end(); pTab++)
00342      {    
00343         cdebug<<(*pTab).second->objetSimul()->Nom()<<endl;
00344      }
00345 #endif
00346   PsController::init();
00347   advanceSimulatedDate(); 
00348   traiterEvt();
00349   reactToControlledObjectsSystemEvents();
00350   cout<<"PsReactController : threadControleur : date avant la BarInit : "<<date<<endl;
00351   barInit.Sync();
00352   ((PsReactGlobalController *)controleur)->barFrsStart->Sync();
00353   if (frs_start(frs)<0) {
00354     perror("PsReactController : threadControleur : démarrage du frs impossible ");
00355     exit(0);
00356   }
00357 #ifdef _DEBUG
00358   cout<<"frame scheduler running"<<endl;
00359 #endif
00360   if (ret=pthread_join(id_pthread_time,0)) {
00361     error("PsReactController : threadControleur : join thread_time failed");
00362   }
00363   else {
00364     cout<<"Thread_time terminé"<<endl;
00365   }
00366   for (pTab= _referenceObjectsMap.begin(); pTab!= _referenceObjectsMap.end(); pTab++) {
00367     if (ret=pthread_join((*pTab).second->objetSimul()->id_pthread_calcul,0)) {
00368       error("PsReactController : threadControleur : join des threads_calcul impossible");
00369     }
00370     cout <<"fini\n";
00371   }
00372   pthread_exit(0);
00373   
00374 }
00375 
00376 //--------------------------------------------------------
00377 
00378 void PsReactController::threadTime() {
00379   int previous_minor; //permet de controler la réussite de frs_yield
00380   int localfin=TRUE;
00381 
00382   //On attend que tous les threads soient dans la file d'execution
00383   barStart->Sync(); 
00384 
00385   //On signale au frs qu'on est prêt
00386   if(frs_join(frs) < 0) {
00387     perror("PsController : Thread_time : pas réussi à joindre le Frame Scheduler");
00388     finObjetActif(0);
00389   }
00390 #ifdef _DEBUG
00391   else {
00392     cout<<"join du thread_time réussi"<<endl;
00393   }
00394 #endif
00395   do { //à chaque pas de simulation, compute la date.
00396     previous_minor=frs_yield();
00397     //on revient de cet appel de procedure seulement au prochain pas de simulation 
00398     if(previous_minor<0)  {
00399       if(!fin) {
00400         perror("PsReactController : Thread_time : frs_yield() a échoué");
00401         finObjetActif(0);
00402       }
00403     }
00404     processEventsOfSuspendedObjects();
00405     supprEvt();
00406     advanceSimulatedDate();
00407     traiterEvt();
00408     reactToControlledObjectsSystemEvents();
00409 #ifdef _DEBUG
00410     cout<<"calcul du temps"<<endl;
00411 #endif
00412     if (*_computeStatePointer==PsnReferenceObjectHandle::stopped
00413         ||*_computeStatePointer==PsnReferenceObjectHandle::destroyed) localfin=FALSE;
00414   } while(localfin);
00415 #ifdef _DEBUG
00416   cout<<"Output du threadTime"<<endl;
00417 #endif
00418   frs_stop(frs);
00419   frs_destroy(frs);
00420   finObjetActif(0);
00421 
00422 }
00423 
00424 //--------------------------------------------------------
00425 
00426 
00427 void * PsReactController::Thread_Time(void *controleurv) {
00428 
00429   PsReactController *controleur=(PsReactController *)controleurv;
00430   controleur->threadTime();
00431   return (controleur); //ça evite des warnings
00432 }
00433 
00434 
00435 //--------------------------------------------------------
00436 
00437 
00438 
00439 //  bool PsReactController::fin=FALSE;
00440 //  PsnSemaphore PsReactController::sem_fin_clavier=PsnSemaphore(0);
00441 
00442 
00443 
00444 //  void PsReactController::finFrs(void) {
00445 //    frs_stop(frs);
00446 //    frs_destroy(frs);
00447 //  }
00448 
00449 //--------------------------------------------------------
00450 
00451 void PsReactController::capture_underrun (int i) {
00452   if((int)signal(SIGUSR1, capture_underrun)== -1) {
00453     error("PsReactController : capture_signal : impossible de mettre en place le signal underrun_error");
00454     frs_abort(1);
00455   }
00456   cout<<"PsReactController : Error underrun : un des modules n'a pu avoir le CPU alors qu'il aurait du";
00457   PsReactGlobalController::monError();
00458   frs_abort(2);
00459 }
00460 
00461 //--------------------------------------------------------
00462 
00463 void PsReactController::capture_overrun (int i) {
00464   if((int)signal(SIGUSR1, capture_overrun)== -1) {
00465     error("PsReactController : capture_signal : impossible de mettre en place le signal overrun_error");
00466     frs_abort(1);
00467   }
00468   cout<<"PsReactController : Error overrrun : un des modules n'a pas relaché le CPU assez vite";
00469   PsReactGlobalController::monError();
00470   frs_abort(2);
00471 }
00472 
00473 //--------------------------------------------------------
00474 
00475 void PsReactController::annulerSignalSIGRTMIN() {
00476   int error;
00477   frs_signal_info_t work;
00478   error=frs_pthread_getattr(frs,0,0,FRS_ATTR_SIGNALS,(void*)&work);
00479   if(!error)
00480     {
00481       work.sig_unframesched=-1;//0 serait la bonne valeur
00482       for(int i=0;i<nbMinor;i++) {
00483       error=frs_pthread_setattr(frs,i,0,FRS_ATTR_SIGNALS,(void*)&work);
00484       if(error) perror("PsReactController::annulerSignalSIGRTMIN:impossible d'annuler le signal");
00485       cout<<"PsReactController::annulerSignalSIGRTMIN::signal annulé"<<endl;
00486       }
00487     }
00488   else perror("PsReactController::annulerSignalSIGRTMIN ");
00489 }
00490 
00491 //--------------------------------------------------------
00492 
00493 void PsReactController::capture_end(int i) {
00494   //l'utilisateur souhaite terminer la session. Le control n'est pas total on fait donc pour le mieux.
00495   PsReactGlobalController::monError();
00496   cout<<"c'est la fin";
00497 }
00498 
00499 //--------------------------------------------------------
00500 
00501 void PsReactController::capture_signal() {
00502   if((int)signal(SIGUSR1, capture_underrun)== -1) {
00503     error("PsReactController : capture_signal : impossible de mettre en place le signal underrun_error");
00504     frs_abort(1);
00505   }
00506 
00507   if((int)signal(SIGUSR2, capture_overrun)== -1) {
00508     error("PsReactController : capture_signal : impossible de mettre en place le signal overrun_error");
00509     frs_abort(1);
00510   }
00511   if((int)signal(SIGINT, capture_end )== -1) {
00512     error("PsReactController : capture_signal : impossible de capturer les signaux de terminaison");
00513     frs_abort(1);
00514   }  
00515 }
00516 
00517 #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