La gestione del clock in Minix Sistemi Operativi Lez. 29 1
La periferica Il cristallo di quarzo sottoposto a tensione genera un segnale con frequenza che varia da 5 a 200 MHz Ad ogni ciclo il contatore viene decrementato quando raggiunge il valore zero: La periferica invia un Interrupt HW (IRQ 8) Il contatore viene re-inizializzato L intervallo di tempo che intercorre tra un interrupt ed il successivo è denominato clock tick 2
Esempio Un clock chip che contiene un contatore a 16 bit ed un cristallo che genera segnali a 5 MHz, genererà clock tick della durata compresa tra 0,2 microsecondi e 13,1 millisecondi E se il clock è a 100 Mhz? Solitamente all interno di un PC esistono più chip di clock programmabili I chip di clock usati per la sincronizzazione di CPU e BUS di sistema usano circuiti diversi da quelli usati per la gestione degli eventi 3
Funzionalità svolte Time of the day: solitamente ottenuto memorizzando il numero di secondi (in termini di tick) trascorsi a partire dal 1/01/1970 4
Funzionalità svolte Segnalare la terminazione dei quanti di tempo: i quanti di tempo sono definiti in termini di tick ad ogni interrupt di clock si decrementa il quanto di 1 Accounting per l uso della CPU 5
Funzionalità svolte Gestire segnali a tempo per conto dei processi eseguiti dal sistema: alcuni processi basano le loro azioni sull avverarsi o meno di certi eventi, entro intervalli di tempo predeterminati (es. ack di TCP) 6
Funzionalità svolte Watchdog timers: simili ai precedenti, con la differenza che allo scadere del tempo prefissato invece di inviare segnali richiamano opportune procedure di gestione Profiling: raccogliere i tempi di esecuzione di diverse componenti del sistema o dei processi utente 7
Implementazione Le componenti del sistema operativo coinvolte nella gestione del clock sono: Interrupt handler Clock driver (clock task) Che si appoggia su do_clocktick per svolgere le operazioni richieste Routine di servizio: leggere il clock, leggere l ora del sistema, leggere dei registri all interno del chip 8
Driver È la prima componente che si occupa del clock ad essere eseguita sul sistema e quindi deve provvedere alla inizializzazione del dispositivo Viene avviata in fase di boot Costituita da un loop infinito che riceve solo un tipo di messaggi provenienti da HARD_INT e generati dall interrupt handler 9
Clock driver 10
init_clock() clock_hook.proc_nr_e = CLOCK; Terminata l esecuzione di init_clock(), dopo 16,67 millisecondi arriverà il primo clock interrupt 11
irq_handlers [nr_irq_hook] irq_hook_t irq_hook_t irq_hook_t irq_hook_t 12
Strutture dati: irq_hook_t STRUTTURA DATI DI RIFERIMENTO PER LA GESTIONE DEGLI INTERRUPT, ESISTE ALMENO UN ELEMENTO irq_hook_t PER OGNI TIPO DI INTERRUPT *HANDLER n.ro IRQ hook_id pid driver policy next Generic handler 13
Strutture dati Minix typedef unsigned long irq_policy_t; typedef unsigned long irq_id_t; typedef struct irq_hook { struct irq_hook *next; /* next hook in chain */ int (*handler)(struct irq_hook *); /* interrupt handler */ int irq; /* IRQ vector number */ int id; /* id of this hook */ int proc_nr_e; /* (endpoint) NONE if not in use */ irq_id_t notify_id; /* id to return on interrupt */ irq_policy_t policy; /* bit mask for policy */ } irq_hook_t; typedef int (*irq_handler_t)(struct irq_hook *); 14
00089 /*===========================================================================* 00090 * put_irq_handler * 00091 *===========================================================================*/ 00092 PUBLIC void put_irq_handler(hook, irq, handler) 00093 irq_hook_t *hook; 00094 int irq; 00095 irq_handler_t handler; 00096 { 00097 /* Register an interrupt handler. */ 00098 int id; 00099 irq_hook_t **line; 00100 00101 if (irq < 0 irq >= NR_IRQ_VECTORS) 00102 panic("invalid call to put_irq_handler", irq); 00103 00104 line = &irq_handlers[irq]; 00105 id = 1; 00106 while (*line!= NULL) { 00107 if (hook == *line) return; /* extra initialization */ 00108 line = &(*line)->next; 00109 id <<= 1; 00110 } 00111 if (id == 0) panic("too many handlers for irq", irq); 00112 00113 hook->next = NULL; 00114 hook->handler = handler; 00115 hook->irq = irq; 00116 hook->id = id; 00117 *line = hook; 00118 00119 irq_use = 1 << irq; 00120 } 15
interrupt_handler() Per prima cosa aggiorna realtime (n.ro di ticks trascorsi dal boot) prevedendo eventuali lost_ticks, variabile globale aggiornata da driver e interrupt handler 16
interrupt_handler Aggiorna il PCB del processo nel caso di processo di sistema (quindi non billable) addebita i tick al processo billable di riferimento 17
interrupt_handler Nel caso di quanto terminato, o di watchdog timers scaduto viene richiamato il clock driver 18
do_clocktick 19
do_clocktick 20
Clock Service 21