Politecnico di Milano
Dipartimento di Elettronica e Informazione
prof.ssa Anna Antola
prof. Luca Breveglieri prof. Giuseppe Pelagatti
prof.ssa Donatella Sciuto prof.ssa Cristina Silvano
AXO – Architettura dei Calcolatori e Sistemi Operativi Prova di venerdì 19 novembre 2010
Cognome________________________ Nome _______________________
Matricola_____________________ Firma ___________________________
Istruzioni
• Si scriva solo sui fogli distribuiti. Non si separino questi fogli.
• Per i calcoli si utilizzino le pagine bianche in fondo allo scritto.
• È vietato portare all’esame libri, eserciziari, appunti, calcolatrici e telefoni cellulari. Chiunque fosse trovato in possesso di documentazione relativa al corso – anche se non strettamente attinente alle domande pro- poste – vedrà annullata la propria prova.
• Non è possibile lasciare l’aula conservando il tema della prova in corso.
• Tempo a disposizione: 2 h : 30 m
Valore indicativo di domande ed esercizi, voti parziali e voto finale:
Esercizio 1 (4 punti) _________________________
Esercizio 2 (4.5 punti) _________________________
Esercizio 3 (4 punti) _________________________
Esercizio 4 (2.5 punti) _________________________
Esercizio 5 (1 punti) _________________________
Voto finale: (16 punti) ______________________
I NUMERI INDICANO I PUNTEGGI APPROSSIMATIVI.
Esercizio n. 1 – modello thread e parallelismo
Si consideri il programma C seguente (gli “#include” sono omessi):
int well = 0;
pthread_mutex_t cover = PTHREAD_MUTEX_INITIALIZER;
sem_t sem;
void ∗ toss (void ∗ arg) { int coin = (int) arg;
pthread_mutex_lock (&cover);
well = well + coin; /∗ statement
A
∗/pthread_mutex_unlock (&cover);
coin = 0;
sem_post (&sem);
return NULL;
} /∗ end toss ∗/
void ∗ fish (void ∗ arg) { int coin = (int) arg;
sem_wait (&sem);
pthread_mutex_lock (&cover);
well = well - coin;
pthread_mutex_unlock (&cover);
coin = 2 ∗ coin; /∗ statement
B
∗/return NULL;
} /∗ end fish ∗/
void main (...) {
pthread_t visitor [2], fisher;
sem_init (&sem, 0, 0);
pthread_create (&visitor [0], NULL, &toss, (void ∗) 5);
pthread_create (&visitor [1], NULL, &toss, (void ∗) 5);
sem_wait (&sem);
pthread_create (&fisher, NULL, &fish, (void ∗) 1);
pthread_join (visitor [0], NULL);
pthread_join (visitor [1], NULL); /∗ statement
C
∗/pthread_join (fisher);
return;
} /∗ end main ∗/
Si completi la tabella sotto riportata, indicando gli stati delle variabili GLOBALI (ovviamente tutte esistenti) negli istanti di tempo specificati. Lo stato di una variabile può essere indicato come:
• intero, carattere, stringa, quando la variabile ha valore definito
• X, quando la variabile non è stata ancora inizializzata
• se la variabile si può trovare in due o più stati, li si riporti tutti quanti
Si presti attenzione alla colonna “condizione”. In particolare, con “subito dopo statement X” si intende richiedere i valori che le variabili possono assumere tra lo statement X e lo statement immediatamente suc- cessivo del thread indicato nella condizione stessa.
variabili globali condizione
well sem subito dopo stat. A in visitor [0] 5 / 10 0 / 1
subito dopo stat. B in fisher 9 0
subito dopo stat. C in main 10 / 9 1 / 0
Si completi la tabella sotto predisposta indicando - per ciascuno degli istanti di tempo specificati - se le variabili riportate esistono con certezza. Nei casi in cui la variabile considerata non esiste oppure può non esistere, si lasci in bianco la casella corrispondente.
Si presti attenzione alla colonna “condizione”. In particolare, con “subito dopo statement X” si intende richiedere i valori che le variabili possono assumere tra lo statement X e lo statement immediatamente suc- cessivo del thread indicato nella condizione stessa.
variabili locali dei thread condizione
coin in visitor [0] coin in fisher subito dopo stat. A in visitor [0] esiste con certezza (può non esistere)
subito dopo stat. B in fisher (può non esistere) esiste con certezza
subito dopo stat. C in main (non esiste) (può non esistere)
Esercizio n. 2 – nucleo e commutazione tra processi prima parte – stati dei processi
Si considerino i seguenti frammenti di programma:
/∗ programma CODICE_UNO.c ∗/
main ( ) { ...
fd = open (“/info2/file1”, O_RDWR); / ∗ 3 blocchi ∗/
pid1 = fork ( );
if (pid1 == 0) {
/∗ codice eseguito da Q figlio di P ∗/
...
pid2 = fork ( );
if (pid2 == 0) {
/ ∗ codice eseguito da R figlio di Q ∗/
execl (“/acso/cod_mutato”, cod_mutato, NULL);
write (stdout, err_msg, 50);
exit (2);
} else {
/∗ codice eseguito da Q ∗/
write (fd, buffer, 1000); / ∗ 2 blocchi ∗/
close (fd);
exit (1);
} /∗ end if ∗/
} else {
/ ∗ codice eseguito da P ∗/
pid1 = wait (&status);
close (fd);
exit (0);
} /∗ end if ∗/
} /∗ CODICE_UNO ∗/
/∗ programma CODICE_DUE.c ∗/
main ( ) { ...
write (stdout, c, 20);
exit (3);
} /∗ CODICE_DUE ∗/
Dati due processi P e S:
• il processo P esegue il programma CODICE_UNO e crea il figlio Q; il processo Q crea il figlio R che esegue una mutazione di codice; il codice mutato qui non è riportato
• il processo S esegue il programma CODICE_DUE Non ci sono altri processi utente nel sistema.
Ulteriori specifiche del sistema:
1. i processi utente hanno associata una priorità, il processo “idle” ha priorità minima e non esistono altri processi nel sistema
2. le priorità relative a tutti i proccesi attivi nel sistema sono indicate, quando necessario, nella tabella di commutazione dei processi da completare
3. si ricorda che quando un processo diventa pronto e ha priorità maggiore di quello in esecuzione, lo scheduler va attivato
4. il buffer del driver di standard output ha dimensione di 50 caratteri 5. per tutte le operazioni sui file che implicano trasferimento di blocchi:
a) la dimensione di un blocco dati di dati trasferito in DMA da o su file è di 512 byte
b) l’interruzione di fine DMA è associata al trasferimento di un singolo blocco del file (evento DMA_in per lettura di un blocco ed evento DMA_out per scrittura di un blocco su file)
6. per la lettura e scrittura su file:
- le operazioni di lettura e scrittura su file accedono sempre a disco, cioè è sempre necessario eseguire trasferimenti in DMA
7. per l’apertura del file:
a) è sempre necessario trasferire in DMA:
- 1 blocco per l’accesso allo I-node di ogni cartella o file presente nel nome-percorso (pathname) (tranne che per la cartella radice), e
- 1 blocco per il contenuto di ogni cartella presente nel nome-percorso (pathname)
b) una volta terminata l’operazione di apertura, l’area di memoria centrale viene resa disponibile e pertanto una successiva apertura del file richiede il trasferimento tramite DMA
8. l’operazione di chiusura di un file (close) implica solo l’aggiornamento delle tabelle gestite dal S.O.
presenti in memoria centrale
9. le chiamate di sistema “wait” e “waitpid” invocano “Sleep_on” su un evento opportuno
10. per completare la tabella delle commutazioni, si faccia riferimento alla notazione vista a lezione
DOMANDA
Si completino le parti mancanti della tabella di commutazione dei processi (riportata alle due pagine seguenti).
AVVERTENZE
Nella tabella di commutazione proposta sono previste righe da completare in cui:
a) è specificato l’evento (con informazioni aggiuntive); in questo caso sono da completare le parti relative a: moduli del S.O., contesto e stato dei processi
b) è specificato lo stato dei processi raggiunto dopo il verificarsi dell’evento; in questo caso sono da completare i campi relativi a: evento (con eventuali informazioni aggiuntive), moduli del S.O. e contesto
NOTA BENE:
• l’evento in questione è sempre determinabile univocamente dallo stato raggiunto, dall’evoluzione precedente dei processi, dal codice dei programmi e dalle ulteriori specifiche di sistema
• se l’evento è un interrupt è obbligatorio usare la notazione “n interrupt” indicando esat- tamente il numero di interruzioni che si sono verificate
evento (è preceduto dal processo nel cui contesto l’evento si verifica)
informazioni aggiuntive
stato dei processi dopo la gestione dell’evento
P Q R S
esec non esiste non esiste pronto
P: open open ha inizializzato
il DMA in lettura attesa (E1) non esiste non esiste esec
S: 2 interrupt
da DMA_in attesa (E1) non esiste non esiste esec
S: interrupt da orologio
il quanto di tempo di S è scaduto
S < P
attesa (E1) non esiste non esiste esec
S: 1 interrupt da DMA_in
è relativo all’ultimo blocco da trasferire
S < P
esec non esiste non esiste pronto
P: pd1 = fork
il quanto di tempo di P è scaduto
S < P = Q
pronto esec non esiste pronto
Q: pid2 = fork
S < P < Q = R
pronto esec pronto prontoTABELLA DI COMMUTAZIONE DEI PROCESSI
(continua)evento (è preceduto dal processo nel cui contesto l’evento si verifica)
informazioni aggiuntive
stato dei processi dopo la gestione dell’evento
P Q R S
Q: interrupt da orologio
il quanto di tempo di Q è terminato
Q < S < P < R
pronto pronto esec pronto
R: write(1)
write ha trasferiti 50 caratteri nel buffer
del driver
Q < S < P
esec pronto attesa (E2) pronto
v. AVVERTENZE
P: wait
S < Q
attesa (E3) esec attesa (E2) prontoQ: exit
P < S
pronto non esiste attesa (E2) esecv. AVVERTENZE
S: 50 interrupt
da stampante
S < P < R
pronto non esiste esec prontoTABELLA DI COMMUTAZIONE DEI PROCESSI
(fine)Nota bene: chiaramente la “execl” di R è fallita, giacché va in esecuzione la “write” successiva.
In rosso sono colorate le parti di tabella assegnate.
seconda parte – funzioni del nucleo
Si consideri la tabella di commutazione della prima parte: per i due eventi sotto riportati si risponda alle domande in modo coerente con lo svolgimento già effettuato della prima parte.
Nelle domande in cui è chiesto di completare lo stato della pila, per indicare gli indirizzi di ritorno memoriz- zati nella stessa, si usi la notazione “indirizzo di ritorno a XXXX” dove, al posto di XXXX, va specificato codi- ce utente oppure il nome del modulo di S.O. a cui si ritorna
Evento
P
: open• si indichino i moduli del Sistema Operativo eseguiti nel contesto di P (anche parzialmente) per ge- stire l’evento
G_SVC_1 open
Sleep_on_1 (E1) Change
• si completi la figura sotto riportata indicando uno stato possibile della pila di sistema di P così come risulta dopo la gestione dell’evento considerato
indirizzi minori
indirizzo ritorno a Sleep_on indirizzo ritorno a open indirizzo ritorno a G_SVC
PSR: modo U
indirizzi
maggiori
indirizzo ritorno a codice utente
pila di sistema di P
Evento
S
: 1 interrupt da DMA_in (è relativo all’ultimo blocco da trasferire)• si indichino i moduli del Sistema Operativo eseguiti per gestire l’evento e il processo (o i processi) nel cui contesto è eseguito ogni modulo
moduli di S.O. eseguiti per gestire l’evento
processo (i) nel cui contesto è eseguito ogni modulo
R_int (DMA_in) Wake_up (E1)
Preempt_1 Change Sleep_on_1 (E1)
open G_SVC 2/3
S S S S − P
P P P
• si completi la figura sotto riportata indicando uno stato possibile della pila di sistema di S così come risulta dopo la gestione dell’evento considerato
indirizzi minori
indirizzo ritorno a Preempt indirizzo ritorno a R_int
PSR: modo U
indirizzi
maggiori
indirizzo ritorno a codice utente
pila di sistema di S
Esercizio n. 3 – memoria virtuale
Un sistema dotato di memoria virtuale con paginazione e segmentazione tipo UNIX è caratterizzato dai pa- rametri seguenti: la memoria fisica ha capacità 32 K byte, la memoria logica ha capacità di 64 K byte e la dimensione delle pagine è di 4096 byte.
(a) Indicare il numero di pagine fisiche e il numero di pagine logiche del sistema.
n. pagine fisiche:
8
n. pagine logiche:16
(b) Nel sistema saranno attivati i processi P e Q che eseguono i programmi X e Y, che condi- vidono un segmento dati. La dimensione ini- ziale dei segmenti dei due programmi è la se- guente:
CX: 8 K DX: 4 K PX: 4 K COND: 4 K CY: 12 K DY: 4 K PY: 4 K COND: 4 K Il segmento COND è allocato lasciando 2 pa- gine libere dopo il segmento dati di X e Y.
Inserire in tabella la struttura in pagine della memoria virtuale dei due programmi X e Y (notazione: CX0, CX1, DX0, PX0,… CY0, …, COND0, ...).
indirizzo di
pagina virtuale
X Y
0 CX0 CY0
1 CX1 CY1
2 DX0 CY2
3 DY0
4
5 COND0
6 COND
7 8 9 A B C D E
F PX0 PY0
(c) A un certo istante
t
0 sono terminati, nell’ordine, gli eventi seguenti:• P viene creato (“fork” di P ed exec di X)
• P esegue una “fork” e crea il processo figlio Q
• Q accede alla pagina condivisa COND
• Q chiama una funzione che si trova nella pagina di codice corrente, la quale funzione esegue un accesso in scrittura a una struttura dati il cui indirizzo virtuale assoluto è 2000 hex
• P accede alla pagina dati
Considerando le ipotesi seguenti, compilare le tabelle della situazione al tempo
t
0 relative alla memo- ria fisica e al contenuto della MMU:• il lancio in esecuzione di un programma avviene caricando solo la pagina di codice con l’istruzione di partenza, la prima pagina dati e una pagina di pila, in quest’ordine
• il caricamento di ulteriori pagine in memoria avviene “on demand”
• il numero di pagine residenti R è pari a 3
• l’indirizzo esadecimale di partenza di X è 11AA hex (indirizzo virtuale assoluto)
• l’indirizzo esadecimale di partenza di Y è 2222 hex (indirizzo virtuale assoluto)
• si utilizza l’algoritmo LRU per la sostituzione di pagine di memoria, considerando che almeno una pagina di pila debba sempre rimanere in memoria
• l’allocazione delle pagine virtuali nelle pagine fisiche avviene sempre in sequenza
• all’inizio della sequenza di eventi la MMU è vuota, e se è richiesta una nuova riga si utilizzi sempre la prima riga libera
situazione al tempo
t
0memoria fisica MMU
indirizzo
fisico pagine allocate proc. NPV NPF valid
bit
0 CP1 = CQ1 P CP1 / 1 0 1
1 DP0 = (DQ0) P DP0 / 2 1 1
2 PP0 P PP0 / F 2 1
3 PQ0 Q CQ1 / 1 0 1
4 (COND) DQ0 Q (DQ0 / 2) (COND / 5) DQ0 / 2 (1) 4 1 / 0 / 1 / 0 / 1
5 Q PQ0 / F 3 1
6 7
(d) A un certo istante
t
1> t
0 è terminata la seguente sequenza di eventi:• Q esegue una “exec” e passa a eseguire il programma Y
• P esegue un accesso a COND
• Q richiede una nuova pagina di pila
• Q esegue un accesso a COND
Completare le tabelle con la situazione al tempo
t
1.situazione al tempo
t
1memoria fisica MMU
indirizzo
fisico pagine allocate proc NPV NPF valid
bit
0 CP1 = (CQ1) P CP1 / 1 0 1
1 (DP0) = (DQ0) COND P (DP0 / 2) COND / 5 (1) 1 1 / 0 / 1
2 (PP0) P PP0 / F 2 1
3 (PQ0) CQ2 Q (CQ1 / 1) CQ2 / 2 (0) 3 1 / 0 / 1 4 (COND) (DQ0) (DQ0)
PQ1 Q (DQ0 / 2) (COND / 5)
(DQ0 / 2) (DQ0 / 3) PQ1 / E
(1) (4) (4) (4) 4
1 / 0 / 1 / 0 / 1 / 0 / 1 / 0 / 1 5 (PQ0) Q (PQ0 / F) (PQ0 / F)
COND / 6 (3) (5) 1 1 / 0 / 1 / 0 / 1 6
AXO – prova di venerdì 19 novembre 2010 – CON SOLUZIONI pagina 12 di 16
Esercizio n. 4 – file system
Si consideri un calcolatore dotato di sistema operativo Linux e in cui valgono le seguenti specifiche:
1. per tutte le operazioni su file:
a) la dimensione di un blocco trasferito in DMA da o su file è di 512 byte b) l'interruzione di fine DMA è associata al trasferimento di un singolo blocco
c) il sistema deve garantire che, per tutti i file aperti, il blocco contenente la posizione cor- rente sia in memoria
d) l’area “buffer” in memoria centrale ha dimensioni elevate e tutti i blocchi letti e/o scritti rimangono a disposizione nella memoria stessa
2. per l'apertura del file:
e) è sempre necessario accedere a:
− 1 blocco per l'accesso allo I-node di ogni cartella (catalogo) o file presente nel nome-percorso (pathname) tranne che per la cartella radice, e
− 1 blocco per il contenuto di ogni cartella (catalogo) presente nel nome-percorso (pathname)
− i blocchi possono trovarsi in memoria (se già acceduti) o necessitare di trasferimento DMA da disco
Su tale calcolatore viene eseguito il seguente programma, che parte come processo P, crea il processo Q che a sua volta crea il processo R (i commenti identificano le chiamate di sistema nel seguente modo:
/* Sn */, con 1 ≤ n ≤ 15 ):
NOTA: si ricorda che in lseek (fd, offset, riferimento)
riferimento=0 indica inizio file, riferimento=1 indica posizione corrente attuale, riferimento=2 indica fine file
int main ( ) { /* processo
P
*/...
fd1 = open (“/acso/esame/esercizio1”, O_RDWR); /* 1 */
lseek (fd1, 1020, 0); /* 2 */
read (fd1, buf1, 10); /* 3 */
write (fd1, buf2, 600); /* 4 */
pid1 = fork ( ); /* 5 */
if (pid1 == 0) { /* processo
Q
*/fd2 = open (“/acso/esame/esercizio2”, O_RDONLY); /* 6 */
lseek (fd2, 1024, 1); /* 7 */
pid2 = fork ( ); /* 8 */
if (pid2 == 0) { /* processo
R
*/fd3 = open (“/acso/esame/esercizio3”, O_RDWR); /* 9 */
write (fd3, buf3, 727); /* 10 */
close (fd2); /* 11 */
exit (0); /* 12 */
} else { /* processo
Q
*/exit (0); /* 13 */
} /* if */
} else { /* processo
P
*/close (fd1); /* 14 */
} /* if */
exit (0); /* 15 */
} /* main */
Al momento dell'esecuzione, il contenuto del volume è il seguente:
I-Lista: < 0, dir, 4 > < 6, dir, 20 > < 7, dir, 31 > < 98, norm, { 800, 801, 802, 803, 804, … } >
< 110, norm, { 1718, 1719, … } > < 232, norm, { 2733, 2734, … } >
Blocco 4: … < 6, acso > … Blocco 20: … < 7, esame > …
Blocco 31: … < 98, esercizio1 > < 110, esercizio2 > < 232, esercizio3 > …
Nota: lo i-node di root è sempre in memoria e il contenuto dei blocchi dei file normali viene omesso perché non significativo ai fini dell'esercizio.
a) Per ciascuna della chiamate di sistema del processo P sotto riportate, si indichi il numero totale di interru- zioni di fine DMA che si verificano affinché l'operazione possa essere completata, la sequenza di accessi agli i-node e ai blocchi (del tipo: I-Lista [X] oppure Blocco Y) in memoria principale (M) o su disco (D).
chiamata di sistema n. di interruzioni
di fine DMA sequenza di accessi in memoria (M) o su disco (D)
fd1 = open (“/acso/esame/esercizio1”, O_RDWR) (si completi la soluzione parziale a lato)
− 1 1 1 1 1 1 1 (totale 7)
I-lista [0] in M blocco 4 su D I-lista [6] su D blocco 20 su D I-lista [7] su D blocco 31 su D I-lista [98] su D blocco 800 su D
lseek ( fd1, 1020, 0 )
− (totale 1) 1
I-lista [98] in M blocco 801 su D
read ( fd1, buf1, 10 )
− − (totale 1) 1
I-lista [98] in M blocco 801 in M blocco 802 su D
write ( fd1, buf2, 600 )
− − 1 (totale 1)
I-lista [98] in M blocco 802 in M blocco 803 su D
b) Durante l'esecuzione è stata osservata la seguente sequenza di chiamate di sistema:
1 2 3 4 5 6 7 8 14 13 9 10 11 12 15 Si completi il contenuto delle tabelle seguenti, indicando la sequenza dei valori assunti fino alla conclu- sione di 15 (si scriva L oppure NE per indicare che una cella si è liberata o non esiste più):
tab file aperti
del proc P tab file aperti
del proc Q tab file aperti
del proc R tabella globale dei file aperti file
des rif riga file
des rif riga file
des rif riga riga posizione
corrente n di processi i-nodo
0 X 0 X 0 X 0 X X X
1 X 1 X 1 X 1 X X X
2 X 2 X 2 X 2 X X X
3 3, L, NE 3 3, NE 3 3, NE 3 0, 1020, 1030, 1630, L 1, 2, 3, 2, 1, L 98, L
AXO – prova di venerdì 19 novembre 2010 – CON SOLUZIONI pagina 14 di 16
Esercizio n. 5 – device driver
Un processo stampa (per esempio tramite write o printf) 4300 (quattromilatrecento) caratteri.
Il driver della stampante possiede un buffer che può contenere al massimo 500 (cinquecento) caratteri. La stampante non è dotata di DMA e buffer propri, e deve pertanto ricevere dal processore un carattere alla volta. La velocità della stampante è di 100 (cento) caratteri al secondo.
Il driver risveglia il processo non appena nel buffer non ci sono più dati da stampare. Si supponga che il tem- po T_PRONTO intercorrente tra il momento in cui un processo diventa pronto a seguito di una Wake_up e il momento in cui viene posto in esecuzione, sia noto e costante nella situazione di carico considerata (sebbe- ne in realtà si tratterebbe di una variabile statistica).
domanda a)
Si chiede di calcolare il tempo totale T_STAMPA che intercorre tra il momento in cui il processo invoca il ser- vizio di stampa e il momento in cui il processo riprende l’esecuzione dopo che la stampa dei 4300 caratteri è terminata, e di calcolare il numero di Wake_up eseguite dal processo nello stesso periodo, nelle situazioni elencate in Tabella e indicando i passaggi fondamentali di tale calcolo.
Nel calcolo di T_STAMPA si tenga conto che tale tempo è dovuto sia al tempo impiegato dalla stampante per eseguire fisicamente la stampa, sia alle eventuali attese della stampante dovute all’indisponibilità momenta- nea di dati da stampare, ma si trascurino tutti i tempi di esecuzione delle routine di interrupt e dei servizi del sistema operativo invocati per la stampa (in quanto brevissimi – alcuni millisecondi – rispetto ai tempi in gio- co per la stampa).
Situazioni da analizzare:
T_PRONTO T_STAMPA n. WAKE_UP SPIEGAZIONI
(formula di calcolo di T_STAMPA)
2 s 61 s 9
il numero di iterazioni e dunque di Wake_up è 4300 char / 500 char arrotondato all’intero superiore, ossia 9 iterazioni
la velocità di stampa è data: 100 char s−1
il tempo di lavoro della stampante è dunque 4300 char / (100 char s−1) = 43 s
9 iterazioni × 2 s = 18 s per l’attesa tempo totale = 43 s + 18 s = 61 s
domanda b)
Si consideri ora un driver OTTIMIZZATO che risveglia il processo non appena nel buffer ci sono ancora 100 (cento) caratteri da stampare, in modo da ridurre il tempo in cui la stampante rimane ferma ad attendere un nuovo riempimento del buffer (il driver gestisce quindi il corretto uso del buffer, che è complicato, ma tali complicazioni non influenzano il problema).
In questo caso il numero di caratteri che viene trasferito nel buffer a ogni risveglio può essere inferiore a 500, perché dipende dal numero di caratteri residui da stampare che occupano ancora il buffer nel momento in cui il processo viene posto in esecuzione.
Attenzione: il risveglio anticipato non avviene quando il buffer è stato riempito per l’ultima vol- ta, perché il progettista ha deciso di attendere l’interrupt che segnala lo svuotamento completo del buffer prima di risvegliare e rimettere in esecuzione in modo U il processo.
T_PRONTO T_STAMPA n. WAKE_UP SPIEGAZIONE
(formula di calcolo di T_STAMPA)
2 s 53 s 9
per 8 iterazioni una parte del tempo di attesa si svolge in sovrapposizione con la stampa degli ultimi 100 caratteri, che impiega un secondo, ma all’ultima iterazione tale sovrapposizione non avviene, pertanto
43 s per la stampa
8 iterazioni × (2 s – 1 s) + 2 s = 10 s per l’attesa tempo totale = 43 s + 10 s = 53 s
1 s 44 s 9
per 8 iterazioni tutto il tempo di attesa si svolge in sovrapposizione con la stampa degli ultimi 100 caratteri, che impiega un secondo, ma all’ultima iterazione tale sovrapposizione non avviene, pertanto
43 s per la stampa
8 iterazioni × (1 s – 1 s) + 1 s = 1 s per l’attesa tempo totale = 43 s + 1 s = 44 s
0,5 s 43,5 s 10
i caratteri trasferiti a ogni ripresa di esecuzione sono solo 450, perciò il numero di iterazioni e dunque di Wake_up diventa 10
per 9 iterazioni tutto il tempo di attesa si svolge in sovrapposizione con la stampa degli ultimi 100 caratteri, che impiega un secondo, ma all’ultima iterazione tale sovrapposizione non avviene, pertanto
43 s per la stampa
9 iterazioni × (1 s – 1 s) + 0,5 s = 0,5 s per l’attesa
AXO – prova di venerdì 19 novembre 2010 – CON SOLUZIONI pagina 16 di 16
spazio libero per minuta