Difference between revisions of "ProvaTeorica 2012.06.15"
		
		
		
		
		
		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  | + | 			/* [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}