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