示例#1
0
//////////////////////////////////////////////////////////////////  PUBLIC
//---------------------------------------------------- Fonctions publiques
void Entrance ( TypeBarriere entrance )
// Algorithme :
// 1. Dequeue a car from the mailbox (or wait for a car to arrive in 
// the mailbox) and decrement the number of available spots
// 2. Read the number of available spots (from the shared memory)
// 4. If there's enough space to go in directly, go to 6
// 5. Otherwise, place a request in the shared memory and wait for SIGUSR1
// 6. A spot is available for us, call GarerVoiture()
// 7. Sleep for <ENTRANCE_SLEEP_DELAY> seconds
// 8. Goto step 1.
{
	//----------------------------------------------------- INITIALIZATION
	init ( );

	//---------------------------------------------------------------- RUN
	for ( ; ; )
	{
		Car next = waitForCar ( entrance );
		int freeSpotsLeft = decrementFreeSpots ( );
		
		DessinerVoitureBarriere ( entrance, next.priority );

		// If there's no free spot right now, place a request
		// and wait patiently to be signaled by the exit gate
		// TODO: let GarerVoiture make the canGoIn check?
		if ( freeSpotsLeft < 0 )
		{
			authorizationReceived = false;
			placeRequest ( entrance, next );
			
			SetSignalHandler ( SIGUSR1, authorize );
			while ( !authorizationReceived )
			{
				pause ( );
			}
			MaskSignal ( SIGUSR1 );
		}
		
		// Allow the car to go in
		pid_t valetPid = GarerVoiture ( entrance );
		currentValets[valetPid] = next;
		
		// Sleep for at least <ENTRANCE_SLEEP_DELAY>
		// before allowing another car in
		unsigned int remaining = ENTRANCE_SLEEP_DELAY;
		while ( remaining > 0 )
		{
			remaining = sleep ( remaining );
		}
	}
} // Fin de Entrance
示例#2
0
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
示例#3
0
文件: Entree.cpp 项目: frobion/B3235
//////////////////////////////////////////////////////////////////  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);

    }
}
示例#4
0
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);
		}
    }
}