static void placeRequest ( TypeBarriere entrance, Car const & car ) { time_t now = time ( NULL ); CarRequest request ( entrance, car, now, getpid ( ) ); State * state = ObtainSharedState ( ); state->requests[entrance - 1] = request; state->requestsNumber++; ReleaseSharedState ( state ); // Display this new request AfficherRequete ( entrance, car.priority, now ); } // Fin de placeRequest
static void Moteur(TypeBarriere parametre) // Algorithme : // Phase moteur de la tâche Entree // S'occupe d'aller piocher un message dans la BaL associée à parametre, et à gérer cette voiture // (la faire entrer, ou attendre que ce soit son tour de rentrer si le parking est plein) { struct sembuf reserver = {MUTEX_MEMPARTAGEE, -1,0}; //p Operation --> Reservation struct sembuf liberer = {MUTEX_MEMPARTAGEE, 1, 0}; //v Operation --> liberation msgClavier* voiture = (msgClavier*) malloc(sizeof(struct msgClavier)); if(msgrcv(balId, voiture, TAILLE_MESSAGE, parametre, 0) != -1) { DessinerVoitureBarriere(parametre,voiture->typeVehicule); while(semop(semId,&reserver,1)==-1 && errno==EINTR); //Reservation de la memoire structMemoire *park = (structMemoire *) shmat(idMemPart, NULL, 0) ; //attachement if(park->nbPlacesLibres <= 0) { park->attente[parametre-1] = (*voiture); shmdt(park); //detachement semop(semId,&liberer,1); //Liberation de la memoire partagee AfficherRequete(parametre, voiture->typeVehicule, voiture->tArrivee); SetSemAttente(parametre,1); while(GetSemAttente(parametre) == 1){sleep(0.1);}; Effacer((TypeZone)(parametre+ETAT_P8)); // l'indice de la zone commence à ETAT_P8 + 1, les parametres des portes font le complément d'indice while(semop(semId,&reserver,1)==-1 && errno==EINTR); //Reservation de la memoire park = (structMemoire *) shmat(idMemPart, NULL, 0) ; //atta chement } park->nbPlacesLibres--; shmdt(park); //detachement semop(semId,&liberer,1); //Liberation de la memoire partagee pid_t garer=GarerVoiture(parametre); Voiturier temp; temp.mouvementGarer = garer; temp.voiture = voiture; mouvementPark.push_back(temp); sleep(ATTENTE); } } //----- fin de Moteur
////////////////////////////////////////////////////////////////// PUBLIC //---------------------------------------------------- Fonctions publiques void GestionEntree(int canalEntree[][2], int canalSortie[2], TypeBarriere typeEntree, int shmIdParking, int shmIdRequete, int semIdParam) { // --- INITIALISATION --- semId = semIdParam; numBarriere = typeEntree -1; decrSemEntree[0].sem_num = numBarriere; decrSemEntree[0].sem_op = -1; decrSemEntree[0].sem_flg = 0; // Canaux : On ferme tout sauf en lecture sur la barriere concernee for(unsigned int barriereEntree = 0; barriereEntree < NB_BARRIERES_ENTREE ; barriereEntree++) { if(barriereEntree != numBarriere) { close(canalEntree[barriereEntree][0]); close(canalEntree[barriereEntree][1]); } else { close(canalEntree[barriereEntree][1]); } } close(canalSortie[0]); close(canalSortie[1]); // -- Creation des handlers de SIGUSR2 // HandlerSIGUSR2 ne doit pas etre interrompu par SIGCHLD struct sigaction actionHandlerUSR2; actionHandlerUSR2.sa_handler = HandlerUSR2; sigemptyset(&actionHandlerUSR2.sa_mask); actionHandlerUSR2.sa_flags = 0; sigaddset(&actionHandlerUSR2.sa_mask, SIGCHLD); // -- Creation des handlers de SIGCHLD struct sigaction actionHandlerCHLD; actionHandlerCHLD.sa_handler = HandlerCHLD; sigemptyset(&actionHandlerCHLD.sa_mask); actionHandlerCHLD.sa_flags = 0; // -- Attachement des segments de memoires partagées ParkingMPPtr =(ParkingMP*) shmat(shmIdParking, NULL, 0); RequeteMPPtr =(RequeteMP*) shmat(shmIdRequete, NULL, 0); // -- Armement des signaux SIGUSR2 et SIGCHILD sigaction(SIGUSR2, &actionHandlerUSR2, NULL); sigaction(SIGCHLD, &actionHandlerCHLD, NULL); // -- Deblocage de SIGCHLD et SIGUSR2 sigset_t listeSignalDebloque; sigemptyset(&listeSignalDebloque); sigaddset(&listeSignalDebloque, SIGUSR2); sigaddset(&listeSignalDebloque, SIGCHLD); sigprocmask(SIG_UNBLOCK, &listeSignalDebloque, NULL); // -- MOTEUR -- while(true) { Voiture voitRecue; pid_t pidVoiturier; // On attend qu'une voiture arrive et on lui affecte son heure d'arrivee while(read(canalEntree[numBarriere][0], &voitRecue , sizeof(Voiture) ) == -1 && errno == EINTR ) ; time_t heureArrivee = (time(NULL)) % TEMPS_MAX; voitRecue.dateArrive = heureArrivee; // -- Quand une voiture arrive a une barriere // On dessine la voiture a la barriere DessinerVoitureBarriere(typeEntree, voitRecue.usager); // On recupere le semaphore de Requete while(semop(semId, decrSemRequete, 1) == -1 && errno == EINTR); // Si y a de une place de libre on gare la voiture, sinon on emet une requete et on attend qu'une place ce libere if(RequeteMPPtr->nbPlacesOccupees < NB_PLACES ) { RequeteMPPtr->nbPlacesOccupees++; semop(semId, incrSemRequete, 1); pidVoiturier = GarerVoiture(typeEntree); } else { RequeteMPPtr->requetes[numBarriere].voiture = voitRecue; RequeteMPPtr->requetes[numBarriere].barriere = typeEntree; AfficherRequete(typeEntree, voitRecue.usager, heureArrivee); semop(semId, incrSemRequete, 1); while(semop(semId, decrSemEntree, 1) == -1 && errno == EINTR); pidVoiturier = GarerVoiture(typeEntree); sleep(TEMPO); } // on garde le pid du Voiturier struct pidVoiture mapPidVoiture = {pidVoiturier, voitRecue}; listeFils.push_back(mapPidVoiture); } }
void Entree(TypeBarriere typeBarriere) { //definition des id d'acces au boites aux lettres et semaphores long msgBufEntreeId; long msgbufRequeteId; unsigned short semElementSyncEntree; TypeZone zoneEcranRequete; switch (typeBarriere) { case PROF_BLAISE_PASCAL : //deja initialises aux bonnes valeurs; msgBufEntreeId = MSGBUF_ID_ENTREE_P; msgbufRequeteId = MSGBUF_ID_REQUETE_P; semElementSyncEntree = SEMELM_SINC_ENTREE_P; zoneEcranRequete = REQUETE_R1; break; case AUTRE_BLAISE_PASCAL : msgBufEntreeId = MSGBUF_ID_ENTREE_A; msgbufRequeteId = MSGBUF_ID_REQUETE_A; semElementSyncEntree = SEMELM_SINC_ENTREE_A; zoneEcranRequete = REQUETE_R2; break; case ENTREE_GASTON_BERGER : msgBufEntreeId = MSGBUF_ID_ENTREE_GB; msgbufRequeteId = MSGBUF_ID_REQUETE_GB; semElementSyncEntree = SEMELM_SINC_ENTREE_GB; zoneEcranRequete = REQUETE_R3; break; default : std::cerr << "not an entry process error" << std::endl; return; break; } //initialisation init(); //phase moteur pid_t pidCurr; Voiture voiture; for(;;) { //appel bloquant, attente d'une demande d'entree if(msgrcv(msgbuffId, &voiture, sizeof(Voiture)-sizeof(long), msgBufEntreeId, 0) == -1) continue; // sarestart (sur les erreurs aussi) DessinerVoitureBarriere(typeBarriere, voiture.typeUsager); if(semVal(SEMELM_PLACEDISPO) > 0) { if((pidCurr = GarerVoiture(typeBarriere)) != -1) { semP(SEMELM_PLACEDISPO); mapVoiturier.insert(std::pair<pid_t, Voiture>(pidCurr, voiture)); } } else { //affiche requete AfficherRequete(typeBarriere,voiture.typeUsager,voiture.heureArrivee); Requete re; re.type = msgbufRequeteId; re.heureArrivee = voiture.heureArrivee; re.typeUsager = voiture.typeUsager; if(msgsnd(msgbuffId, &re, sizeof(Requete)-sizeof(long), 0 )==-1); semP(semElementSyncEntree); if((pidCurr = GarerVoiture(typeBarriere)) != -1) { //met à jour l'heure d'entree dans le parking voiture.heureArrivee = time(NULL); mapVoiturier.insert(std::pair<pid_t, Voiture>(pidCurr, voiture)); } Effacer(zoneEcranRequete); } } }