Professional Documents
Culture Documents
prof.
Giuseppe Pelagatti
prof.ssa Donatella Sciuto
prof.ssa Cristina Silvano
Istruzioni
-
Si scriva solo negli spazi previsti nel testo della prova e non si separino i fogli.
Per la minuta si utilizzino le pagine bianche inserite in fondo al fascicolo distribuito con il testo della
prova. I fogli di minuta se staccati vanno consegnati intestandoli con nome e cognome.
vietato portare con s libri, eserciziari e appunti, nonch cellulari e altri dispositivi mobili di calcolo
o comunicazione. Chiunque fosse trovato in possesso di documentazione relativa al corso anche se
non strettamente attinente alle domande proposte vedr annullata la propria prova.
Tempo a disposizione 2 h : 15 m
(4
punti)
_________________________
esercizio 2
(3
punti)
_________________________
esercizio 3
(2
punti)
_________________________
esercizio 4
(2
punti)
_________________________
esercizio 5
(3
punti)
_________________________
esercizio 6
(2
punti)
_________________________
punti)
______________________
statement A
statement B
statement C
statement D
global = 1
pthread_mutex_unlock (&black)
return NULL
/
end left
void
mid (void
arg)
pthread_mutex_lock (&black)
sem_wait (&new)
sem_wait (&old)
pthread_mutex_lock (&white)
pthread_mutex_unlock (&white)
sem_post (&old)
pthread_mutex_unlock (&black)
return (int
/
end mid
void
) arg
right (void
arg)
pthread_mutex_lock (&white)
sem_wait (&old)
pthread_mutex_unlock (&white)
global = 3
return NULL
/
end right
void main ( )
pthread_t th_1, th_2, th_3
sem_init (&new, 0, 0)
sem_init (&old, 0, 1)
pthread_create (&th_2, NULL, mid, (void ) 2)
pthread_create (&th_1, NULL, left, NULL)
pthread_create (&th_3, NULL, right, NULL)
pthread_join (th_1, NULL)
pthread_join (th_2, &global)
pthread_join (th_3, NULL)
return
/
end main
pagina 2 di 19
Si completi la tabella qui sotto indicando lo stato di esistenza del thread nellistante di tempo
specificato da ciascuna condizione, cos: se il thread esiste, si scriva ESISTE; se non esiste, si scriva NON
ESISTE; e se pu essere esistente o inesistente, si scriva PU ESISTERE. Ogni casella della tabella va
riempita in uno dei tre modi (non va lasciata vuota).
Si badi bene alla colonna condizione: con subito dopo statement X si chiede lo stato che il thread assume
tra lo statement X e lo statement immediatamente successivo del thread indicato.
thread
condizione
th_1
th_2
th_3
ESISTE
ESISTE
PU ESISTERE
PU ESISTERE
ESISTE
PU ESISTERE
PU ESISTERE
PU ESISTERE
ESISTE
NON ESISTE
NON ESISTE
PU ESISTERE
Si completi la tabella qui sotto, indicando i valori delle variabili globali (sempre esistenti) nellistante
di tempo specificato da ciascuna condizione. Il valore della variabile va indicato cos:
intero, carattere, stringa, quando la variabile ha un valore definito; oppure X quando indefinita
se la variabile pu avere due o pi valori, li si riporti tutti quanti
il semaforo pu avere valore positivo o nullo (non valore negativo)
Si badi bene alla colonna condizione: con subito dopo statement X si chiede il valore (o i valori) che la
variabile ha tra lo statement X e lo statement immediatamente successivo del thread indicato.
condizione
variabili globali
new
old
global
0/1
0/3
0/1
2/3
Il sistema pu andare in stallo (deadlock), con uno o pi thread che si bloccano, in tre casi diversi
(con deadlock si intende anche un blocco dovuto a un solo thread che non potr mai proseguire). Si
indichino gli statement dove avvengono i blocchi, con il valore (o i valori) della variabile global:
caso
th_1
th_2
lock black
wait new
lock white
wait old
th_3
global
0/3
wait old
1
1/3
pagina 3 di 19
FIRST
void
LAST (void
arg)
pthread_mutex_lock (&GATE)
sem_post (&GO)
pthread_mutex_unlock (&GATE)
sem_wait (&GO)
sem_post (&GO)
return NULL
LAST
main ( )
// codice eseguito da S e Q
pthread_t TH_1, TH_2
sem_init (&GO, 0, 0)
pthread_create (&TH_1, NULL, FIRST, NULL)
pthread_create (&TH_2, NULL, LAST, NULL)
pthread_join (TH_2, NULL)
pthread_join (TH_1, NULL)
exit (1)
/
main
in ciascuna riga lo stato dei processi al termine del tempo indicato; si noti che la prima riga della
tabella potrebbe essere solo parzialmente completata
NOTA BENE:
si considerino solo le funzioni marcate in grassetto nel codice dato
lesecuzione della funzione exec non sospende il processo
AXO prova di gioved 4 febbraio 2016 CON SOLUZIONI
pagina 4 di 19
TH1
TH2
PID
evento processo-chiamata
TGID
S sem_init
pronto
esec
pronto
NE
NE
NE
NE
S pthread_create TH1
10
pronto
esec
pronto
pronto
NE
NE
NE
interrupt da RT_clock,
scadenza quanto di tempo
20
pronto
pronto
esec
pronto
NE
NE
NE
fork
30
pronto
pronto
esec
pronto
pronto
NE
NE
P open
40
pronto
pronto
A (open)
esec
pronto
NE
NE
TH1 sem_wait
50
pronto
esec
A(s_wait)
pronto
NE
NE
S pthread_create TH2
60
pronto
esec
pronto
pronto
NE
70
pronto
pronto
esec
pronto
pronto
NE
fork
80
pronto
pronto
esec
pronto
pronto
pronto
P waitpid (pid1)
90
pronto
pronto
A (wait)
esec
pronto
pronto
Q execl
100
pronto
pronto
A (wait)
esec
pronto
pronto
interrupt da RT_clock,
scadenza quanto di tempo
110
pronto
pronto
A (wait)
pronto
esec
pronto
TH2 mutex_lock
120
pronto
pronto
A (wait)
pronto
esec
pronto
TH2 sem_post
130
pronto
pronto
A (wait)
esec
pronto
pronto
pronto
TH1 mutex_lock
140
pronto
esec
A (wait)
A (lock)
pronto
pronto
pronto
S pthread_join (TH2)
150
pronto
A (join)
A (wait)
A (lock)
pronto
pronto
esec
R write
160
pronto
A (join)
A (wait)
A (lock)
esec
pronto
A(write)
Q exit
170
pronto
A (join)
esec
A (lock)
NE
pronto
A(write)
P exit
180
pronto
A (join)
NE
A (lock)
NE
esec
A(write)
TH2 mutex_unlock
190
pronto
A (join)
NE
esec
NE
pronto
A(write)
TH1 sem_post
200
pronto
A (join)
NE
esec
NE
pronto
A(write)
P pid1
P pid2
pagina 5 di 19
6 ms, GR
0,75 ms e WGR
1 ms
exe U x ms
un task (da determinare) ha
eseguito codice utente (modo U)
dal tempo assoluto precedente
fino al tempo assoluto x ms
ti.nome_funzione_di_SO ...
il
task
ti
ha
eseguita
la
funzione_di_SO; se serve, si specifica
csw ti
tj
avviene la commutazione di
contesto dal task ti al task tj; il
tempo di commutazione di
contesto sempre trascurabile
Si effettui lo scheduling CFS dei task (classe NORMAL) indicati sulla base di azioni e tempi indicati nelle
colonne ATTIVIT e TEMPI, compilando i campi vuoti non oscurati. Per ogni riga, vanno riportati i valori
che si avranno alla fine dellattivit.
La colonna TASK e CONDIZIONI per le eventuali annotazioni ausiliarie: a ciascuna attivit specificata si
aggiunge il nome del task che la svolge, si calcola il VRT di risveglio, si valuta una condizione di preemption,
o si dice se scade il quanto. Se implicato dalle azioni specificate, task esistenti possono terminare e task
nuovi possono essere creati (in questultimo caso si usino le eventuali colonne lasciate vuote in partenza).
pagina 6 di 19
inizio
exe U
TEMPO
0 ms
4,6 ms
wait_event
exe U
5,6 ms
sys_exit
exe U
8,6 ms
wake_up
exe U
9,8 ms
TASK e
CONDIZIONI
RUNQUEUE
TASK
L0
NRT
LC
PER
RQL
VRTC
t1
LOAD
t2
LOAD
t3
LOAD
CURR
t2
DELTA
RB
t3, t1
SUM
1,2
1,2
VMIN
VRT
1,2
1,2
NRT
LC
PER
RQL
VRTC
CURR
DELTA
RB
SUM
VMIN
VRT
NRT
LC
PER
RQL
VRTC
CURR
DELTA
RB
SUM
VMIN
VRT
NRT
LC
PER
RQL
VRTC
CURR
DELTA
RB
SUM
VMIN
VRT
NRT
LC
PER
RQL
VRTC
CURR
DELTA
RB
SUM
VMIN
VRT
pagina 7 di 19
SOLUZIONE
ATTIVIT
TEMPO
TASK e
CONDIZIONI
0 ms
inizio
exe U
4,6 ms
wait_event
exe U
5,6 ms
t3.wait_event
csw t3
t1
t1.exe U 5,6
8,6 ms
t1.sys_exit
csw t1
t2
t2.exe U 8,6
sys_exit
exe U
wake_up
exe U
t2.exe U 3,6
t2.Q scade
csw t2
t3
t3.exe U 4,6
9,8 ms
t2.wake_up t3
t3.VRT max (2,2,
2,2 6/2) 2,2
t2.cond_pr
2,2 1 0,25 2,2
falsa t2.exe U 9,8
RUNQUEUE
NRT
PER
RQL
CURR
RB
VMIN
NRT
PER
RQL
CURR
RB
VMIN
NRT
PER
RQL
CURR
RB
VMIN
NRT
PER
RQL
CURR
RB
VMIN
NRT
PER
RQL
CURR
RB
VMIN
3
6
5
t2
t3, t1
0
3
6
5
t3
t1, t2
1,2
2
6
4
t1
t2
1,2
1
6
3
t2
vuota
2,2
2
6
4
t2
t3
2,2
TASK
L0
LC
Q
VRTC
DELTA
SUM
VRT
LC
Q
VRTC
DELTA
SUM
VRT
LC
Q
VRTC
DELTA
SUM
VRT
LC
Q
VRTC
DELTA
SUM
VRT
LC
Q
VRTC
DELTA
SUM
VRT
t1
LOAD
1 / 5 0,2
6 1/5 1,2
1/1 1
0
1,2
1,2
0,2
1,2
1
0
1,2
1,2
1 / 4 0,25
6 1/4 1,5
1
1
2,2
2,2
TERMINATO
TERMINATO
t2
LOAD
3 / 5 0,6
6 3/5 3,6
1 / 3 0,33
0
0
0
0,6
3,6
0,33
3,6
3,6
1,2
3 / 4 0,75
6 3/4 4,5
0,33
0
3,6
1,2
3/3 1
6 3/3 6
0,33
3
6,6
2,2
3 / 4 0,75
6 3/4 4,5
0,33
4,2
7,8
2,6
t3
LOAD
1 / 5 0,2
6 1/5 1,2
1/1 1
0
1,2
1,2
0,2
1,2
1
1
2,2
2,2
IN ATTESA
IN ATTESA
1 / 4 0,25
6 1/4 1,5
1
0
2,2
2,2
Il sistema parte con tre task in round robin, con pesi diversi ma con incrementi di VRT uguali per quanto,
ossia VRT 1,2 ms per tutti e tre i task. Ecco i passaggi salienti:
allinizio il task t2 esegue per 3,6 ms, poi scade il quanto di t2 e il sistema commuta a t3, che il task
LFT in coda RB
il task t3 esegue per 1 ms; poi chiama un servizio di SO, si autosospende con wait_event e il sistema
commuta a t1, che il task LFT in coda RB; i parametri vengono ricalcolati
il task t1 esegue per 1 ms; poi termina con sys_exit e il sistema commuta t2, che il task LFT (e anzi
lunico task) in coda RB, la quale dunque resta vuota; i parametri vengono ricalcolati
il task t2 esegue per 3 ms; poi risveglia il task t3 (lunico in attesa dunque pu essere solo t3 il task da
risvegliare), lo rimette in coda RB (che era vuota dunque il task t3 risvegliato diventa il task LFT), ma
mantenendogli il VRT che aveva poich si ha:
t3.VRT max (t3.VRT, VMIN LT / 2) max (2,2, 2,2 6 / 2) 2,2 (lattesa di t3 stata breve)
e infine il task t2 valuta per il task t3 risvegliato la condizione di preemption:
t3.VRT WGR t3.LC CURR.VRT ossia (ora il task CURR t2) 2,2 1 0,25 2,2
che risulta falsa (di nuovo poich lattesa di t3 stata breve), e cos il task t2 NON imposta la
rischedulazione; i parametri vengono ricalcolati
il task t2 si avvia al rientro modo U, il sistema NON rischedula, pertanto il task t2 prosegue ed esegue
per altri 1,2 ms (DELTA arriva a 4,2), poi la simulazione finisce senza che il task t2 abbia consumato
tutto il suo quanto (infatti ha consumato 4,2 ms su un quanto che correntemente di 4,5 ms)
Si noti che in tre momenti il numero di task runnable NRT varia e alcuni parametri globali del sistema (NRT e
RQL) e locali di task (LC e Q) vengono ricalcolati.
AXO prova di gioved 4 febbraio 2016 CON SOLUZIONI
pagina 8 di 19
In tutte le domande seguenti le pagine fisiche richieste dal programma vengono messe a disposizione nel
seguente ordine: A04, A05, A06, A07, A08, A09, A0A, A0B, ecc.
Domanda 1: si decomponga lindirizzo di argv per ottenere la pagina iniziale della pila.
PGD
PUD
PMD
PT
OFFSET
255
511
256
128
PGD
PUD
PMD
PT
NPF
A04
RO
A05
RO
NX
A06
RW
NX
255
511
256
A07
RW
NX
255
511
255
A08
RW
NX
255
511
254
A09
RW
NX
261
A0A
RW
NX
262
A0B
RW
NX
pagina 9 di 19
I processi padre (normale) P e figlio (normale) Q condividono le pagine, tutte marcate in sola lettura (se gi
non lo erano, come p. es. il codice) per permettere leventuale separazione on demand a tempo debito
(quando venissero accedute in scrittura si veda poi la domanda 4), tranne la pagina in cima alla pila dove
la funzione fork scrive il risultato (cio il pid del figlio o zero), la quale pagina viene dunque separata subito
al momento della creazione: il padre P ne prende una nuova, numero A0C, il figlio Q (qui non mostrato)
mantiene quella vecchia (numero A09), ed entrambe sono marcate in RW. Ecco la tabella delle pagine di P:
FLAG
RO/RW
X/NX
PGD
PUD
PMD
PT
NPF
A04
RO
A05
RO
NX
A06
RO
NX
255
511
256
A07
RO
NX
255
511
255
A08
RO
NX
255
511
254
A0C
RW
NX
262
A0A
RO
NX
263
A0B
RO
NX
pagina 10 di 19
Si ricorda che i processi padre (normale) P e figlio (thread) R hanno una sola tabella delle pagine, condivisa.
Prima, da parte di pthread_create, viene allocata una pagina fisica (numero A0D) per la pagina di pila del
processo thread R creato (la entry del PGD 254, come sempre per le pile dei thread nel modello virtuale
standard dei processi di Linux). Poi, si osservi che modificare una variabile globale causa la separazione della
pagina dei dati statici di P / R rispetto al figlio Q creato in precedenza (domanda 3), il quale ha pagina dati
statici ancora condivisa con P. Dunque tale modifica di variabile causa lallocazione di una nuova pagina di
dati statici (numero A0E) in RW, naturalmente sempre condivisa tra i due processi P / R poich R un
processo thread secondario del processo normale P. Ecco la tabella delle pagine di R (che anche di P):
FLAG
RO/RW X/NX
PGD
PUD
PMD
PT
NPF
A04
RO
A05
RO
NX
A0E
RW
NX
255
511
256
A07
RO
NX
255
511
255
A08
RO
NX
255
511
254
A0C
RW
NX
262
A0A
RO
NX
263
A0B
RO
NX
254
511
511
511
A0D
RW
NX
pagina 11 di 19
2e
Ecco la dimensione iniziale delle aree virtuali degli eseguibili dei programmi X e Y che verranno utilizzati:
XC 8 K byte
XS 4 K byte
XM 2 K byte
YC 4 K byte
YS 8 K byte
YM 2 K byte
liste LRU
attivazioni
processi
iniziale
P Q
active
inactive
NPV
NPF
NPV
NPF
NPV
NPF
NPV
qc0
qp0
qp1
pc0
pp0
qm0
swap file
inizialmente vuoto
NPF
pc0
pp0
NPV
NPF
1
1
pagina 12 di 19
Domanda 1
Il processo P esegue una chiamata a funzione il cui record di attivazione richiede una nuova pagina di pila.
Si compilino la tabella delle pagine, il TLB e le liste LRU.
Levento di chiamata a funzione utente comporta laggiunta della pagina virtuale di pila pp1 e la sua
allocazione, in quanto la pagina viene acceduta dalla chiamata a funzione. Ora vale FREE 2. Poich vale
FREE 1 1 MIN_FREE, necessario invocare PFRA per portarsi a MAX_FREE 1 4. Dunque occorre
rilasciare due pagine prima di potere allocare la nuova pagina di pila. Prima si rilascia la pagina qp0 (che in
coda alla inactive), liberando la pagina fisica 1, e si copia qp0 nello swap file poich il suo dirty bit D vale 1
(ipotesi iniziale), e poi si rilascia anche la pagina qm0 (che ora in coda alla lista inactive), liberando la
pagina fisica 5, senza copiare qm0 nello swap file poich il suo dirty bit D vale 0 (ipotesi iniziale). Nel TLB si
registra la pagina pp1 aggiunta, poich viene acceduta come detto prima con dirty bit D uguale a 1 (la
funzione scrive nellarea di attivazione). La pagina pp1 aggiunta entra in testa alla lista active, con referenza.
NPV
NPF
NPV
NPF
NPV
NPF
NPV
qc0
pp1
qp1
pc0
pp0
swap file
qp0
NPF
pc0
pp0
pp1
NPV
NPF
liste LRU
attivazioni
processi
active
iniziale
P Q
finale
P Q
qp1
inactive
pagina 13 di 19
Domanda 2
Il processo P crea il processo figlio R (P esegue fork); il processo P rimane in esecuzione.
Si compilino la tabella delle pagine, il TLB e le liste LRU.
Levento di creazione comporta la duplicazione della cima delle pila, con il processo padre P che deve
allocare la pagina nuova (pp1 in pagina fisica 5) e il processo figlio R che tiene la vecchia (rp1 che resta in
pagina fisica 1); per il momento tutte le altre pagine di P restano condivise tra padre P e figlio R. Ora vale
FREE 3. Poich NON vale FREE 1 2 MIN_FREE, lalgoritmo PFRA NON viene attivato. Dunque viene
allocata una sola pagina fisica (la prima libera ossia la numero 5) per pp1. Il TLB cambia, poich ora la
pagina virtuale pp1 associata alla pagina fisica 5 con il suo dirty bit D uguale a 1. Le pagine di R (rc0, rp0
e rp1) entrano in testa alla lista active, con referenza, nellordine virtuale noto.
NPV
NPF
NPV
NPF
NPV
NPF
NPV
qc0
rp1
qp1
pc0 / rc0
pp0 / rp0
pp1
swap file
qp0
NPF
pc0
pp0
pp1
NPV
NPF
liste LRU
attivazioni
processi
iniziale
P Q
finale
P Q R
active
inactive
qp1
qp1
pagina 14 di 19
Domanda 3
Il processo P accede al codice e alla pagina in cima alla pila. Durante questo periodo viene eseguita il
daemon kswapd.
Si compilino la tabella delle pagine e le liste LRU.
Il daemon kswapd esegue lalgoritmo Controlla_liste: le pagine pc0 e pp1 di P, gi in lista active, con
referenza, e ora accedute, vanno in testa alla lista active, con referenza; le altre pagine con referenza in
active perdono la referenza, tranne pp0 che da TLB risultava anchessa essere stata acceduta e che quindi va
pure in testa alla lista active mantenendo la referenza; mentre la pagina qc0, in active senza referenza, va in
testa a inactive con referenza. Poich vale FREE 2 MAX_FREE, il daemon kswapd attiva lalgoritmo PFRA
e questo deve scaricare una pagina per ritornare a MAX_FREE; dunque si scarica la pagina qp1 (che in
coda a inactive), e la si copia in testa alla swap file poich il suo dirty bit D vale 1 (ipotesi iniziali). Nota: lo
stato del TLB non richiesto, comunque lalgoritmo Controlla_liste azzererebbe tutti i bit A delle pagine nel
TLB, tranne i bit A di quelle che vengono accedute (poich vengono accedute sia prima sia dopo lattivazione
di kswapd).
NPV
NPF
NPV
NPF
qc0
rp1
pp0 / rp0
pp1
swap file
NPV
NPF
NPV
pc0 / rc0
qp1 qp0
liste LRU
attivazioni
processi
active
iniziale
P Q R
qp1
finale
P Q R
QC0
inactive
pagina 15 di 19
Domanda 4
Il processo P esegue una wait e va in stato di attesa, il processo R viene posto in esecuzione e chiama una
execl per mandare in esecuzione il programma Y.
Si compilino la tabella delle pagine e le liste LRU.
Il processo P esce dallesecuzione (e si avrebbe flush completo del TLB). Prima la execl di R deve separare il
processo R dal processo padre P, poich le pagine rc0 e rp0 sono ancora condivise con P (si noti che il
processo R ha gi una pagina di pila separata, rp1). Poi, considerando il modello virtuale del programma Y, la
execl di R deve allocare due nuove pagine per R: una nuova di codice e una nuova di pila (per ora le due
pagine dei dati statici di R non vengono allocate la loro eventuale allocazione avverrebbe in seguito su
richiesta). Pertanto la execl di R smarca le pagine rc0 e rp0 condivise con P, e rilascia la pagina rp1; inoltre la
execl di R le toglie tutte e tre della lista active, poich essa ha successo e non si rientra al vecchio codice di
R; cos ora ci sono quattro pagine libere, cio vale FREE 4. Poich NON vale FREE 2 2 MIN_FREE,
lalgoritmo PFRA NON viene attivato. Ora si allocano rc0 (in pagina fisica 1) e rp0 (in pagina fisica 2). Le
pagine rc0 e rp0 nuove vengono inserite in testa alla lista active, con referenza, nellordine virtuale noto.
NPV
NPF
NPV
NPF
NPV
NPF
NPV
qc0
rc0
rp0
pc0
pp0
pp1
swap file
qp1 qp0
liste LRU
attivazioni
processi
active
iniziale
P Q R
QC0
finale
P Q R
QC0
inactive
pagina 16 di 19
int main ( )
/
processo P
dichiarazioni varie
processo Q
pid = fork ( )
if (pid == 0)
processo R
end if
end if
exit (0)
/
end main
pagina 17 di 19
< 0, dir ,8 > < 3, dir, 9 > < 7, dir, 20 > < 10, dir, 12 > < 72, norm, 60 >
< 86, norm, 72 > < 92, norm, 90 >
blocco 8:
blocco 9:
blocco 12:
blocco 20:
blocco 60:
ITALIANO
blocco 72:
INGLESE
blocco 90:
FRANCESE
Nota bene: lo i-node associato al catalogo radice / ha 0 come i-number, la i-lista contiene terne
< i-number, tipo_file, indice_blocco >, e i cataloghi contengono coppie < i-number, nome_file >.
Si svolgano i punti seguenti:
1) Si indichi il contenuto delle variabili seguenti allistante di tempo T1:
riferimento
a riga
riferimento
a riga
riferimento
a riga
.....
14
numero
di riferimenti
i-number
......
...
...
15 L NE
15 L NE
15
0 3
1 2 3 2 1
92
16 L NE
16 L NE
16
0 3 4 6 7 L
1 2 1 L
86 L
17 L NE
17
0 6 8 L
1 2 L
72 L
17 L NE
18
15
posizione
corrente
Nota bene i nomi dei campi: file des indica il numero di descrittore di file; riferimento a riga indica il riferimento alla riga
della tabella globale dei file aperti dove si trova il descrittore del file; posizione corrente lindicatore di posizione
corrente allinterno del file; numero di riferimenti il numero di riferimenti da parte dei processi che hanno aperto il file;
i-number si riferisce allo i-node del file.
Il segno indica che presente un valore non significativo ai fini del problema. Le tabelle sono semplificate e
contengono solamente le colonne che si chiede di riempire.
pagina 18 di 19
pagina 19 di 19