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