Prova teorica 2015.01.20
Testo: [1]
Esercizio c.1
<syntaxhighlight lang="C"> /*
* Esercizio c.1: Scrivere il monitor lwlrbb. Il monitor deve implementare le seguenti procedure entry: * void write(generic_type val); * generic_type read(void); * Il lwlrbb si comporta come un bounded buffer di MAX elementi che coordina l'attivita' di numerosi processi * produttori/scrittori e numerosi lettori/consumatori. lwlrbb ammette un numero massimo (sempre MAX) di lettori * e scrittori in attesa. Se il buffer e' vuoto e ci sono piu' gia' MAX lettori in attesa, il lettore che e' in * attesa da piu' tempo esce resituendo NULL. In ugual modo se il buffer e' completamente pieno e ci sono gia' MAX * scrittori che attendono di scrivere viene perduto il valore che da piu' tempo nel buffer attende di venir letto, * il primo processo in attesa di scrivere puo' cosi' scrivere il suo elemento nel buffer e sbloccarsi. */
- define MAX
monitor lwlrbb{ generic_type bb[]; int i, nw, nr; bool exitNull; conditions lw, lr;
void lwlrbb(void){ bb = new generic_type[MAX]; exitNull = FALSE; i = nw = nr = 0; }
procedure entry void write(generic_type val){ if(i == MAX){ // Il buffer è completamente pieno if(nw == MAX){ // ci sono già MAX scrittori che attendono di scrivere // spostamento a sinistra di tutti gli elementi, in modo da perdere for(j = 0; j<i; j++) // il valore da più tempo nel buffer bb[j] = bb[j+1]; i--; lw.signal(); // il primo processo in attesa di scrivere puo' scrivere e sbloccarsi. } nw++; lw.wait(); nw--; } else{ // Il buffer non è pieno bb[i] = val; i++; lr.signal(); } }
procedure entry generic_type read(void){ generic_type retval; if(i == 0){ // Il buffer è vuoto if(nr == MAX){ // ci sono gia MAX lettori in attesa exitNull = TRUE; // quindi riattivio il lettore che e' in attesa da piu' tempo, restituendo NULL lr.signal(); } nr++; // incremento il contatore dei lettori in coda lr.wait(); // metto in attesa il lettore // Riprendo l'esecuzione da dove era stata interrotta nr--; // decremento il contatore dei lettori in coda if(exitNull){ // Controllo se è una richiesta di uscita forzata exitNull = FALSE; return NULL; } } else{ // Il buffer non è vuoto i--; retval = bb[i]; lw.signal(); // Riattivo uno scrittore in coda }
}
}