// Para simplificar usa-se a uma estrutura semelhante ao exemplo anterior // No entanto, o campo que identifica o destinatário passa a ser um char (8 bits chegam para codificar 2 alternativas: P3 ou P4) // Mudamos também o nome do tipo para estar de acordo com a especifícação do enunciado typedef struct { char type; Mensagem msg; } Elemento; // Assumindo que existem as seguintes filas filaP1 - liga P1 a PA filaP2 - liga P2 a PA filaPAB - liga PA a PB filaP3 - liga PB a P3 filaP4 - liga PB a P4 // Assumindo que existem as seguintes semáforos para cada fila // Segue apenas o exemplo da fila P1 semExmutP1 = 1; // semáforo binário que controla o acesso à fila P1 semLivresP1 = N; // semáforo que conta o número de posições livres na fila P1 - N tamanho máximo da fila semOcupadasP1 = 0; // semáforo que conta o número de posições ocupadas na fila P1 // Função que envia um pacote para a fila fila // cujo acesso é controlado pelos semáforos semOcupadas. semLivres e semExmut // Assume-se um versão ligeiramente diferente da função inserir que recebe como argumento a fila alvo enviar(int fila, Elemento *pacote, int semOcupadas, int semLivres, int semExmut) { P(semLivres); P(semExmut); inserir(fila, pacote); V(semExmut); V(semOcupadas); } // Função que recebe um pacote da fila fila // cujo acesso é controlado pelos semáforos semOcupadas. semLivres e semExmut // Assume-se um versão ligeiramente diferente da função remover que recebe como argumento a fila alvo receber(int fila, Elemento *pacote, int semOcupadas, int semLivres, int semExmut) { P(semOcupadas); P(semExmut); remover(fila, pacote); V(semExmut); V(semLivres); } // Consonte o processo que está a executar, P1 ou P2, assume-se que: // a variável fila contém filaP1 ou filaP2 // a variável semOcupadas contém semOcupadasP1 ou semOcupadasP2 // a variável semLivres contém semLivresP1 ou semLivresP2 // a variável semExmut contém semExmutP1 ou semExmutP2 int enviarMensagem(Mensagem *msg, int p) { if (p != P3 && p != P4) return -1; Elemento pacote; pacote.type = p; memcpy(&pacote.msg, msg, sizeof(Mensagem)); enviar(fila, &pacote, semOcupadas, semLivres, semExmut); return 0; } // Comportamento de PA int PA() { Elemento pacote; int filaIn = filaP1; int semOcupadas = semOcupadasP1; int semLivres = semLivresP1; int semExmut = semExmutP1; while(1) { receber(filaIn, &pacote, semOcupadas, semLivres, semExmut); enviar(filaPAB, &pacote, semOcupadasPAB, semLivresPAB, semExmutPAB); if (filaIn == filaP1) { filaIn = filaP2; semOcupadas = semOcupadasP2; semLivres = semLivresP2; semExmut = semExmutP2; } else { filaIn = filaP1; semOcupadas = semOcupadasP1; semLivres = semLivresP1; semExmut = semExmutP1; } } } // Comportamento de PB int PB() { Elemento pacote; int filaOut; int semOcupadas; int semLivres; int semExmut; while(1) { receber(filaPAB, &pacote, semOcupadasPAB, semLivresPAB, semExmutPAB); if (pacote.type == P3) { filaOut = filaP3; semOcupadas = semOcupadasP3; semLivres = semLivresP3; semExmut = semExmutP3; } else { filaOut = filaP4; semOcupadas = semOcupadasP4; semLivres = semLivresP4; semExmut = semExmutP4; } enviar(filaOut, &pacote, semOcupadas, semLivres, semExmut); } } // Consonte o processo que está a executar, P3 ou P4, assume-se que: // a variável fila contém filaP3 ou filaP4 // a variável semOcupadas contém semOcupadasP3 ou semOcupadasP4 // a variável semLivres contém semLivresP3 ou semLivresP4 // a variável semExmut contém semExmutP3 ou semExmutP4 int receberMensagem(Mensagem *msg, int p) { if (p != P1 && p != P2) return -1; Elemento pacote; receber(fila, &pacote, semOcupadas, semLivres, semExmut); memcpy(msg, &pacote.msg, sizeof(Mensagem)); return 0; }