Un parcheggio offre 30 posti auto, non tutti uguali:
Le vetture che non possono accedere al parcheggio vengono bloccate all’ingresso. In questo caso, quando queste vetture verranno sbloccate potranno accedere solamente a parcheggi del tipo corrispondente.
Una vettura “S” che arriva all’ingresso può accedere ad un posto “M” solo se non ci sono posti liberi “S” e almeno 3 posti “M” sono occupati da vetture “M”.
Una vettura “S” che arriva all’ingresso può accedere ad un posto “L” solo se non ci sono posti liberi “S” e la vettura non può accedere a posti “M”
Una vettura “M” che arriva all’ingresso può accedere ad un posto “L” solo se non ci sono posti liberi “M” e le vetture “M” già presenti nel parcheggio sono meno di 15.
Programmare l’ingresso e l’uscita delle vetture di ogni tipo usando i semafori con la semantica tradizionale.
//variabili
busyL = busyM = busyS = 0; //numero di posti occupati, sempre tra 0 e 10
inM = 0; //numero di macchine M nel parcheggio (slot M o L)
inMM = 0; //numero di macchine M negli slot M
wL = wM = wS = 0; //numero di macchine in attesa di entrare
//semafori
mutex = 1;
semL = semM = semS = 0; //semafori per bloccare le macchine
boolean canSS(){return busyS < 10;}
boolean canMM(){return busyM < 10;}
boolean canLL(){return busyL < 10;}
boolean canSM(){return (busyM < 10 && inMM >= 3);} //busyS >= 10 non controllata
boolean canSL(){return (busyL < 10 && canSM());} //busyS >= 10 non controllata
boolean canML(){return (busyL < 10 && inM < 15);} //musyM > 0 non controllata
void inSS(){busySS++;}
void inSM(){busyM++;}
void inSL(){busyL++;}
void inMM(){busyM++; inM++; inMM++;}
void inML(){busyL++; inM++;}
void inLL(){busyL++;}
void outS(){
if(wM > 0){wS--; signal(semS);}
else{busyS--;}
}
void outM(){
if(wM > 0){wM--; inM++; inMM++; signal(semM);}
else{busyM--;}
}
void outL(){
if(wL > 0){wL--; signal(semL);}
else{busyL--;}
}
void carS(){
wait(mutex);
if(canSS()){busyS++; signal(mutex); park(); wait(mutex); outS(); signal(mutex);}
else{
if(canSM()){busyM++; signal(mutex); park(); wait(mutex); outM(); signal(mutex);}
else{
if(canSL()){busyL++; signal(mutex); park(); wait(mutex); outL(); signal(mutex);}
else{
wS++; signal(mutex); wait(semS); park(); wait(mutex); outS(); signal(mutex);
}
}
}
}
void carM(){
wait(mutex);
if(canMM()){
busyM++; inM++; inMM++; signal(mutex);
park();
wait(mutex); inM--; inMM--; outM(); signal(mutex);
}else{
if(canML()){
busyL++; inM++; signal(mutex);
park();
wait(mutex); inM--; outL(); signal(mutex);
}else{
wM++; signal(mutex); wait(semM);
park();
wait(mutex); outM(); signal(mutex);
}
}
}
void carL(){
wait(mutex);
if(canLL){
busyL++; signal(mutex);
park();
wait(mutex); outL(); signal(mutex);
}else{
wL++; signal(mutex); wait(semL);
park();
wait(mutex); outL(); signal(mutex);
}
}