-
-
-
CENAPAD-MGCO
A seguir: 3a. Questão Acima: Marcelo Bernardes Vieira Anterior: 1a Questão
Considerações iniciais:
a) Programa cliente:
void carro(int dire\c{c}\~{a}o) {
RequestPonte(dire\c{c}\~{a}o);
. . .
ReleasePonte(dire\c{c}\~{a}o);
}
b) Controlador da ponte:
key mutex; CarQueue waiting; Bed b;
int guarda[2], waitcar[2], busy[2];
struct {
int dire\c{c}\~{a}o;
int posi\c{c}\~{a}o;
} Request;
void RequestPonte(int dire\c{c}\~{a}o) {
lock(mutex);
Request rq = waiting.GetRequest(dire\c{c}\~{a}o);
waitcar[dire\c{c}\~{a}o]++;
while( (guarda[dire\c{c}\~{a}o] >= 5
&& waitcar[!dire\c{c}\~{a}o] > 0 ) ||
busy[!dire\c{c}\~{a}o] > 0 ||
!waiting.IsTheBest(rq)) {
wait(b, mutex);
}
guarda[dire\c{c}\~{a}o]++; // Deixou mais um passar
busy[dire\c{c}\~{a}o]++;
waitcar[dire\c{c}\~{a}o]--; // Menos um esperando
waiting.ok(rq);
guarda[!dire\c{c}\~{a}o] = 0;
wakeup(b, mutex); // Outros carros podem entrar
unlock(mutex);
}
void ReleasePonte(int dire\c{c}\~{a}o) {
lock(mutex);
busy[dire\c{c}\~{a}o]--;
wakeup(b, mutex);
unlock(mutex);
}
c) Fila de prioridades:
OrderedQueue q(new firstcarcomparator());
Request GetRequest(int dire\c{c}\~{a}o) {
Request rq = new Request(dire\c{c}\~{a}o);
q.Put( rq );
return( rq );
}
void Ok(Request rq) {
q.Atualiza(rq.dire\c{c}\~{a}o);
q.del( rq );
}
boolean IsTheBest(Request rq) {
return rq.posicao == 1; // Primeiro de qualquer dire\c{c}\~{a}o
}