Scheduling della CPU Simulazione in linguaggio Java Realizzato da: Amelio Francesco 556/001699 Di Matteo Antonio 556/000067 Viola Antonio 556/000387 Progetto di Sistemi Operativi Docente Giancarlo Nota a.a. 2002/03
Uno sguardo all insieme Introduzione allo scheduling della Cpu Scenario dei componenti implementati Utenti Processi Ready Queue Scheduler e Dispatcher Input/Output CPU
Introduzione Lo Scheduling della Cpu è la base della multiprogrammazione. Lo scopo dello scheduling è ottimizzare la produttività del sistema di elaborazione, assegnando ad ogni istante la risorsa CPU ad uno solo processo, secondo diversi criteri. La simulazione si sviluppa su alcune ipotesi di base che ne hanno permesso una realizzazione alquanto realistica.
Scenario Utente 1 Ready IO Device New Process R E A D Y Q U E U E Ready Scheduler Dispatcher Wait Context switching Run I O Q U E U E Utente N CPU Terminated
SO La classe SO dà una visione generare del sistema, avendo le istanze di tutti i dispositivi che interagiscono nella simulazione. Impone alle classi User e _Process degli intervalli (cpu burst, IO burst, numero di IO, ), utilizzati per limitare la casualità dei valori. Contiene altri parametri specifici.
Utenti Nella nostra simulazione un utente è un thread che ha il solo scopo di creare e lanciare processi, tramite push nella ready queue. Ogni lancio è intervallato da un tempo casuale. Esistono due tipi di utente: User ed _User. La differenza è che il primo genera in modo casuale processi e ritardi di lanci; il secondo viene costruito con processi e ritardi prefissati, viene usato nel confronto di algoritmi.
Processi Un processo è l istanza di una classe, contenente un PID univoco, una priorità, un PC, un burst di cpu ed una sequenza di IO stabiliti durante la creazione, tutto in modo casuale, attenendosi a limiti prefissati. Il suo metodo principale è work(), che incrementa il PC e restituisce lo stato del processo in quell istante, fra: NORMAL_STATUS, IO_STATUS, END_STATUS.
Ready Queue La Ready Queue è un interfaccia implementata da due diverse strutture dati: F.I.F.O e Priority Queue. I push vengono effettuati da User, _User, Dispatcher e IODevice; Il pop viene effettuato esclusivamente dallo Scheduler, in base al proprio criterio di schedulazione.
Scheduler e Dispatcher Scheduling è un interfaccia implementata dai vari algoritmi trattati, allo scopo di rendere universale l utilizzo dello scheduler specifico da parte del Dispatcher. Il Dispatcher è l unico oggetto che comunica con la CPU, attraverso il context switching. Gli algoritmi implementati sono: FCFS SJF Priority Round Robin
First Come First Served L algoritmo FCFS rispetta i canoni di F.I.F.O., in ordine di tempo. Non è prelazionato e quindi ogni processo, una volta acquisita la risorsa CPU, salvo richieste di IO, eseguirà il suo burst totale.
Shortest Job First Nella nostra simulazione l SJF si basa sull ipotesi di sapere anticipatamente il cpu burst successivo di ogni processo (generato nel costruttore di _Process e ottenuto tramite il metodo getnextcpuburst()). Passando un parametro al costruttore, lo si può creare con o senza prelazione. La prelazione avviene tramite uno scambio di messaggi fra la Priority Queue e l SJF, infine con la CPU ( chiamando il metodo interruptrunningps()).
Priority L algoritmo a priorità non fa altro che sfruttare una coda a priorità, che ad ogni push ordina in modo decrescente le istanze di _Process. Può essere prelazionato e non, avere un timer di aging e non. Il timer è implementato attraverso la classe AgingTimer, un thread che ha lo scopo di aumentare la priorità di tutti i processi in coda allo scadere di un tempo prestabilito.
Round Robin Lo scheduling Round Robin è simile ad FCFS, ma ha la prelazione che avviene allo scadere di un quanto di tempo prestabilito. Il quanto di tempo viene scandito all interno della CPU, che blocca l iterazione del metodo work() del processo in esecuzione. Il processo passerà dallo stato running allo stato ready, rientrando nella ReadyQueue tramite il Dispatcher.
Input Output L input output è gestito nella nostra simulazione tramite una IORequest, che un istanza di _Process può richiedere durante l iterazione del suo metodo work(); la CPU rileverà lo stato (IO_STATUS), creerà una richiesta, che tramite il Dispatcher, entrerà in una IOQueue. Il thread IODevice elaborerà questa richiesta (tramite una sleep(n) con n uguale all IO burst richiesto) ed infine rimetterà il processo nella ReadyQueue. Avremo il seguente cambio di stati: running, waiting, ready.
CPU La CPU è il thread con priorità massima. Ad ogni istante richiede un processo allo Dispatcher, lo elabora iterando il metodo work(), fin quando non si verificherà uno dei seguenti eventi: Time slice scaduto (solo con Round Robin) Interruzione esterna (SJF e Priority) Richiesta di IO Terminazione del burst del processo
Interfaccia grafica