# 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; } ```