Prova teorica 2014.09.24
Jump to navigation
Jump to search
Testo: [1]
Esercizio c.1
/*
* Esercizio c.1: Scrivere un monitor vBB che realizzi un bounded buffer a dimensione variabile.
* Le procedure entry da implementare sono read, write e resize. Read e write hanno gli stessi parametri del BB ordinario.
* La funzione resize ha come parametro un numero intero positivo che rappresenta la nuova dimensione del buffer espressa in numero
* di elementi. Inizialmente il bounded buffer ha dimensione DEFAULTSIZE. Se la dimensione viene incrementata I processi
* eventualmente in attesa di scrivere devono poter inserire I loro elementi nel buffer fino a che e' consentito della nuova dimensione.
* Se la dimensione diminuisce, nuovi scrittori potranno inserire elementi nel buffer solo quando sara' possibile farlo in modo coerente
* con il nuovo numero massimo di elementi.
*/
#define DEFAULTSIZE
monitor vbb{
generic_type bb[];
int i, size;
conditions W, R;
void vbb(void){
bb = new generic_type[DEFAULTSIZE];
i = 0;
size = DEFAULTSIZE;
}
procedure entry void write(generic_type val){
if(i == size){ // Il buffer è completamente pieno
W.wait(); // Metto in attesa il processo
}
// Il buffer non è pieno, scrivo
bb[i] = val;
i++;
R.signal();
}
procedure entry generic_type read(void){
generic_type retval;
if(i == 0){ // Il buffer è vuoto
R.wait(); // Metto in attesa il processo
}
// Il buffer non è vuoto, leggo
i--;
retval = bb[i];
W.signal(); // Riattivo uno scrittore in coda
return retval;
}
procedure entry void resize(unsigned int n){
int old_size, j;
old_size = size;
size = n;
newbb = new generic_type[n];
if(n > old_size){ // Se la nuova dim. è maggiore di quella vecchia
int ndiff = n - old_size; // Numero di celle libere su cui scrivere
for(j = 0; j < old_size; j++) // Copia gli elementi di bb nel nuovo vettore
newbb[j] = bb[j];
bb = newbb;
for(j = 0; j < ndiff; j++) // allora più scrittori possono scrivere perchè vi sono celle libere
W.signal();
}
else{ // Se la nuova dim. è minore o uguale a quella vecchia
for(j = 0; j < n; j++) // Copia gli elementi di bb nel nuovo vettore
newbb[j] = bb[j];
bb = newbb;
if(i >= n){ // se il buffer è comunque completamente pieno
if(i > n)
i = n;
R.signal(); // allora un lettore può leggere
}
else{ // se il buffer non è ancora pieno
W.signal(); // allora uno scrittore può scrivere
}
}
}
}
S.G (talk) 14:18, 21 November 2016 (CET)
Questo è un bounded stack! non un bounded buffer (che deve essere FIFO, se no c'e' starvation!). Renzo (talk) 19:17, 21 November 2016 (CET)
Esercizio c.1 mia soluzione
#define DEFAULTSIZE
monitor vBB {
condition oktowrite, oktoread
int waintingW // scrittori in attesa
int waintingR // lettori in attesa
buffer buffer = defaultsize;
procedure entry write {
if (bufferlen() >= defaultsize)
waitingW ++;
okowrite.wait();
waitingW++;
buffer.enqueue(val);
oktoread.signal();
buffer.enqueue(val);
}
procedure entry read () {
if (buffer.len() == 0)
waitingR++;
oktoread.wait();
waitingR--;
buffer.dequeue();
buffer.dequeue();
oktowrite.signal();
}
procedure entry resize (n) {
buffer=(int*)realloc(n*sizeof(int);
while (waitingW>0)
oktowrite.signal()
}
}
Esercizio 2
Appunti: Si può usare semplicemente il message passing a coda ma inserire in uno stack i messaggi che arrivano. Nella recv si può automandarsi un messaggio con un tag particolare per sapere quando abbiamo letto tutti i messaggi. --FedericoB (talk) 13:49, 9 May 2017 (CEST)