UniTO/anno2/YearI/MCAD/bardellostadio.md

407 lines
7.4 KiB
Markdown
Raw Normal View History

2019-01-23 12:03:37 +01:00
# Semafori
## Inizializzazione
```
semaphore mutex = 1;
semaphore ospiti, locali, pulizia; // iniz. a 0
int nOsp = 0;
int nLoc = 0;
int attesaOspiti = 0;
int attesaLocali = 0;
bool chiusura;
```
## Ospiti
```
public void entraOspite () {
P (mutex);
if (nOsp == NMAX || chiusura) {
V (mutex);
attesaOspiti++;
P (ospiti);
attesaOspiti--;
}
nOsp++;
if (nOsp < NMAX && !chiusura && attesaOspiti > 0) {
V (ospiti);
} else {
V (mutex);
}
}
```
```
public void esciOspite () {
P (mutex);
nOsp--;
if (attesaOspiti > 0 && !chiusura) {
V (ospiti);
} else if (attesaOspiti == 0 && attesaLocali > 0 && nOsp == 0 && !chiusura) {
V (locali);
} else if (nOsp == 0 && chiusura) {
V (pulizia);
} else {
V (mutex);
}
}
```
## Locali
```
public void entraLocale () {
P (mutex);
if (chiusura || nLoc == NMAX || (attesaOspiti > 0 && nLoc == 0)) {
V (mutex);
attesaLocali++;
P (locali);
attesaLocali--;
}
nLoc++;
if (nLoc < NMAX && !chiusura && attesaLocali > 0) {
V (locali);
} else {
V (mutex);
}
}
```
```
public void esciLocale () {
P (mutex);
nLoc--;
if (nLoc == 0 && !chiusura && attesaOspiti > 0) {
V (ospiti);
} else if (attesaLocali > 0 && !chiusura) {
V (locali);
} else if (nLoc == 0 && chiusura) {
V (pulizia);
} else {
V (mutex);
}
}
```
## Barista
```
public void pulisciBar () {
P (mutex);
chiusura = true;
if (nLoc > 0 || nOsp > 0) {
V (mutex);
P (pulizia);
}
<...pulisci...>
chiusura = false;
if (attesaOspiti > 0) {
V (ospiti);
} else if (attesaLocali > 0) {
V (locali);
} else {
V (mutex);
}
}
```
# Monitor
```
monitor bar {
int nLoc = 0;
int nOsp = 0;
bool chiusura = false;
condition locali, ospiti, pulizia;
public void entraOspite() {
if (nOsp == NMAX || chiusura) {
wait (ospiti);
}
nOsp++;
if (nOsp < NMAX && !chiusura && !empty(ospiti)) {
signal (ospiti);
}
}
public void esciOspite () {
nOsp--;
if (!empty(ospiti) > 0 && !chiusura) {
signal (ospiti);
} else if (nOsp == 0 && empty(ospiti) == 0 && !empty (locali) > 0 && !chiusura) {
signal (locali);
} else if (nOsp == 0 && chiusura) {
signal (pulizia);
}
}
public void entraLocale () {
if (nLoc == NMAX || chiusura || (!empty(attesaOspiti) && nLoc == 0)) {
wait (locali);
}
nLoc++;
if (nLoc < NMAX && !chiusura && !empty (locali)) {
signal (locali);
}
}
public void esciLocale () {
nLoc--;
if (!empty (ospiti) && nLoc == 0 && !chiusura) {
signal (ospiti);
} else if (!empty (locali) && empty (ospiti) && !chiusura) {
signal (locali);
} else if (nLoc == 0 && chiusura) {
signal (pulizia);
}
}
public void pulisciBar () {
chiusura = true;
if (nLoc > 0 || nOsp > 0) {
wait (pulizia);
}
<...pulisci...>
chiusura = false;
if (!empty(ospiti) {
signal (ospiti);
} else if (!empty (locali)) {
signal (locali);
}
}
}
```
# Scambio di messaggi asincrono
Implementazione in scambio di messaggi **asincrono** del problema "il bar dello stadio".
Seguono le implementazioni del processo gestore e le interfacce Barista, Locali, Ospiti.
## Gestore
```
process gestoreBar {
port signal entraOsp, entraLoc, esciOsp, esciLoc;
port signal richiestaPulizia, finePulizia;
process barista, locale, ospite;
int nLoc = 0;
int nOsp = 0;
bool chiusura = false;
signal s;
queue attesaOsp, attesaLoc; // inizializzate come empty
// helper function per svegliare in maniera corretta i processi in coda
public void svegliaProcesso () {
if (chiusura && nOsp == 0 && nLoc == 0) {
send (s) to barista.ok_pulizia;
barista = receive (s) from finePulizia;
} else if (!chiusura && !attesaOsp.empty && nLoc == 0) {
while (!attesaOsp.empty && nOsp < NMAX) {
ospite = attesaOsp.dequeue();
send (s) to ospite.ok_entra;
nOsp++;
}
} else if (!chiusura && !attesaLoc.empty && nOsp == 0 && attesaOsp.empty) {
while (!attesaLoc.empty && nLoc < NMAX) {
locale = attesaLoc.dequeue();
send (s) to locale.ok_entra;
nLoc++;
}
}
}
...
// implementazione con guardie logiche
do {
* (nLoc == 0 && !chiusura && nOsp < NMAX); ospite = receive(s) from entraOsp; ->
send(s) to ospite.ok_entra;
nOsp++;
* (nOsp == 0 && !chiusura && nLoc < NMAX); locale = receive(s) from entraLoc; ->
send(s) to ospite.ok_entra;
nLoc++;
* (chiusura || (nOsp == NMAX && nLoc == 0)); ospite = receive(s) from entraOsp; ->
attesaOsp.enqueue(ospite)
* (chiusura || (nLoc == NMAX && nOsp == 0)); locale = receive(s) from entraLoc; ->
attesaLoc.enqueue(locale)
* barista = receive(s) from richiestaPulizia; ->
chiusura = true;
if (nLoc == 0 && nOsp == 0) {
send (s) to barista.ok_pulizia;
// qui pulisce
barista = receive(s) from finePulizia;
chiusura = false;
svegliaProcesso();
}
* ospite = receive(s) from esciOsp; ->
nOsp--;
svegliaProcesso();
* locale = receive(s) from esciLoc; ->
nLoc--;
svegliaProcesso();
} od
```
## Barista
```
process Barista {
port signal ok_pulizia;
signal s;
process p;
...
send (s) to gestoreBar.richiestaPulizia;
p = receive(s) from ok_pulizia;
<...pulisci...>
send (s) to gestoreBar.finePulizia;
...
}
```
## Ospiti
```
process Ospite {
port signal ok_entra;
signal s;
process p;
...
send (s) to gestoreBar.entraOsp;
p = receive(s) from ok_entra;
<...bevi birra come un vero tifoso in trasferta...>
send (s) to gestoreBar.esciOsp;
...
}
```
## Locali
```
process Locale {
port signal ok_entra;
signal s;
process p;
...
send (s) to gestoreBar.entraLoc;
p = receive(s) from ok_entra;
<...bevi birra come un vero tifoso in casa...>
send (s) to gestoreBar.esciLoc;
...
}
```
# Rendez-vous
```
process bar {
entry entraOspite;
entry ok_entraOspite;
entry entraLocale;
entry ok_entraLocale;
entry esciOspite;
entry esciLocale;
entry pulizia;
entry ok_pulizia;
entry fine_pulizia;
int nLoc = 0;
int nOsp = 0;
int attesaLoc = 0;
int attesaOsp = 0;
bool chiusura = false;
do {
* (!chiusura); accept entraOspite {}; ->
if (nOsp == NMAX) {
attesaOsp++;
} else {
accept ok_entraOspite;
nOsp++;
}
* accept esciOspite {}; ->
nOsp--;
if (attesaOsp > 0 && !chiusura) {
while (attesaOsp > 0 && nOsp < NMAX) {
accept ok_entraOspite;
}
} else if (attesaOsp == 0 && !chiusura && nOsp == 0 && attesaLoc > 0) {
while (attesaLoc > 0 && nLoc < NMAX) {
accept ok_entraLocale;
}
} else if (chiusura && nOsp == 0) {
accept ok_pulizia;
}
* (!chiusura); accept entraLocale {}; ->
if (nLoc == NMAX || (attesaOsp > 0 && nLoc == 0)) {
attesaLoc++;
} else {
accept ok_entraLocale;
nLoc++;
}
* accept esciLocale {}; ->
nLoc--;
if (nLoc == 0 && attesaOsp > 0 && !chiusura) {
while (attesaOsp > 0 && nOsp < NMAX) {
accept ok_entraOspite;
}
} else if (attesaLoc > 0 && !chiusura) {
while (attesaLoc > 0 && nLoc < NMAX) {
accept ok_entraLocale;
}
} else if (chiusura && nLoc == 0) {
accept ok_pulizia;
}
* accept pulizia {}; ->
chiusura = true;
if (nLoc == 0 && nOsp == 0) {
accept ok_pulizia;
}
* accept fine_pulizia {}; ->
chiusura = false;
} od
}
```
## Ospiti
```
process ospite {
...
call bar.entraOspite;
call bar.ok_entraOspite;
... bevi ...
call bar.esciOspite;
}
```
## Locali
```
process locale {
...
call bar.entraLocale;
call bar.ok_entraLocale;
... bevi ...
call bar.esciLocale;
}
```
## Barista
```
process barista {
...
call bar.pulizia;
call bar.ok_pulizia;
... pulisci ...
call bar.fine_pulizia;
}
```