SISTEMI OPERATIVI SOFTWARE DI BASE Il software di base comprende tutti quei programmi indispensabili ai fini del funzionamento dell’elaboratore, per questo viene detto di base. I S.O. rientrano nella categoria del software di base. SOFTWARE APPLICATIVO Il software applicativo comprende tutti quei programmi che servono a risolvere all’utente uno specifico problema. Esempi di software applicativo sono i programmi: word, excel, powerpoint, internet explorer, videogiochi, ecc. SISTEMA OPERATIVO Il S.O. è un insieme di programmi che coordinano il funzionamento delle componenti HARDWARE e SOFTWARE del computer e ne consentono l’utilizzo da parte dell’utente. In pratica un S.O. deve: • Permettere all’utente di usare tutte le risorse del sistema in modo semplice e immediato • Ottimizzare l’uso delle risorse adottando le più adeguate politiche di gestione RISORSA Per risorsa si intende un generico elemento del computer sia esso hardware (CPU, Memoria centrale, Dispositivi) che software (Programmi, Dati). Come è possibile vedere dall’immagine sotto, il S.O. fa da interfaccia tra l’hardware ed il software applicativo che l’utente sceglie di eseguire. E’ il S.O. in funzione sul computer che consente all’utente di poter avviare i programmi applicativi desiderati. Appunti sui Sistemi Operativi del Prof. Giammona - Aggiornati al 16 maggio 2014 Pagina 1 di 26 L’interfaccia che il S.O. presenta all’utente può essere di due tipi: 1. Testuale, detta a linea di comando (CLI - Command Line Interface) 2. Grafica, chiamata anche GUI (Graphic User Interface) Le interfacce di tipo CLI, come quella mostrata nella figura sotto, prevedono che l’utente debba conoscere lo specifico comando con la rispettiva sintassi da digitare al fine di far svolgere al S.O. una determinata operazione (es: creazione di una cartella, copia di un file, ecc.). Le interfacce di tipo GUI, come quelle mostrate nelle figure sotto, fanno uso di piccole immagini grafiche dette icone, per ricordare all’utente quale applicazione può avviare tramite l’icona. Vengono usati i menù per ricordare tutte le opzioni ed i comandi a disposizione dell’utente, oltre che finestre per l’esecuzione di applicazioni. Questo tipo di interfaccia è molto più semplice da utilizzare per un utente inesperto, infatti, viene detta user friendly. Appunti sui Sistemi Operativi del Prof. Giammona - Aggiornati al 16 maggio 2014 Pagina 2 di 26 Sistema operativo Windows Sistema operativo Linux Il S.O. più l’hardware del computer creano una macchina virtuale per l’utente che lo utilizza, il quale si astrae completamente dalle caratteristiche e dal funzionamento dei componenti vedendo solo quello che il S.O. gli mette a disposizione. Appunti sui Sistemi Operativi del Prof. Giammona - Aggiornati al 16 maggio 2014 Pagina 3 di 26 PROCESSO Per processo si intende un programma in esecuzione da parte della CPU, infatti, non è corretto dire che un processo è in esecuzione ma piuttosto che è nello stato di avanzamento. Il modello a buccia di cipolla (figura sopra) è un modello a strati che mostra in dettaglio i moduli (programmi fondamentali) che compongono il S.O., cioè: 1. Nucleo o Kernel o Gestore dei processi che contiene le procedure di gestione della CPU e i programmi di gestione delle interruzioni. E’ lo strato più vicino all’hardware e quindi dipende strettamente da esso. Il nucleo si occupa di: a. Creare e cancellare i processi b. Mantenere aggiornato lo stato dei processi e del processore c. Allocare la risorsa processore in base a una specifica politica di gestione d. Rilasciare il processore e. Gestire la sincronizzazione tra i vari processi f. Gestire le interruzioni 2. Gestore della memoria centrale che contiene le routine per gestire l’organizzazione della memoria e per accedere agli indirizzi delle singole celle di memoria. Esso si occupa di: a. Tenere traccia di quali parti della memoria sono libere e quali sono occupate b. Decidere quanta memoria allocare ad un processo in base a una specifica politica di gestione c. Allocare e liberare lo spazio di memoria dedicato ad un processo e memorizzarne le informazioni 3. Gestore delle periferiche o dell’I/O che contiene i programmi di gestione dei singoli dispositivi e si occupa di gestire l’assegnazione dei dispositivi ai vari processi che ne fanno richiesta secondo una politica di gestione. Esso si occupa di: a. Tenere aggiornato lo stato delle periferiche b. Decidere l’allocazione delle periferiche in base a una specifica politica di gestione c. Allocare la risorsa e iniziare l’operazione di I/O Appunti sui Sistemi Operativi del Prof. Giammona - Aggiornati al 16 maggio 2014 Pagina 4 di 26 d. Rilasciare la risorsa 4. Gestore delle informazioni o File System che si occupa della gestione dei file ed in particolare di controllare ed organizzare come avviene la memorizzazione delle informazioni sulle memorie di massa (hard disk, floppy disk, schede di memoria, ecc.). Esso si occupa nello specifico di: a. Conoscere lo stato delle memorie di massa, il loro uso e il modo di accesso b. Decidere che può utilizzare le informazioni in base a una specifica politica di gestione c. Assegnare la risorsa al processo d. Rilasciare la risorsa e. Creare e cancellare file e cartelle f. Permettere la copia dei file L’organizzazione a strati dei moduli del S.O. è basata sul fatto che un determinato modulo sfrutta i servizi offerti dal modulo sottostante senza conoscere quello che c’è al di sotto (astrazione) e offre delle funzionalità al livello sovrastante, creando così una macchina virtuale per il livello superiore. Da questo punto di vista gli strati del S.O. hanno una struttura di tipo gerarchico. Di tutto il S.O. l’unico modulo che deve sempre essere presente in memoria centrale è il nucleo, mentre gli altri risiedono in Ram solo quando debbono essere eseguiti, altrimenti normalmente sono presenti su memoria di massa. Indici delle prestazioni di un Sistema Operativo Il S.O. al pari degli altri software deve anch’esso essere eseguito dalla CPU, questo significa che la sua esecuzione ruba del tempo all’esecuzione dei programmi lanciati dall’utente, quindi, possiamo dire che un S.O. è tanto più efficiente quanti più programmai riesce ad eseguire nel minor tempo possibile a parità di configurazione hardware. Possiamo individuare alcuni indici di prestazioni di un S.O.: 1. Tempo di Attività della CPU, espresso in percentuale e dato dal rapporto tra il tempo di lavoro della CPU ed il tempo di lavoro dell’intero sistema, cioè %CPU = Tcpu / Ttotale (dove Ttotale = Tcpu + tempo I/O) Appunti sui Sistemi Operativi del Prof. Giammona - Aggiornati al 16 maggio 2014 Pagina 5 di 26 2. Throughput, che indica il numero di programmi eseguiti nell’unità di tempo, cioè: Throughput = N / Ttotale 3. Tempo S.O. su tempo totale, che indica il rapporto tra il tempo che la CPU dedica all’esecuzione del S.O. ed il tempo totale di esecuzione da parte della CPU, cioè: Tso su Ttot = Tcpu S.O. / Tcpu Totale 4. Turnaround Time, che indica il tempo trascorso tra l’istante iniziale e quello finale di esecuzione di un programma, cioè: TT = tempo finale – tempo iniziale Considerando il Turnaround Time di n lavori è possibile calcolare il tempo medio di esecuzione degli n lavori con la seguente formula: = ∑ dove ATT sta per Average Turnaround Time e TTi sta per il tempo di esecuzione dell’iesimo lavoro. Classificazione dei Sistemi Operativi (in base alle modalità di input) 1. Elaborazione a lotti (batch): è una modalità di funzionamento del S.O. che prevede che i dati da elaborare vengono accumulati su una memoria ausiliaria prima dell’elaborazione, che avviene in tempi prefissati, e che al termine fornisce i risultati. Durante l’esecuzione del programma non è possibile fornire dati in input, quindi non esiste interattività tra l’utente ed il processo in corso. I S.O. batch sono molto semplici, dato che non prevedono alcuna interfaccia utente e non debbono gestire più programmi presenti in memoria contemporaneamente. Appunti sui Sistemi Operativi del Prof. Giammona - Aggiornati al 16 maggio 2014 Pagina 6 di 26 2. Elaborazione interattiva: è una modalità di funzionamento del S.O. che prevede la possibilità per l’utente di interagire con il programma in esecuzione, fornendo dati in input durante l’elaborazione. L’interazione tra ciascun utente e l’elaboratore centrale avviene mediante il videoterminale, che consente l’invio di dati e comandi tramite tastiera all’elaboratore centrale e la visualizzazione dei risultati ricevuti da quest’ultimo sullo schermo. Classificazione dei Sistemi Operativi (in base alle modalità di gestione della CPU) 1. Sistema Operativo monoprogrammato: è un S.O. in grado di gestire l’esecuzione di un programma utente alla volta, il che lo rende un software non molto complesso. Solo al termine dell’esecuzione di un programma, l’utente potrà lanciarne un altro. Un classico esempio di S.O. monoprogrammato è l’MS-DOS (MicroSoft-Disk Operating System), divenuto oramai obsoleto. In figura sotto è possibile vedere il contenuto della memoria nel caso di utilizzo di un S.O. monoprogrammato. memoria RAM Sistema Operativo Programma utente 2. Sistema Operativo multiprogrammato: è un S.O. in grado di caricare in memoria più programmi utente contemporaneamente e di ripartire fra questi l’uso delle risorse. Questi S.O. migliorano nettamente le prestazioni del sistema sfruttando i tempi morti della CPU dovuti alle operazioni di Input/Output, cioè in pratica quando un programma in esecuzione ha la necessità di svolgere una operazione di I/O, la CPU anziché restare senza far nulla in attesa del termine di questa operazione, viene assegnata ad un altro programma che deve essere eseguito, qualora quest’ultimo dovesse effettuare anch’esso una operazione di I/O, l’utilizzo della CPU ritornerebbe al programma che precedentemente era stato sospeso. Con una politica di Appunti sui Sistemi Operativi del Prof. Giammona - Aggiornati al 16 maggio 2014 Pagina 7 di 26 gestione di questo tipo si cerca di tenere il più possibile la CPU al lavoro (tempo di attività %CPU molto elevato). La sensazione dell’utente è che il sistema stia eseguendo più programmi contemporaneamente, mentre in realtà è grazie alla velocità di esecuzione della CPU che passa da un programma all’altro, quindi in un dato istante è in esecuzione un solo programma. In figura sotto è possibile vedere il contenuto della memoria nel caso di utilizzo di un S.O. multiprogrammato. memoria RAM Sistema Operativo Programma utente 1 Programma utente 2 Programma utente 3 Nell’immagine sotto è possibile vedere un grafico che illustra l’utilizzo della CPU rispetto al tempo in un S.O. monoprogrammato. Appunti sui Sistemi Operativi del Prof. Giammona - Aggiornati al 16 maggio 2014 Pagina 8 di 26 Nell’immagine sotto è possibile vedere un grafico che illustra l’utilizzo della CPU rispetto al tempo in un S.O. multiprogrammato. I vantaggi dei S.O. multiprogrammati sono: • Esecuzione di più programmi contemporanemante; • Migliore gestione delle risorse; Gli svantaggi sono: • Maggiore complessita del S.O.; • Uso di algoritmi specifici per la gestione delle risorse: CPU, memoria e dipositivi di I/O; In un S.O. multiprogrammato, quando un programma in esecuzione richiede di svolgere una operazione di I/O, la CPU viene liberata dal compito di gestione di tale operazione grazie all’utilizzo degli Elaboratori di Canale, i quali si preoccupano di gestire l’intero processo di I/O svincolando la CPU e consentendole quindi di dedicarsi all’esecuzione di altri programmi. 3. Sistema Operativo time-sharing I S.O. multiprogrammati così come descritti sopra presentano un grosso problema, cioè nel caso in cui un programma è in possesso della CPU e non necessita mai di fare operazioni di I/O continua a mantenerne il possesso in modo esclusivo, non consentendo agli altri programmi presenti in memoria di poter avanzare nell’esecuzione. Per ovviare a questo problema sono stati introdotti i S.O. multi Appunti sui Sistemi Operativi del Prof. Giammona - Aggiornati al 16 maggio 2014 Pagina 9 di 26 programmati in Time-Sharing, cioè a condivisione di tempo, in pratica il S.O. assegna la CPU a ciascun programma per un quanto di tempo predefinito chiamato time slice terminato il quale il S.O. toglie la CPU al programma che ha terminato il suo quanto di tempo e la assegna al prossimo che ne ha diritto. Con un meccanismo di gestione della CPU di questo tipo si ha l’impressione che tutti i programmi lanciati si eseguono contemporaneamente. Windows è un S.O. time-sharing monoutente, mentre Linux è un S.O. time-sharing multiutente. 4. Sistema Operativo distribuito I S.O. distribuiti consentono di utilizzare più CPU connesse tra di loro come se si trattasse di un unico sistema di elaborazione, al quale ci si può connettere da qualsiasi punto. Ogni CPU aumenta le capacità di calcolo del sistema e può accadere che un programma sia in esecuzione su più processori contemporaneamente. 5. Sistema Operativo realtime I S.O. realtime sono utilizzati specificamente in applicazioni industriali e nel controllo di processo, ovvero in tutte quelle situazioni in cui è necessaria una rapidissima valutazione degli input ed una relativa risposta in uscita in modo tale da controllare in tempo reale l’avanzamento di un processo automatizzato dal computer. 6. Sistema Operativo dedicato o transazionale Sono S.O. utilizzati per specifiche applicazioni e quindi diversi dai classici S.O. che permettono l’utilizzo dell’elaboratore per qualsiasi necessità dell’utente mediante l’uso del programma specifico. Il Nucleo di un Sistema Operativo Il Nucleo del S.O. si occupa principalmente di: 1. Mantenere aggiornato lo stato del processore (libero/occupato) 2. Decidere a quale processo assegnare il processore secondo una specifica politica di gestione 3. Assegnare il processore al processo scelto 4. Riprendere il controllo del processore quando il processo è terminato o sospeso oppure è terminato il quanto di tempo di CPU spettante Il Nucleo di un S.O. si compone dei seguenti programmi: Appunti sui Sistemi Operativi del Prof. Giammona - Aggiornati al 16 maggio 2014 Pagina 10 di 26 1. 2. 3. 4. 5. Lo schedulatore dei lavori (Scheduler a lungo termine) Lo schedulatore dei processi (Scheduler a breve termine) Il controllore del traffico (Dispatcher) Il gestore delle interruzioni Le procedure di sincronizzazione e comunicazione tra processi In ogni istante un programma che deve essere eseguito dal sistema, può trovarsi in uno degli stati descritti dal seguente diagramma, che indica in quello specifico momento a che punto dell’intero processo di esecuzione si trova il programma. A ciascuno stato corrisponde una specifica situazione in cui si può trovare un processo ed in particolare: • HOLD: indica che l’utente ha chiesto al sistema l’esecuzione di un programma presente su memoria di massa (ad esempio con un doppio click sull’icona nel caso di windows); • READY: indica che il S.O. ha caricato in memoria RAM il programma che deve essere eseguito, quindi è pronto per l’esecuzione; • RUN: indica che il processo è in esecuzione da parte della CPU, è chiaro che in un sistema dotato di un solo processore, un solo processo potrà trovarsi in questo stato in un determinato momento; • WAIT: indica che il processo è in attesa del completamento di una operazione di Input/Output; Appunti sui Sistemi Operativi del Prof. Giammona - Aggiornati al 16 maggio 2014 Pagina 11 di 26 • END: indica che il processo di esecuzione è terminato. Esaminiamo ora in corrispondenza di quali eventi avvengono le transizioni tra gli stati del diagramma: • Transizione 1: avviene quando lo schedulatore dei lavori (scheduler a medio termine) decide di caricare in memoria RAM un programma scelto tra quelli che si trovano nella lista dei processi in stato di Hold, in questo caso viene rimosso il JCB dalla lista di Hold e viene creato un PCB del processo e aggiunto in coda alla lista di Ready; • Transizione 2: avviene quando lo schedulatore dei processi (scheduler a breve termine) decide di assegnare la CPU al processo scelto fra quelli presenti nella lista di Ready, in questo caso viene rimosso il PCB dalla lista di Ready e viene aggiunto alla lista di Run; • Transizione 3: avviene quando un processo in esecuzione (stato RUN) chiede di svolgere una operazione di Input/Output, in questo caso viene rimosso il PCB dalla lista di Run e viene aggiunto in coda alla lista di Wait; • Transizione 4: avviene quando un processo in esecuzione (stato RUN) termina il quanto di tempo di CPU assegnatogli (time slice) e quindi torna nello stato di Ready, in questo caso viene rimosso il PCB dalla lista di Run e viene aggiunto in coda alla lista dei processi nello stato di Ready; • Transizione 5: avviene quando un processo in attesa (stato WAIT) termina di svolgere una operazione di Input/Output e quindi diventa pronto per continuare l’esecuzione, in questo caso viene rimosso il PCB dalla lista di Wait e viene aggiunto in coda alla lista dei processi nello stato di Ready; • Transizione 6: avviene quando un processo in fase di avanzamento (stato RUN) termina l’esecuzione. Sia il JCB che il PCB sono strutture dati (tipicamente dei Record) che contengono informazioni specifiche sul programma/processo ed in particolare: 1. Il JCB (Job Control Block) contiene le seguenti informazioni: a. L’identificativo del programma b. La dimensione in Kbyte c. L’indirizzo di caricamenti da memoria di massa d. Gli identificatori delle periferiche e. Il puntatore al JCB successivo Appunti sui Sistemi Operativi del Prof. Giammona - Aggiornati al 16 maggio 2014 Pagina 12 di 26 2. Il PCB (Process Control Block) contiene le seguenti informazioni: a. L’identificatore del processo (PID) b. L’identificatore del padre, il puntatore al suo PCB c. Il puntatore alla lista dei figli d. Lo stato in cui si trova: RUN, READY, WAIT, ecc. e. Il registro di salvataggio f. L’indirizzo di caricamento in memoria centrale g. Gli identificatori delle periferiche h. I file aperti La figura sotto riporta una ipotetica situazione delle liste dei processi in stato di HOLD e di READY, evidenziando cosa accade quando un processo transita da uno stato all’altro: Guardando la figura sopra è possibile notare che, in corrispondenza della transizione 1: da stato di HOLD a stato di READY, il JCB del programma viene eliminato dalla lista HOLD ed il PCB del processo corrispondente viene aggiunto in coda alla lista READY. Appunti sui Sistemi Operativi del Prof. Giammona - Aggiornati al 16 maggio 2014 Pagina 13 di 26 Algoritmi di scheduling Lo schedulatore a lungo termine (Job Scheduler) nello scegliere quale programma, tra quelli presenti nella coda di HOLD, caricare in RAM e quindi far diventare processo (con relativo inserimento nella coda di READY), può adottare uno dei seguenti algoritmi: 1. FIFO (First In First Out): I lavori vengono prelevati dalla lista di HOLD secondo l’ordine di arrivo e vengono inseriti nella coda di READY, si tratta di una politica semplice ma che non ottimizza al meglio la gestione delle risorse; 2. Priorità statica: ad ogni lavoro presente nella lista di HOLD viene assegnato un livello di priorità in base all’importanza della sua esecuzione, in questo modo il job scheduler sceglierà di caricare in memoria il programma con il livello di priorità più elevato presente nel JCB, nel caso di uguale priorità si adotta il metodo FIFO; 3. Priorità dinamica: per evitare di privilegiare sempre gli stessi programmi dotati di priorità più elevata, il S.O. aumenta il valore della priorità dei programmi in funzione del tempo di permanenza nella lista di HOLD. Per attuare questa politica, bisogna memorizzare nel JCB il tempo di inserimento in coda del programma. Lo schedulatore a breve termine (Process Scheduler) nello scegliere a quale processo assegnare la CPU tra quelli presenti nella coda di READY deve rispettare dei criteri generali quali: imparzialità, efficienza, risposta in tempo reale, turnaround time minimizzato, throughput massimizzato e fairness. Gli algoritmi che può adottare lo Job Scheduler possono essere: non preemptive e preemptive in dipendenza del fatto di lasciare la CPU assegnata ad un processo fin quando termina o chiede di svolgere una operazione di I/O oppure di toglierla anche durante la sua esecuzione. Algoritmi di scheduling non preemptive: 1. FCFS (First Come First Served): la CPU viene assegnata al primo processo presente nella coda di READY e così via. Tale politica ha un tempo medio di attesa abbastanza lungo e non privilegia i processi brevi; 2. SJF (Shortest Job First): la CPU viene assegnata al processo che ha il più breve tempo di utilizzo della CPU prima di una operazione di I/O. Il problema di questa politica è che dei tempi di esecuzione è possibile fare solo una stima. Appunti sui Sistemi Operativi del Prof. Giammona - Aggiornati al 16 maggio 2014 Pagina 14 di 26 3. Scheduling con priorità: in questo caso viene associata una priorità ad ogni processo presente nella coda di READY, il processo scelto per l’assegnazione della CPU è quello con priorità più elevata. La priorità può essere calcolata tenendo conto sia del tempo di esecuzione che di quello di permanenza all’interno della coda di READY, quindi: à = + in questo modo si privilegiano i processi brevi e quelli che attendono da più tempo. Algoritmi di scheduling preemptive: 1. Round Robin: la CPU viene assegnata a turno per un quanto di tempo (time slice) a ciascuno dei processi della coda di READY secondo l’ordine di arrivo, quindi con una gestione di tipo FIFO. Qualunque processo che si trova a transitare da uno stato a quello di READY verrà inserito in coda. 2. Round Robin a percentuale di tempo: il round robin tradizionale rischia di penalizzare fortemente i processi che fanno spesso operazioni di I/O, dato che al termine questi vengono inseriti in coda alla lista dei processi READY, indipendentemente dal fatto di aver sfruttato in tutto o in parte il loro time slice prima dell’inizio dell’I/O. Il RR a percentuale di tempo, invece, tiene conto del tempo di time slice sfruttato dal processo prima dell’operazione di I/O, facendolo rientrare nella coda di READY in una posizione tanto più avanzata quanto più bassa è stata la percentuale di time slice consumata precedentemente. 3. Round Robin limitato: fissato un certo numero N di time slice, si utilizza l’algoritmo di RR tradizionale fino a quando un processo non consuma i suoi N time slice, dopodiché viene inserito in un’altra coda che verrà presa in considerazione solamente quanto tutti i processi avranno usufruito dei loro N time slice. 4. Priorità statica: ad ogni processo viene attribuita una priorità, per esempio in base al tempo di esecuzione stimato, lo scheduler terrà conto di questo valore per inserire i processi in coda. Appunti sui Sistemi Operativi del Prof. Giammona - Aggiornati al 16 maggio 2014 Pagina 15 di 26 5. Priorità dinamica: il S.O. modifica la priorità sulla base del tempo di utilizzo della CPU, per esempio in base al fatto che il processo ha sfruttato o meno interamente il suo time slice. L’assegnazione della CPU a un nuovo processo comporta il salvataggio del PCB del vecchio processo, la scelta del processo a cui assegnare la CPU ed il caricamento del suo PCB. Il tempo impiegato per il cambio di contesto è chiamato overhead di sistema e deve essere minimizzato. Gli Interrupt L’interrupt è il meccanismo mediante il quale vengono comunicati alla CPU alcuni eventi ben precisi, ad esempio lo scadere di un time slice, un errore in un programma, ecc. Un interrupt hardware è un segnale che viene inviato da un dispositivo di I/O alla CPU. Un interrupt software è invocato da un processo attraverso specifiche istruzioni per richiedere al S.O. di svolgere una operazione di I/O. La CPU fin dall’accensione svolge il ciclo istruzione, che le consente di eseguire una istruzione di un programma, ma che ripetuto ciclicamente consente di eseguire interi programmi. Il ciclo istruzione si compone delle seguenti fasi: 1. ripeti 2. se non c’è stato un interrupt allora 3. fetch (preleva l’istruzione dalla memoria) 3. decode (decodifica l’istruzione caricata) 4. execute (esegue l’istruzione) 5. altrimenti 6. eseguire routine di interrupt 7. finché non viene spento il sistema La commutazione dell’esecuzione dal programma corrente alla routine di servizio dell’interruzione comporta le seguenti operazioni: • Salvataggio dello stato del programma corrente nel suo PCB in memoria RAM; • Esecuzione della routine di servizio dell’interrupt; Appunti sui Sistemi Operativi del Prof. Giammona - Aggiornati al 16 maggio 2014 Pagina 16 di 26 • Ripristino delle informazioni sullo stato del programma precedentemente interrotto, prelevate dal PCB presente in memoria RAM; I principali tipi di interruzioni sono: 1. Hardware interrupt: causata da malfunzionamento o guasto hardware; 2. Supervisor call interrupt: chiamata da un modulo supervisore per una richiesta di I/O; 3. Program interrupt: istruzione non valida, overflow, violazione delle aree di memoria protette; 4. External interrupt: causata dalla fine del time slice o dalla pressione dei tasti CTRL+C; 5. I/O interrupt: in caso di comando di I/O errato, canale o dispositivo non correttamente connesso. Interrupt multipli Può accadere che mentre la CPU sta eseguendo una routine di servizio dell’interruzione arrivi un’altra richiesta di interruzione, la scelta se continuare l’esecuzione della routine in corso oppure sospenderla e dedicarsi all’esecuzione della routine di servizio della nuova interruzione giunta può essere fatta basandosi su un meccanismo a priorità, in questo modo solo se la nuova richiesta di interruzione ha una priorità più elevata di quella in corso, quella attuale verrà sospesa e la gestione passerà a quella nuova, altrimenti la nuova richiesta di interrupt verrà gestita solo al termine di quella corrente. E’ anche possibile effettuare il mascheramento di un interrupt, andando a resettare o a settare il bit corrispondente del registro delle interruzioni. Per quanto riguarda la tecnica che permette di sapere in caso di più richieste in contemporanea quale dispositivo ha fatto richiesta, è possibile adottarne una fra le seguenti: 1. Interruzioni vettorizzate: in questo caso la periferica che ha generato l’interrupt genera anche un codice che consente alla CPU di identificare direttamente il dispositivo e attivare la corrispondente routine di servizio dell’interruzione; 2. Ciclo di polling: i dispositivi che hanno generato un interrupt settano un opportuno flag, che esaminato dalla CPU tramite una interrogazione ciclica di Appunti sui Sistemi Operativi del Prof. Giammona - Aggiornati al 16 maggio 2014 Pagina 17 di 26 tutti i flag delle periferiche, consente di capire chi ha fatto richiesta e quindi di attivare la corrispondente routine di servizio dell’interruzione. Il Gestore della Memoria centrale di un Sistema Operativo Un programma per poter essere eseguito dalla CPU deve prima essere caricato in memoria RAM. Lo spazio di memoria occupato da un programma è composto dalla zona dati (variabili del programma) e dalla zona istruzioni (i codici macchina eseguibili) che insieme formano il cosiddetto spazio degli indirizzi del programma. Può accadere che un programma durante la sua esecuzione venga più volte caricato in RAM dalla memoria di massa (swap in) e viceversa (swap out), il che comporta che ad ogni caricamento andrà ad occupare indirizzi di memoria differenti. Possiamo distinguere i seguenti tipi di indirizzi: 1. Indirizzo simbolico: l’utilizzo del nome di una variabile nel caso di assegnazione di un valore, sia in linguaggio ad alto livello che in linguaggio assembly è un esempio di indirizzo simbolico; 2. Indirizzo logico: si tratta di un indirizzo numerico ma che non corrisponde all’indirizzo fisico della locazione di memoria cui effettivamente farà riferimento il programma durante la sua esecuzione; 3. Indirizzo virtuale: si tratta ancora di riferimenti logici che dovranno essere trasformati nei reali indirizzi fisici nel momento in cui il programma verrà caricato in RAM; 4. Indirizzo fisico: sono i reali indirizzi di memoria RAM. La trasformazione degli indirizzi logico-virtuali in indirizzi fisici durante l’esecuzione del programma, viene svolta da un circuito hardware dedicato presente internamente alla CPU chiamato MMU (Memory Management Unit). La rilocazione consiste nell’andare, all’atto del caricamento in Ram del programma da eseguire, a trasformare gli indirizzi logici in indirizzi fisici. La rilocazione può essere di tipo: 1. Statica: se all’atto del caricamento in RAM del programma tutti gli indirizzi logici vengono trasformati in fisici. Questa operazione richiede un tempo di preparazione iniziale del programma elevato e ne vincola il funzionamento Appunti sui Sistemi Operativi del Prof. Giammona - Aggiornati al 16 maggio 2014 Pagina 18 di 26 solo a quella porzione di memoria usata per l’allocazione. Tipicamente usato nei S.O. mono task; 2. Dinamica: in questo caso il calcolo dell’indirizzo fisico viene effettuato solo in corso di esecuzione del programma, ciò significa che tutti gli indirizzi cui esso fa riferimento all’atto del caricamento in RAM vengono lasciati inalterati, in pratica restano indirizzi logico-virtuali. Il gestore della memoria del S.O. svolge i seguenti compiti: 1. Tiene traccia di quali intervalli di indirizzi corrispondono ad aree di memoria libere o occupate; 2. Assegna la memoria centrale ai processi che ne fanno richiesta; 3. Gestisce le operazioni di swap-in e swap-out secondo opportune politiche di gestione; 4. Recupera la memoria centrale al termine di un processo. Tecniche di gestione della memoria 1. Allocazione a singola partizione: è una tecnica utilizzata nei S.O. monoprogrammati che prevede di utilizzare la parte di memoria RAM non occupata dal S.O. per allocarvi il programma utente. Il meccanismo di protezione è realizzato tramite l’uso di un registro limite che contiene l’indirizzo di memoria al di sotto del quale il programma utente non deve accedere per non invadere la porzione di RAM dedicata al sistema operativo. In questo modo se la RAM libera è grande rispetto alla dimensione del programma in esecuzione si ha uno spreco di memoria, se risulta troppo piccola per contenerlo il programma non può essere caricato ed andare in esecuzione, in pratica quindi una tecnica che non ottimizza la gestione della risorsa memoria centrale. 2. Allocazione a partizioni multiple: è una tecnica usata nei S.O. multiprogrammati e si basa sulla suddivisione dello spazio RAM disponibile in più partizioni, dove ogni partizione potrà ospitare un programma permettendo così la multiprogrammazione. Il gestore della memoria deve tenere traccia delle partizioni libere e di quelle occupate, come pure deve attuare il meccanismo di protezione che impedisce ad un processo di accedere ad indirizzi di memoria esterni alla propria partizione. Appunti sui Sistemi Operativi del Prof. Giammona - Aggiornati al 16 maggio 2014 Pagina 19 di 26 2.1.Partizioni multiple statiche: in questo caso la dimensione delle partizioni è fissata in anticipo dal sistemista che stabilisce per ottimizzarne lo sfruttamento partizioni di dimensioni differenti, cioè piccole, medie e grandi in modo tale da poter soddisfare le esigenze dei vari programmi. Questa tecnica genera una frammentazione degli spazi residui di ciascuna partizione che impedisce l’allocazione di altri programmi la cui occupazione sarebbe inferiore allo spazio libero totale. Nella figura seguente è visibile la tabella di gestione della partizioni. Nella figura seguente è possibile vedere un esempio di occupazione della memoria con la relativa tabella delle partizioni. 2.2.Partizioni multiple dinamiche: questa tecnica consiste nel non definire in anticipo la dimensione delle partizioni, in modo tale da allocare una partizione delle esatte dimensioni necessarie al programma da eseguire. Appunti sui Sistemi Operativi del Prof. Giammona - Aggiornati al 16 maggio 2014 Pagina 20 di 26 Purtroppo anche questa tecnica a seguito di operazioni di allocazione e deallocazione al termine dell’esecuzione di un programma, tende a generare delle porzioni di memoria (residui liberi) di dimensioni non sfruttabili singolarmente ma che raggruppate assieme potrebbero ospitare programmi anche di grosse dimensioni. Per cercare di ridurre questo problema vengono adottati degli algoritmi specifici che sono: • First Fit: assegnazione della prima partizione libera di dimensioni tali da ospitare il programma; • Best Fit: assegnazione della più piccola partizione che possa contenere il programma; • Worst Fit: assegnazione della partizione più grande tra tutte quelle capaci di contenere il programma. In questo caso il gestore della memoria deve usare due tabelle, una che contiene le informazioni sulle partizioni allocate ed una che contiene le informazioni sulle aree libere, così come mostrato nella figura seguente (lato sinistro). Nella figura sopra (lato destro) è possibile vedere un esempio di occupazione della memoria con relativa tabella delle partizioni e tabella delle aree libere. Appunti sui Sistemi Operativi del Prof. Giammona - Aggiornati al 16 maggio 2014 Pagina 21 di 26 Allocazione non contigua Si parla di allocazione contigua, quando il programma viene caricato in memoria come un unico blocco, mentre si parla di allocazione non contigua, quando il programma all’atto del caricamento in memoria viene suddiviso in più blocchi sparsi. Le tecniche analizzate finora sono tutte basate sull’allocazione contigua, che però a quanto abbiamo visto sembrano soffrire sempre del fatto che rimangono svariati residui sparsi di memoria RAM che singolarmente non consentono il caricamento di un programma da eseguire, ma che raggruppati assieme avrebbero una capienza sufficiente allo scopo. Per rimediare a questo problema, si adottano tecniche basate su allocazione non contigua. La paginazione La paginazione consiste nel suddividere logicamente il programma in pagine e la memoria RAM in blocchi aventi la stessa dimensione delle pagine (in genere multipli di 2K). In questo modo, le pagine in cui si suddivide il programma, che hanno indirizzi contigui, vengono caricate in blocchi di memoria sparsi, cioè con indirizzi di memoria non contigui, ovvero dove vi è la disponibilità. Per tenere traccia della situazione, il gestore della memoria ha bisogno di due tabelle: la tabella delle pagine e la tabella dei blocchi. La figura sotto, mostra un esempio di tale organizzazione. Con questa tecnica è necessario trasformare gli indirizzi relativi di variabili e istruzioni contenuti nelle pagine in indirizzi assoluti, in funzione dell’indirizzo di caricamento del blocco, tale operazione viene effettuata a RUNTIME, quindi questa tecnica si basa su rilocazione dinamica e allocazione statica. Appunti sui Sistemi Operativi del Prof. Giammona - Aggiornati al 16 maggio 2014 Pagina 22 di 26 Grazie a questa tecnica il problema della frammentazione viene risolto completamente, ma si presenta un altro problema, cioè quello di non poter caricare in memoria un programma che ha bisogno di 5 pagine se ne abbiamo a disposizione solamente 4. Vedremo tra poco che la memoria virtuale ci permette di superare anche questa ulteriore limitazione. La memoria virtuale La memoria virtuale è una tecnica di gestione che consente di eseguire programmi le cui dimensioni superano la memoria Ram effettivamente disponibile, grazie al fatto che del programma da eseguire ne viene caricata in RAM solo una parte, lasciando la parte restante su hard-disk, in modo tale da poter cominciare l’esecuzione. Nel momento in cui serviranno le altre porzioni del programma, queste verranno caricate in memoria secondo la necessità. Con questa tecnica è possibile, per esempio, eseguire un programma di 1 Megabyte avendo a disposizione solamente 100 Kilobytes di memoria. Teoricamente abbiamo a disposizione una memoria infinita, ma solo virtualmente, non fisicamente. Grazie alla memoria virtuale, si supera il limite della memoria fisica finita, si aumenta notevolmente la multiprogrammazione con relativo migliore sfruttamento delle risorse. La memoria virtuale si basa su due principi di località: 1. Località temporale: le locazioni di memoria usate di recente è probabile che verranno presto riutilizzate; 2. Località spaziale: se è stata indirizzata una locazione di memoria è probabile che presto saranno indirizzate anche le locazioni ad essa adiacenti. La gestione della memoria virtuale deve seguire tali criteri: • si deve spezzettare un programma; • si devono caricare in Ram solo alcuni pezzi del programma lasciando il resto su memoria di massa; • se durante l’esecuzione di un programma viene richiesta una pagina che non è presente in memoria, si dovrà provvedere al caricamento con eventuale rimozione di una pagina (algoritmi di rimozione). Appunti sui Sistemi Operativi del Prof. Giammona - Aggiornati al 16 maggio 2014 Pagina 23 di 26 Tecniche di gestione basate sulla memoria virtuale Le tecniche di gestione della memoria virtuale sono: 1. gestione virtuale a richiesta di pagine; 2. gestione segmentata; 3. gestione segmentata-paginata. Gestione virtuale a richiesta di pagine Questa tecnica funziona come la paginazione illustrata precedentemente, solo che non tutte le pagine del programma sono caricate in memoria in un certo istante, ma vengono caricate a seconda della necessità, cioè se la prossima istruzione da eseguire si trova in una pagina non presente in RAM, viene generato un interrupt per mancanza di pagina (page fault) e viene richiesto al S.O. di provvedere al suo caricamento dalla memoria di massa. All’atto del caricamento in RAM di una pagina richiesta si possono verificare due casi: • 1° caso: in memoria centrale c’è un blocco libero che può ospitare la pagina da caricare, in questo caso si procede al caricamento da memoria di massa a memoria centrale (operazione di swap in) e si aggiornano le varie tabelle di gestione; • 2° caso: non ci sono blocchi liberi in memoria centrale. In questo caso il S.O. deve scegliere quale pagina liberare tra quelle occupate per caricare quella necessaria al programma in esecuzione. Per fare la scelta migliore il S.O. ricorre ad un algoritmo di rimpiazzamento che può essere: FIFO: viene rimpiazzata la pagina che per prima è entrata in memoria; LRU (Last Recently Used): viene rimpiazzata la pagina che non viene usata da più tempo; NRU (Not Recently Used): viene rimpiazzata una pagina non utilizzata di recente. L’operazione di salvataggio su memoria di massa della pagina da liberare prende il nome di swap out. Per evitare di salvare inutilmente una pagina su disco, si può utilizzare un bit che segnala se la pagina in questione ha subito o meno modifiche, in Appunti sui Sistemi Operativi del Prof. Giammona - Aggiornati al 16 maggio 2014 Pagina 24 di 26 modo che qualora non ci siano state modifiche non sarà necessario fare l’operazione di swap out, ma si potrà procedere direttamente con lo swap in. Gli svantaggi della gestione virtuale a richiesta di pagine sono: - tempi di accesso alla memoria raddoppiati; - eccessiva occupazione della memoria da parte delle varie tabelle di gestione; - difficile scelta della pagina da liberare senza che si verifichino troppi page fault (fenomeno del trashing). Il fenomeno del trashing può essere risolto adottando un algoritmo di rimpiazzamento intelligente, mentre nel caso in cui fossero presenti in memoria troppo poche pagine del processo in corso, il problema si potrebbe ripresentare, in questi casi si prende in considerazione il modello detto working set, cioè l’insieme delle pagine virtuali utilizzate correntemente dal processo in un certo istante. Gestione segmentata Nella tecnica memoria virtuale a gestione segmentata, il programma non viene più suddiviso in pagine la cui dimensione dipende dai blocchi di memoria centrale, ma viene suddiviso in porzioni dette segmenti, dove ogni segmento corrisponde per esempio a un array, una tabella, una routine, ecc. In questo modo, vengono caricati in memoria solo quei segmenti del programma necessari alla sua esecuzione. Nella figura a fianco si vede un esempio di programma composto da 5 segmenti: tab1, tab2, main, proc1 e proc2. Inizialmente per cominciare l’esecuzione del programma basta caricare in memoria il programma principale (segmento main) e poi secondo le necessità caricare gli ulteriori segmenti. Gestione segmentata-paginata Appunti sui Sistemi Operativi del Prof. Giammona - Aggiornati al 16 maggio 2014 Pagina 25 di 26 Questa tecnica combina la segmentazione con la paginazione, nel senso che un segmento invece di essere un unico blocco di memoria viene suddiviso in pagine di dimensioni prefissate e la memoria è divisa in blocchi aventi la stessa dimensione delle pagine. In questo modo la corrispondenza tra indirizzo logico e indirizzo fisico è stabilita specificando il segmento, il numero di pagina ed il numero di byte nella pagina. Con tale tecnica il S.O. deve gestire due eccezioni: segment fault (mancanza del segmento in memoria) e page fault (mancanza della pagina in memoria). La segmentazione-paginata è abbastanza efficiente e flessibile, consente una buona protezione della memoria, ma ha una gestione più gravosa da parte del S.O., come pure si ripresenta il problema della frammentazione. Appunti sui Sistemi Operativi del Prof. Giammona - Aggiornati al 16 maggio 2014 Pagina 26 di 26