Difference between revisions of "ProvaTeorica 2012.06.15"

From Sistemi Operativi
Jump to navigation Jump to search
 
(2 intermediate revisions by 2 users not shown)
Line 62: Line 62:
 
stopped[index].N--;
 
stopped[index].N--;
 
}
 
}
/* [Case 1] Non esiste un numero in attesa che corrisponde al numero che  
+
/* [Case 2] Non esiste un numero in attesa che corrisponde al numero che  
 
  si deve inserire. Inoltre l'attuale non corrisponde al numero che  
 
  si deve inserire. Inoltre l'attuale non corrisponde al numero che  
 
  si deve inserire. */
 
  si deve inserire. */
Line 76: Line 76:
 
}
 
}
 
}
 
}
 +
</syntaxhighlight>
 +
 +
Esercizio del professore da rivedere
 +
 +
 +
<syntaxhighlight lang="C">
 +
condition c[10]; /* current != -1 &&  ((pali && !i in seq) || (ndrome && seq[n]==i)) */
 +
int current=-1;
 +
boolean waiting[10];
 +
boolean pali=True;
 +
boolean ndrome=False;
 +
int seq[5];
 +
int n=0;
 +
 +
procedure entry synch(i) {
 +
  waiting[i]=True;
 +
  if(current==i) {
 +
    current=-1;
 +
    if(pali) {
 +
      if(n==4) ndrone=True, pali = False;
 +
      if(x=anynotin(seq, n, waiting))
 +
        c[x].signal();
 +
    } else {
 +
      c[seq[n]].signal;
 +
      if(n==0) ndrone=False, pali=True;
 +
     
 +
    }
 +
  }
 +
  if(current!=-1 || pali && cerca(i, seq, n)!=0 || (ndrome && n!=4))
 +
    c[i].wait();
 +
  if(pali)
 +
    seq[n++]==i;
 +
  else
 +
    n--;
 +
  current=i;
 +
  waiting[i]=False;
 +
}
 +
</syntaxhighlight>
 +
 +
 +
 +
== Esercizio c.2 ==
 +
 +
 +
<syntaxhighlight lang="Python">
 +
/*
 +
Esercizio c.2: Implementare facendo uso di un processo server e usando le asend() e areceive() le seguenti primitive
 +
di comunicazione:
 +
sx2send(m,dest1,dest2); Invia il messaggio m o a dest1 o a dest2 (ma non ad entrambi)
 +
m = sx2receive(sender); Riceve un messaggio in maniera sincrona.
 +
il mittente e il destinatario devono riattivarsi solo quando il destinatario ha ricevuto il messaggio.
 +
*/
 +
 +
def sx2send(m,dest1,dest2):
 +
  asend(SND,getpid(),dest1,dest2,m),server)
 +
  arecv(server);
 +
 +
def(sx2receive(sender):
 +
    asend((RECV,getpid(),sender,NULL,NULL),server)
 +
    return arecv(server)
 +
   
 +
process server:
 +
  waiting=Set({})
 +
  pending=[]
 +
  while(True):
 +
    (tag,proc,pi1,p2,m)=arecv(*)
 +
    if(TAG==SND)
 +
      if p1 in waiting:
 +
        asend(m,p1)
 +
        asend(ACK,proc)
 +
        waiting-={p1}
 +
      else if p2 in waiting:
 +
        asend(m,p2)
 +
        asend(ACK,proc)
 +
        waiting-={p2}
 +
      else pending.append((proc,m,p1,p2))
 +
  else: #TAG==RECV
 +
    if(px,mx,p1x,p2x)=searchpending(pending,sender):
 +
      #cerca il primo che ha sender come uno dei destinatari
 +
      #ed elimina l'elemento dalla sequenza
 +
      asend(mx,sender)
 +
      asend(ACK,mx)
 +
    else:
 +
      waiting+={sender}
 
</syntaxhighlight>
 
</syntaxhighlight>

Latest revision as of 16:23, 14 April 2014

http://www.cs.unibo.it/~renzo/so/compiti/2012-06-15.tot.pdf


/*
 * URL: http://www.cs.unibo.it/~renzo/so/compiti/2012-06-15.tot.pdf
 * author: Tommaso Ognibene
*/

monitor palindrome5
{
	// Struttura che rappresenta i numeri bloccati
	typedef struct
	{
		condition C;
		int N;
	} Stopped;

	Stopped stopped[10];
	for (int i = 0; i < 10; i++)
		stopped[i].N = 0;
	int n = 0;
	int palindrome[10];
	repeated = {} // Python-like dictionary
	
	procedure entry synch(int index)
	{
		// Se ho raggiunto la lunghezza del palindromo
		if (n == 10)
		{
			// Azzero le variabili
			n = 0;
			repeated = {};
		}
		// [Case 1] parte sinistra del palindromo
		if (n < 5)
		{
			// Se il numero e' gia' stato inserito
			if (repeated[index])
			{
				// Mi fermo e attendo di essere sbloccato
				stopped[index].N++;
				stopped[index].C.wait();
				stopped[index].N--;
			}
			palindrome[n++] = index;
			repeated[index] = true;
		}
		// [Case 2] parte destra del palindromo
		else
		{
			int number = palindrome[n - 5];
			/* [Case 1] Esiste (almeno) un numero in attesa che corrisponde al numero che 
			   si deve inserire. Lo riattivo. In questo modo evito la starvation. */
			if (stopped[number].N > 0)
			{
				stopped[number].C.signal();
				// Mi fermo e attendo di essere sbloccato
				stopped[index].N++;
				stopped[index].C.wait();
				stopped[index].N--;
			}
			/* [Case 2] Non esiste un numero in attesa che corrisponde al numero che 
			   si deve inserire. Inoltre l'attuale non corrisponde al numero che 
			   si deve inserire. */			
			else if (number != index)
			{
				// Mi fermo e attendo di essere sbloccato
				stopped[index].N++;
				stopped[index].C.wait();
				stopped[index].N--;				
			}
			palindrome[n++] = index;
		}
	}
}

Esercizio del professore da rivedere


condition c[10]; /* current != -1 &&  ((pali && !i in seq) || (ndrome && seq[n]==i)) */
int current=-1;
boolean waiting[10];
boolean pali=True;
boolean ndrome=False;
int seq[5];
int n=0;

procedure entry synch(i) {
  waiting[i]=True;
  if(current==i) {
    current=-1;
    if(pali) {
      if(n==4) ndrone=True, pali = False;
      if(x=anynotin(seq, n, waiting))
        c[x].signal();
    } else {
      c[seq[n]].signal;
      if(n==0) ndrone=False, pali=True;
      
    }
  }
  if(current!=-1 || pali && cerca(i, seq, n)!=0 || (ndrome && n!=4))
    c[i].wait();
  if(pali)
    seq[n++]==i;
  else
    n--;
  current=i;
  waiting[i]=False;
}


Esercizio c.2

/*
Esercizio c.2: Implementare facendo uso di un processo server e usando le asend() e areceive() le seguenti primitive
di comunicazione:
sx2send(m,dest1,dest2); Invia il messaggio m o a dest1 o a dest2 (ma non ad entrambi)
m = sx2receive(sender); Riceve un messaggio in maniera sincrona.
il mittente e il destinatario devono riattivarsi solo quando il destinatario ha ricevuto il messaggio.
*/

def sx2send(m,dest1,dest2):
  asend(SND,getpid(),dest1,dest2,m),server)
  arecv(server);

def(sx2receive(sender):
    asend((RECV,getpid(),sender,NULL,NULL),server)
    return arecv(server)
    
process server:
  waiting=Set({})
  pending=[]
  while(True):
    (tag,proc,pi1,p2,m)=arecv(*)
    if(TAG==SND)
      if p1 in waiting:
        asend(m,p1)
        asend(ACK,proc)
        waiting-={p1}
      else if p2 in waiting:
        asend(m,p2)
        asend(ACK,proc)
        waiting-={p2}
      else pending.append((proc,m,p1,p2))
   else: #TAG==RECV
     if(px,mx,p1x,p2x)=searchpending(pending,sender):
       #cerca il primo che ha sender come uno dei destinatari
       #ed elimina l'elemento dalla sequenza
       asend(mx,sender)
       asend(ACK,mx)
     else:
       waiting+={sender}