Sei sulla pagina 1di 34

1 – SISTEMI EMBEDDED REAL TIME

È un sistema che acquisisce dati dal mondo esterno tramite dei sensori e agisce su di esso per mezzo di attuatori.
Sensori: raccolgono dati dall’ambiente del sistema. Attuatori: cambiano attraverso certe azioni l’ambiente del sistema.

La particolarità di un sistema real-time è che la correttezza dell’elaboratore dipende non solo dai valori in uscita ma
anche dall’istante in cui tali risultati vengono resi disponibili.

Per far ciò il sistema Real time deve essere sottoposto a dei vincoli temporali, dunque il tempo del sistema deve essere
sincronizzato con quello dell’ambiente esterno

Es cruise control: Una volta dato l’input, il


rilevatore di velocità setta un timer che
interrompe periodicamente la rilevazione
con periodo T. A ciascuna interruzione
legge, computa e scrive.

• Soft real time system: è un sistema in cui se le operazioni non rispettano le relative deadline provocano un
danno NON irreparabile
• Hard real time system: è un sistema in cui se le operazioni non rispettano le relative deadline provocano un
danno irreparabile

SISTEMI REAL TIME CONCORRENTI/DISTRIBUITI


Le funzioni di controllo (monitor) e di azione (attuatore) possono essere svolte sulla stessa CPU (concorrenti) o su
diverse CPU

• Concorrenti (stessa CPU): una sola CPU che elabora 2 o più


attività che agiscono in concorrenza. La CPU può svolgere
soltanto un’attività alla volta, per cui avranno uno
sfasamento. Per regolare la sincronizzazione, la CPU deve
anche occuparsi della trasmissione e scambio di dati tra le
attività.

• Distribuiti (2 o più CPU): sono applicazioni che prevedono


l’utilizzo di più sistemi collegati tra loro tramite dei trasmettitori
(CAN).
Middleware= insieme di programmi che fanno da intermediari tra
le applicazioni e l’hardware. Contengono librerie che servono a
semplificare la progettazione di sistemi distribuiti.

I sistemi Real Time si possono dividere in:

• Pc integrati con un OS; il SO gestisce i vari task tramite lo scheduler.


• Microcontrollori senza OS (ex. Arduino); chi scrive le operazioni gestisce i task.
5 - REAL TIME OPERETING SYSTEM
Utilizzare un sistema concorrente serve a sfruttare al meglio il processore. Bisogna evitare che rimanga inattivo (idle).
La concorrenza serve per modellare il parallelismo anziché utilizzare una programmazione sequenziale.

Un solo processo alla volta può essere eseguito in un istante di tempo, ma usando il time sharing il SO può switchare i
processi e decidere chi eseguire, in modo tale da far risultare che stia eseguendo tanti processi “allo stesso tempo”. È
importante per il SO sapere quali processi sono pronti per essere eseguiti.

a) Creation: creazione del processo


b) Dispatch: azione di selezione del processo dalla coda
dei processi pronti per la sua esecuzione
c) Preemption: azione per cui un processo abbandona
l’uso del processore prima della sua conclusione ed
entra in una coda d’attesa (es: un processo a priorità
più alta chiede di essere eseguito)
d) Wait on Condition: processo bloccato per una
condizione (es: attesa di I/O)
e) Condition true: sblocco dei processi
f) Exit: processo terminato

Time sharing systems: ogni processo ha a disposizione blocchi di tempo


per l’esecuzione. Alla fine del turno subentra un altro processo. I processi
sono inizialmente tutti in coda, secondo l’ordine stabilito dal criterio di
schedulazione

Context switch (cambio di contesto):

• Succede quando:
o Il processo ha una priorità minore rispetto ad uno appena arrivato
o Il processo si è bloccato su una condizione
o Il processo ha concluso il suo round (solo nei Time-sharing-systems)
• Bisogna salvare il suo stato per ripristinare il processo in seguito, richiede del tempo
• Esso può essere
o Volontario: il processo richiama una funzione primitiva (bloccante come un read() )
o Involontario: un’interruzione causa il context switch

Coda di attesa multiple

Notiamo che ci possono essere più code dei processi e anche queste code
possono avere un ordine di precedenza, con algoritmi di schedulazione
diversi.
Differenza fra Threads e Processi

• Processi:
o Gestione risorse: un processo ha uno spazio di indirizzamento nel quale sono allocate le risorse
o Esecuzione: l’esecuzione di un processo è un percorso e genera una traccia, sequenza di stati interni. È
composto da vari stati e da parametri di scheduling.
o Generalmente un processo non condivide memoria. La comunicazione tra processi avviene con
primitive. Lo switch tra i processi è più complesso per via del cambio di spazio di indirizzamento.
• Thread:
Due Threads dello stesso processo condividono lo stesso spazio di indirizzamento, dunque hanno accesso alle
stesse variabili, la comunicazione tra Thread è più semplice e lo switch tra Thread è meno costoso.

I processi utilizzano risorse distinte mentre i Thread le condividono. I processi solitamente sono in contrasto per
l’acquisizione di risorse. I Threads sono utilizzati invece per collaborare ad un solo obiettivo.
I thread sono entità schedulabili che vengono eseguite con un processo, ogni processo ha un thread principale,
il quale, può averne molti altri con cui condivide lo spazio di indirizzamento del processo invocato

La maggior parte dei Sistemi RT non fornisce le caratteristiche di un sistema desktop standard.
Generalmente:
• Hanno una singola funzione.
• Non richiedono l’interazione con l’utente.
• Richiedono meno hardware di quello richiesto dalle funzioni di un PC desktop.

• Caratteristiche di un RTS:
o Controllo concorrente di diverse parti del sistema (si lavora in parallelo).
o Estremamente affidabile e sicuro, i RTS controllano l’ambiente in cui operano; la generazione di errori nel
controllo possono causare danni.
o Tempi di risposta garantiti (dobbiamo predire il caso peggiore)
• Caratteristiche desiderabili:
o Tempestività: bisogna implementare meccanismi di gestione del tempo e di gestione dei task nei tempi
o Predicibilità: essere sicuri che il sistema si comporterà come previsto. Garantire la soddisfazione delle
deadline
o Tolleranza del guasto: dei guasti nel sistema non devono causare problemi
o Costruiti per il caso peggiore: tutti gli scenari vanno considerati.

(Alcuni di questi requisiti possono essere soddisfatti con elementi del SO)

Le caratteristiche principali di un Real-time operating system sono:

• Preemptive, priority based scheduling. Scheduling con priorità


• Preemptive kernel. Kernel a rilascio anticipato
• Latenza minimizzata
la latenza di un evento è la quantità di tempo da quando un evento accade a quando il sistema risponde. La
latenza di un interrupt è il periodo di tempo da quando arriva l’interrupt alla CPU a quando viene gestito. La
latenza di dispatch (d’invio) è il tempo richiesto dallo scheduler per fermare un processo e iniziarne un altro.
RAGGIUNGIMENTO DELLA PREDICIBILITA’

Per quanto riguarda la predicibilità ci sono molti elementi che possono portare ad un non-determinismo, come ad
esempio le caratteristiche del SO, la gestione della memoria e le architetture. Di seguito, alcuni metodi per raggiungerla.

DMA (Direct Memory Access)


Serve per il trasferimento diretto di dati dai dispositivi alla memoria principale, senza l’utilizzo dalla CPU.

Problema: il dispositivo I/O e la CPU usano lo stesso bus. Due possibili soluzioni:

• Cycle stealing. Il DMA ruba alla CPU un ciclo di memoria per eseguire un trasferimento di dati. La CPU aspetta
finché il trasferimento non venga completato. Il sistema non è deterministico.
• Time-slice method. Ogni ciclo di memoria è diviso in due slots: uno per la CPU e uno per il DMA. Più costoso ma
deterministico.

Cache
Per ottenere un’alta predicibilità è meglio avere un processore senza cache.

Interrupts
Nella maggior parte dei OS gli interrupts sono utilizzati per rispettare la priorità di schemi prefissati. Gli interrupts hanno
una priorità più elevata dei processi. Il ritardo prodotto dagli Interrupts è causato da quanti Interrupts avvengono
durante l’esecuzione di un task e da quanto dura la loro esecuzione.

Il problema che può sussistere è che i processi da eseguire siano più importanti delle operazioni di I/O che causano
interrupts. Soluzioni:

1. Si può pensare di disabilitare tutti gli interrupt eccetto quelli dei timer. Questo comporta che tutti i dispositivi
periferici debbano essere gestiti tramite dei task, il trasferimento dati utilizza il meccanismo del polling
(trasferisce quando è il suo turno), è un meccanismo flessibile che permette di stimare precisamente i tempi per
il trasferimento dati e non serve cambiare il kernel quando si aggiungono dispositivi. Tuttavia a causa dell’attesa
della CPU si ha una riduzione delle performance del processore e i task devono essere a conoscenza dei dettagli
dei livelli inferiori del sistema.
2. Si disabilitano tutti gli interrupt tranne quelli dei timer e si gestiscono i dispositivi tramite speciali routine del
kernel con timer attivato. I vantaggi sono che vengono eliminati i ritardi dovuti agli interrupt, si può stimare in
anticipo le routine periodiche dei dispositivi e i dettagli dell’hardware possono essere incapsulati in particolari
routine dedicate. Gli svantaggi sono che non viene risolta la riduzione della performance del processore, che ci
sono più comunicazioni tra processi che vanno gestite e che il kernel deve essere modificato quanto vengono
aggiunti dei dispositivi.
3. Vengono abilitati degli interrupt esterni e vengono ridotti i driver (insieme di procedure che permettono ad un
sistema operativo di pilotare un dispositivo hardware) alle dimensioni più piccole possibili. Questi si attivano
solo per gestire determinate task del dispositivo corrispettivo. I task vengono comunque eseguiti sotto il
controllo dell’OS come tutti gli altri task. Inoltre i task degli utenti hanno maggiore priorità dei task dei
dispositivi. I vantaggi sono che non si ha più l’attesa alla CPU, vengono notevolmente ridotti i ritardi dovuti agli
interrupt dei dispositivi, e quelli restati possono essere stimati precisamente.

System Calls
Tutte le chiamate di sistema devono essere caratterizzate da un limitato tempo di esecuzione. Tutte le primitive del
kernel devono essere predicibili. Chiamate non predicibili possono ritardare l’esecuzione di attività critiche.

Semafori
In generale i semafori non sono adatti ai sistemi RT per dei problemi che riguardano le inversioni di priorità, infatti un
task ad alta priorità può essere bloccato da uno a più bassa priorità per un periodo di tempo imprecisato. La soluzione è
quella di usare speciali protocolli: Priority Inheritance o Priority Ceiling.
Priority ceiling: è una tecnica che serve a limitare l’acceso ad una risorsa limitata da parte di un task a priorità più bassa.
Un task non può accedere ad una risorsa se essa è occupata da un task a priorità più alta. Il SO deve avere nel codice
un’istruzione per specificare le priorità dei task.

Priority inheritance: la priorità del task cambia nel corso della sua esecuzione per mano del SO, per tenere conto della
priorità di altri task che hanno bisogno della risorsa. Questo protocollo ha il vantaggio di essere completamente
trasparente al programmatore e di impedire l’inversione di priorità. Non impedisce però i deadlock ed i blocchi a catena.

6 - POSIX THREADS

POSIX = Portable Operating System Interface. Famiglia di standard IEE che mantiene la compatibilità tra diversi OS.

I thread sono entità che possono essere schedulabili e che vengono eseguiti all’interno di un processo. Ciascun processo
ha un thread principale e può avere più thread aggiuntivi che condividono lo stesso spazio di indirizzamento del
processo invocato tramite pthread_create().
Pthread è implementato dalla libreria libpthread.so. Il file header pthread.h consente di includere nella propria
applicazione in linguaggio C un set di circa cento funzioni, costanti, definizioni e strutture, tutti identificati dal prefisso
pthread_ e divisi in quattro gruppi:

• gestione dei thread (creazione e chiusura)


• variabili mutex
• variabili condizioni
• sincronizzazione tra thread

La creazione di un thread avviene tramite la funzione pthread_create la quale accetta 4 parametri:

• pthread_t, variabile con cui si può fare riferimento al thread


• pthread_attr_t, contiene gli attributi di configurazione
• il puntatore alla funzione funct, funzione eseguita dal thread
• il puntatore agli argomenti da mappare alla funzione.

La configurazione avviene attraverso una variabile di tipo pthread_attr_t: tale variabile contiene tutti gli elementi di
configurazione del thread. Una volta inizializzata può essere usata per mostrare varie configurazioni grazie a funzioni
specifiche. Può essere riutilizzata per la configurazione di altri thread e le eventuali modifiche dopo la creazione.

La funzione threadRun passata al thread implementa l’attività del task, restituisce void* e deve terminare con la
chiamata alla funzione pthread_exit che segnala l’uscita da un thread.

Passaggio di parametri. È possibile interagire con l’esecuzione di un thread attraverso i parametri passati alla funzione
task e attraverso variabili globali o comunque visibili nell’ambito della funzione.

La chiusura di un thread dipende dalla tipologia di thread:

• thread joinable: Il thread invocante attende la terminazione del thread invocato chiamando una funzione. Tutte
le strutture dati allocate dal thread non verranno deallocate fino alla chiamata del pthread_join.
• thread detached: Questi invece hanno un’esecuzione completamente autonoma rispetto al thread invocante

Due o più thread possono fare accesso ad una risorsa condivisa (es: una variabile globale) solo in modo mutuamente
esclusivo. Per garantire che, in ogni istante, solo un thread possa accedere alla risorsa occorre definire delle sezioni
critiche. La libreria pthread gestisce l’accesso alle sezioni critiche attraverso degli oggetti detti mutex (mutualexclusive).
Ogni thread può acquisire e rilasciare il controllo di un mutex attraverso due funzioni definite dalla libreria stessa. Fino a
quando un thread mantiene il controllo su un certo mutex, nessun altro thread può acquisirne il controllo. Quando un
thread rilascia il controllo di un mutex, un altro può prenderne possesso.

La libreria pthread consente di notificare il verificarsi di particolari eventi:


• Un thread resta in attesa del verificarsi di un particolare evento
• Un altro thread esegue una notifica «sbloccando» il thread in attesa.
Il meccanismo richiede l’uso dei mutex e di un’altra particolare variabile detta «condizione».
La libreria mette a disposizione funzioni per l’attesa, la notifica e la notifica broadcast di «condizioni»
Il meccanismo è simile al metodo notify()di Java.
L’operazione di notifica è associata ad un mutex e deve essere eseguita solo quando si è in possesso del mutex, in caso
contrario il comportamento risulta impredicibile.
Pthread_cond_wait serve per attendere che la risorsa sia disponibile.
Al momento della chiamata a pthread_cond_signal, il thread chiamante rilascia il mutex e l’esecuzione passa al thread in
attesa. In caso non ci siano thread in attesa il chiamante riacquisisce il mutex e riprende l’esecuzione. La funzione
pthread_cond_signal può notificare soltanto un singolo thread in attesa. Nel caso si vogliano notificare più thread è
possibile usare pthread_cond_broadcast:

• il chiamante rilascia il lock sul mutex.


• Tutti i thread in attesa vengono notificati e concorrono per l’acquisizione del mutex.
• Solo uno lo acquisisce entrando nella sezione critica.

7 - TASK COMUNICATION

In molte applicazioni Real-time i task si scambiano dati tramite l’uso di variabili globali:

• Vantaggi: meccanismo più veloce, possibilità di analisi di schedulazione, basso tempo di esecuzione
• Svantaggi: bisogna accedere ai dati con mutua esclusione, non adatto per design modulari, un cambiamento di
un task comporta un cambiamento anche negli altri tasks

Un’altra tecnica è quella di scambiarsi messaggi per scambiarsi dati, ciò comporta che

• ogni task deve avere uno spazio privato di memoria


• i dati sono scambiati attraverso messaggi, set di dati aventi un formato, canale, link logico attraverso il quale
due task possono comunicare.

Molti canali mantengono l’astrazione attraverso i port, i task scambiano messaggi tramite l’uso di due primitive:

• send: manda messaggi a un port


• receive: riceve messaggi da un port

I port si possono differenziare per:

• numero di task che possono mandare messaggi


• numero di task che possono ricevere messaggi
• politica usata per estrarre e mandare messaggi
• reazione in caso di eccezioni

Prima di essere usata, una port deve essere creata dopodiché distrutta se non più utilizzata. Gli attributi delle port
devono essere definiti al momento della creazione.

Un messaggio mandato ad un port è inserito in un buffer, la cui dimensione è definita al momento della creazione, con
da una parte il mittente (task1) e dall’altra il destinatario (task2).

Nel momento in cui i due task avessero frequenza diversa il canale potrebbe riempirsi troppo o svuotarsi troppo.
Problemi di invio messaggio: se un messaggio viene inviato quando il buffer è pieno può succedere che:
• il mittente è bloccato finché il destinatario non legge un messaggio
• il messaggio viene perso
• un messaggio di errore ritorna al mittente

Problemi ricezione del messaggio: se il buffer è vuoto il ricevente è bloccato finché un nuovo messaggio non viene
inviato oppure un messaggio di errore viene mandato al ricevente.
Esiste un proprietario della connessione (A) ed è colui
che deve iniziare per primo.

Problematiche dei task periodici: (T periodo di esecuzione e τ nome del processo)

1. 𝑇1 <𝑇2
o 𝜏1 manda molti più messaggi nel buffer di quanti 𝜏2 possa leggerne.
o Quando il buffer si riempie 𝜏1 procede alla stessa frequenza di 𝜏2
2. 𝑇1 >𝑇2
o 𝜏2 legge molti più messaggi di quanti 𝜏1 possa inviarne
o Quando il buffer si svuota 𝜏2 deve procedere alla stessa frequenza di 𝜏1

Quindi se 𝑇1 ≠ 𝑇2, dopo un certo periodo di tempo, entrambi i task andranno alla velocità di quello più lento. Per
raggiungere la priopria velocità di trasmissione, i task che usano port sincroni dovrebbero avere lo stesso periodo.

Buffer saturato (dopo quanto tempo il buffer si satura, cioè i task si stabilizzano su una frequenza)

𝑇1 𝑇2
𝑡 < (𝑁 − 1)
𝑇2 − 𝑇1
STICK ports

Sono delle porte con una semantica a messaggi di stato:

• L’ultimo messaggio è disponibile alla lettura


• Un nuovo messaggio sovrascrive quello precedente
• I messaggi, una volta letti, non vengono distrutti

Questa tecnica si usa quando non ci importa avere un buffer di tutti i messaggi, ma solo il più recente, ciò comporta che
i task non si interromperanno mai perché i buffer non saranno mai pieni o vuoti. Buffer a una dimensione.
Nonostante lo stick port non si blocchi in caso di buffer pieno (o vuoto), può bloccarsi per la mutua esclusione, in
maniera più specifica sui semafori. Lunghi messaggi possono causare lunghi ritardi sui semafori. Lunghe attese possono
essere evitate attraverso la replicazione dei buffer.

CAB = Cyclic Asynchronous Buffer

È un modo per scambiarsi messaggi tra task periodici con frequenza diverse

• I confitti di memoria sono evitati con la replicazione di buffer interni ad una dimensione (sono stick ports
replicate)
• L’ultimo messaggio è sempre disponibile alla lettura
• L’ultimo messaggio sovrascrive quello precedente
• I messaggi non sono distrutti dal lettore

Accessi simultanei
Se un task τw scrive, mentre un altro task τr sta leggendo si scrive un nuovo messaggio in un nuovo buffer.

DUAL BUFFERING

È comunemente usato per lo scambio di grandi dati provenienti


da dispositivi periferici. Una volta scritto il nuovo messaggio
diventa disponibile al prossimo lettore. Due buffer interni.

CAB non fa altro che generalizzare il dual buffering per N lettori. Così facendo il lettore non è forzato a memorizzare il
messaggio nel proprio spazio. L’accesso ai dati avviene con un puntatore alla memoria. Più lettori possono leggere lo
stesso messaggio in concorrenza. C’è sempre un puntatore mrb (most recent buffer) che punta al buffer più recente in
cui è scritto il nuovo messaggio.

Se questa tecnica CAB è usata da N task, per evitare blocchi, bisogna avere almeno N+1 buffer. Questi buffer
serviranno per mantenere il messaggio più recente nel caso i buffer siano usati.

Inconsistenza con N buffer: assumiamo che tutti i buffer siano usati e 𝜏𝑤


sovrascriva il messaggio più recente M4 con M5. Se, mentre 𝜏𝑤 sta scrivendo, 𝜏1
finisce e richiede un nuovo messaggio trova il CAB inconsistente.

Per scrivere un messaggio in un CAB, un task deve:

• Richiedere al CAB il puntatore ad un buffer libero


• Copiare il messaggio nel buffer usando il puntatore
• Rilasciare il puntatore al CAB per render disponibile il messaggio alle letture
Per leggere un messaggio in un CAB, un task deve

• Ottenere il puntatore al messaggio più recente nel CAB (mrb)


• “leggere” il messaggio attraverso il puntatore
• Rilasciare il puntatore per permettere al CAB di ridare il buffer se non usato

PRIMITIVE CAB

• Creation
o cab_create(cab_name, buf_size, max_buf) crea un CAB di grandezza max_buf buffers di lunghezza
buf_size byte
o cab_delete(cab_id) distrugge il CAB
• Writing
o cab_reserve(cab_id, pointer) ritorna il puntatore per scrivere in un buffer libero
o cab_putmes(cab_id, pointer) ritorna il puntatore dopo un’operazione di scrittura
• Reading
o cab_getmes(cab_id, pointer) ritorna un puntatore al messaggio più recente
o cab_unget(cab_id, pointer) rilascia il puntatore dopo l’operazione di lettura

8 RT- COMUNICATION

Uso del modello ISO-OSI


I layers dal 3 al 6 non sono sempre presenti poiché le loro
funzionalità non sono sempre necessarie. Ciò assicura una grande
efficienza dei messaggi, stretti tempi di risposta e bassi costi di
Hw Sw.

Livelli di Rete:
• Livello fisico: si occupa della codifica, decodifica,
trasmissione e ricezione dei bit
• Livello Data link: Contiene il Medium Access Control (MAC) il quale si occupa della condivisione del mezzo
trasmissivo
Paragone fra comunicazione e scheduling

Dominio di risorsa Comunicazione real time: rete Scheduling real-time: CPU


Utilizzo di risorsa Pacchetto a rilascio non anticipato Processi a rilascio anticipato (Preemptive)
Manager di risorse Controllo di accesso medio (MAC) Schedulatore
Bisogno di risorse Bit Cicli di clock della CPU
Metrica Ritardo end-to-end / tempo di risposta Schedulabilità / tempo di risposta

Scheduling
La risorsa contesa è la CPU. Se N task vengono eseguiti su un computer, il sistema operativo si occupa di stabilirne
l’esecuzione assegnando la CPU ai vari task, ovvero ha il compito di eseguire la schedulazione. Il gestore della risorsa è lo
scheduler.
Alcuni parametri fondamentali di cui tenere conto sono:
• Il tempo di risposta, ovvero quanto tempo trascorre da quando il task è pronto per l’esecuzione a quando viene
effettivamente eseguito.
• La schedulabilità di un task set, cioè la capacità del sistema operativo di gestire un insieme di task con
caratteristiche (periodo, deadline, tempo di esecuzione) differenti, rispettando i limiti di deadline.
È necessario che la CPU sia interrompibile, nel senso che per poter ripartire al meglio la CPU, i processi devono poter
essere interrotti in qualsiasi istante.
Comunicazione
Un altro tipo di risorsa condivisa è il bus, il mezzo trasmissivo. Il gestore della risorsa è il MAC, una funzionalità del
Sistema Operativo in grado di decidere a chi assegnare l’accesso al canale trasmissivo. In questo casonon ci sono dei
task ma i pacchetti. Un processo è l’esecuzione di un algoritmo. Nelle reti l’equivalente del processo è il pacchetto, che
non può assolutamente essere trasmesso in frammenti. Per la comunicazione esiste un solo parametro fondamentale: Il
tempo di risposta.

Livello DLC: CSMA/CD

La gestione del canale di comunicazione è assegnata al MAC (Medium Access Control) attraverso protocolli come
CSMA/CD: scambio di messaggi attraverso un canale condiviso. Viene anche definito Ethernet o IEEE 802.3.

Il CSMA/CD è un metodo di accesso al mezzo trasmissivo tipico del livello MAC in cui tutti i nodi sono connessi allo
stesso Bus.

Passi fondamentali del funzionamento di CSMA/CD

1. Un nodo connesso in rete ascolta se il mezzo di trasmissione è libero (carrier sense): se non lo trova occupato
trasmette, in caso contrario continua ad ascoltare. Una volta libero trasmetterà il messaggio.
2. Se viene rilevata una collisione durante una trasmissione, viene trasmessa una breve sequenza di jamming (un
messaggio di avviso) per assicurarsi che tutte le stazioni sappiano della collisione e non provino a trasmettere
evitando la creazione di ulteriori collisioni (collision detection)
3. Dopo la trasmissione del segnale di jamming, si attende una quantità di tempo pseudo casuale e si ritenta la
trasmissione

Questo scambio di messaggi non è però deterministico poiché ci sono delle attese, non è possibile dunque applicarlo ai
sistemi real-time.

Controllo di accesso al mezzo

È importane che i messaggi arrivino nel tempo definito dal progettista. L’alternativa al CSMA/CD è definire criteri diversi
per accedere al mezzo trasmissivo. Esistono due categorie:

1) Time Division Multiple Access (time- triggered, dipende dal tempo)


2) Carrier Sense Multiple Access /Collision Resolution (event-triggered, dipende da un evento)

TIME DIVISION MULTIPLE ACCESS(TDMA)


L'accesso al mezzo trasmissivo è regolato da una tabella che definisce quando un nodo ha il diritto di accedere al mezzo
e di trasmettere messaggi. L’intervallo di tempo viene suddiviso in finestre temporali di durata fissa (o slots) durante le
quali un nodo può scrivere o leggere sequenze di messaggi. La sequenza si ripete ad intervalli di tempo consecutivi. Un
certo numero di slot definisce un TDMA round.
Per garantire il rispetto del protocollo è necessario che i sistemi Real time in rete attraverso il canale trasmissivo siano
sincronizzati sullo stesso clock.
CAN (Controller Area Network)
Il CAN è un bus seriale di comunicazione dati progettato per applicazioni real-time. Alcune caratteristiche:

• Si parla di CAN se è necessario un alto livello di affidabilità e sicurezza


• Permette alle varie parti del sistema di comunicare con bassi costi, facilità di
configurazione, diagnosi dei gesti, affidabilità, velocità e sicurezza.
• La comunicazione si basa sul meccanismo broadcast, i pacchetti non hanno
indirizzi. Il contenuto del messaggio è identificato univocamente da
identificatore, che ne definisce anche l’importanza.

La specifica CAN prevede due parti:

A. Formato per soli messaggi standard


B. Formato per messaggi standard ed estesi

Un’implementazione CAN per essere compatibile con la specifica CAN 2.0 deve essere compatibile con una delle due
parti; inoltre, una compatibile con la parte A può comunicare con una compatibile con la B se non vengono usati
messaggi estesi.

PARTE A, costituita da:

• Livello Object, decide quali messaggi trasmettere/ricevere dal/al “transfer


layer” e di fornire un’interfaccia all’ “application layer” (interfaccia livello
superiore)
• Livello Transfer, si occupa del protocollo di trasferimento. Fornisce i messaggi
ricevuti dal “livello object” ed accetta i messaggi da trasmettere al “livello
object”
• Livello Fisico, si occupa dell’effettivo trasferimento di bit (tutti i nodi della
rete hanno lo stesso livello fisico)

PARTE B

• Livello Data Link, diviso in


o Logical Link Control (LLC) decide quali messaggi ricevere e fornisce
servizi per il trasferimento dati
o Medium Access Control (MAC) si occupa del protocollo di trasferimento
(arbitrazione, segnalazione e gestione errori, …)
• Livello Fisico, si occupa del trasferimento di bit(tutti i nodi della rete hanno lo
stesso livello fisico)àp

LIVELLO 1 – PHYSICAL LAYER

La velocità di trasmissione dipende dalla distanza.


Il bus può trovarsi in due stati: Dominante (0 Logico) o Recessivo (1 Logico). I due stati corrispondono a tensioni
elettriche che dipendono dal livello fisico adottato. Il livello fisico definisce le tensioni elettriche, lo schema dei bus,
l’impedenza dei cavi, ecc. Tale livello viene definito dagli standards ISO 11898 e ISO11519

LIVELLO 2 – DATA LAYER

Comunicazione di tipo broadcast. I pacchetti non contengono indirizzi ma un identificatore che ne specifica anche la
priorità. Tutti i nodi ascoltano e filtrano solo quelli di interesse.
Arbitrato bit-wise: Tecnica secondo la quale, se un nodo trasmette il bit recessivo sul bus e, contemporaneamente, un
altro nodo trasmette quello dominante. il primo, leggendo il bit dominante, capirà di avere priorità minore e terminerà
la sua trasmissione.

il nodo A trasmette il bit recessivo sul bus libero

Dato che il bit trasmesso dal nodo A non ha ancora


raggiunto B, quest’ultimo crede che il bus sia ancora
libero e trasmette il bit dominante.

Quando il nodo A riceve il bit dominante trasmesso da B,


capisce di aver priorità minore e si ritira dalla
competizione. Il nodo B continua la trasmissione.

ESEMPIO: Immagino di avere tre nodi ognuno dei quali cerca di


scriver un messaggio, tutti nello stesso istante. Il CANbus prevede
un orologio che scandisce i messaggi. Tutti i nodi possono iniziare
a scrivere messaggi ad intervalli di tempo predefiniti (es. 1 ogni
ms perché ci impiegano quel tempo ad essere trasmessi,
differente dall’approccio con TMDA). All’inizio della trasmissione
viene inviato un bit di controllo. Ogni codifica ha una priorità
diversa. tutti trasmettono il bit 0, tutti scrivono esattamente lo
stesso bit e quello che si trova sul bus trovano quello che hanno
scritto. fino all'istante 5. il nodo 1 vuole scrivere 1 mentre 2 e 3
scrivono 0. 0=dominante 1=recessivo. chi trasmette il valore 1
perde. il nodo che perde la competizione smette di trasmettere. Il risultato è che il nodo 2 con il messaggio più
importante ha la garanzia che arriva a destinazione. un messaggio con tanti 0 sarà più importante con quello di tanti 1.
Tipi di messaggi

• Data Frame, messaggi che contengono dei dati


• Remote Frame, messaggi inviati per sollecitare la trasmissione del corrispondente Data Frame
• Errore Frame – rilevamento errori messaggio
1. CRC (Cyclic redundancy Check): la sequenza CRC, contenuta all’interno di ogni messaggio, è il risultato di
opportuni calcoli effettuati dal trasmettitore. Ogni ricevente calcola la sequenza CRC nello stesso modo
con cui è stata calcolata dal trasmettitore. Se la sequenza CRC calcolata non corrisponde a quella
ricevuta nel messaggio, viene segnalato un CRC Error.
2. Frame Check: questo meccanismo controlla la struttura del frame trasmesso, verificando il formato e la
dimensione dei campi. Eventuali errori vengono segnalati come Format Errors.
3. Acknowledgment Check: ogni nodo che ha ricevuto correttamente il messaggio, sovrascrive il bit di
acknowledgement con un bit dominante. Nel caso in cui il trasmettitore non rileva alcun riscontro al
frame appena inviato, viene segnalato un ACKerror.
Rilevamento degli errori (bit)

• Monitoring: il trasmettitore monitora il messaggio trasmesso, se legge un bit diverso da quello trasmesso,
genera un Bit error.
• Bit-stuffing:
o Dopo 5 bit della stessa polarità il trasmettitore aggiunge un bit della polartà opposta, il lettore farà il
contrario togliendo il bit
o Se il lettore vede più di 5 bit uguali consecutivi si genera uno Stuff error
o Quando uno o più errori vengono individuati da almeno una stazione usando questi meccanismi, la
trasmissione viene interrotta e viene inviato un Error Flag. Quest’ultimo è costituito da 6 bit dello stesso
segno e viola volontariamente la regola del “bit stuffing”, in modo che tutte le altre stazioni rilevino un
errore e spediscano anch’esse un Error flag. Questa procedura evita che altre stazioni accettino il
messaggio e quindi assicura la consistenza dei dati lungo la rete
o Dopo la trasmissione di un messaggio errato, che è stato abortito, il trasmettitore automaticamente
ritenta la trasmissione (‘ritrasmissione automatica’), eventualmente entrando in competizione con altre
stazioni per l’accesso al bus.

TTP CAN (Time Triggered Protocol CAN)


La comunicazione dipende da una temporizzazione predefinita al momento della progettazione del Sistema. L’accesso al
mezzo trasmissivo è conflict free (senza conflitto). Strategia TDMA (Time Division Multiple Access). Ad ogni nodo sono
associati specifici slot temporali, durante i quali vengono trasmessi i messaggi.
Ogni TTPCAN possiede un MEDL (Message Descriptor List) in cui ci sono racchiuse tutte le informazioni temporali
relative alla trasmissione o ricezione di ogni singolo messaggio.

9 - DDS
L'espressione publisher/subscriber si riferisce a un design pattern o stile architetturale utilizzato per la comunicazione
asincrona fra diversi processi, oggetti o altri agenti. Per la sua natura di integrazione tra diverse sorgenti software, il
pattern publisher/subscriber può essere considerato un middleware.
In questo schema, mittenti e destinatari di messaggi dialogano attraverso un tramite, che può essere
detto dispatcher o broker. Il mittente di un messaggio (detto publisher) non deve essere consapevole dell'identità dei
destinatari (detti subscriber); esso si limita a "pubblicare" il proprio messaggio al dispatcher. I destinatari si rivolgono a
loro volta al dispatcher “abbonandosi” alla ricezione di messaggi. Il dispatcher quindi inoltra ogni messaggio inviato da
un publisher a tutti i subscriber interessati a quel messaggio.
Questo schema implica che ai publisher non sia noto quanti e quali siano i subscriber e viceversa.

il DDS è un servizio che fornisce uno spazio astratto dove le applicazioni possono autonomamente e in maniera
asincrona leggere e scrivere dati godendo di un disaccoppiamento temporale e spaziale (significa che ciascun
applicazione si sincronizza con le altre solo quando ha bisogno di comunicare con le altre, ma per il restate tempo
rimane indipendente).

Il Data Distribution Service for Real Time Systems (DDS) è uno standard che definisce un middleware per la
distribuzione di dati in tempo reale secondo il paradigma publish/subscribe.

Il DDS è un middleware per sistemi distribuiti, il cui funzionamento è basato sullo scambio di dati in tempo reale da più
sorgenti a più destinazioni. I vantaggi dell'uso di DDS in questo dominio sono i seguenti:

• Accoppiamento lasco tra entità e semplicità d'uso grazie all'uso del paradigma publisher/subscriber nella
variante topic-based;
• Architettura flessibile ed adattabile grazie al discovery automatico;
• Efficienza grazie alla comunicazione diretta tra publisher e subscriber;
• Determinismo nella consegna dei dati;
• Scalabilità elevata come conseguenza dell'accoppiamento lasco tra entità;
• Qualità di Servizio altamente parametrizzabile;
• Indipendenza dalla piattaforma
Rappresenta le applicazioni Insieme di oggetti
Insieme di oggetti che partecipano alla DataReader responsabili
DataWriter responsabili comunicazione collettiva della ricezione dei dati
dell’informazione

Il subscriber si
sottoscrive
all’argomento cui è
interessato

Applicazioni per scrivere


dei dati di un particolare
topic

Applicazioni per leggere


i dati riguardanti uno
specifico topic

DataWriter
Punto di accesso per la pubblicazione di dati all'interno di un topic. Il DataWriter viene creato a partire da un Publisher,
il quale a sua volta è associato univocamente ad un Topic. E’ un entità tipizzata che viene utilizzata per produrre
campioni di una o più istanze di un Topic con determinate regole.

DataReader
Punto di accesso per la ricezione di dati all'interno di un topic. Come il DataWriter, anche il DataReader è una entità
astratta che viene resa concreta tipizzando la sua interfaccia con il tipo di dato corrispondente al topic a cui il
DataReader si riferisce.

DATA CENTERED PUBLISHER AND SUBSCRIBER (DCPS)

è il livello inferiore di DDS che definisce le entità, i ruoli, le interfacce e le policy di QoS per la piattaforma
publish/subscribe, nonché le tecniche di discovery dei partecipanti alla comunicazione. DCPS rappresenta in sostanza la
parte dello standard relativa alla comunicazione di rete.

Le applicazioni semplicemente ricevono e mandano dati con una standard API e il DDS si occupa quindi
dell’instradamento, la conversione, la ricezione e degli errori.

Il DataWriter alla creazione è generalmente legato ad un singolo Topic, mentre il DataReader può essere legato a uno
o più Topic (ContentFilteredTopic o MultiTopic).

Topic = definisce una classe d’informazione, è l’argomento. Esso è composto da:

• Nome = identifica il topic


• Type = è il linguaggio di programmazione associato al Topic
• Qos = è la qualità del servizio, parametri che definiscono come avviene la comunicazione

Qos (Durabilità) = definisce se e come le istanze di un topic sono salvate. Tipologie di durabilità:

• Volatile, nessuno storico salvato


• Transient, storico salvato nella memoria locale
• Persisent, storico salvato nell’archivio permanente
Qos (Affidabilità) = il messaggio deve essere recapitato, se non riesce riprova e riinvia più volte.

Keys = quando dichiariamo un publisher creiamo una coda (se il publisher scrive). Ci possono essere diverse code per un
topic e un subscriber può voler topic diversi.

• Qos: History (Last or All)


• Qos: Deadline
• Qos: LIveliness
• Qos: Time_Based_Filter
• Qos: Ownership
• Qos: Ownership_stregth
• Qos: Destination_Order
• Qos: Latency_Budget
• Qos: Resource: Limits
• Qos: User_Data
• Qos: Partitions

11 – MODELLO SISTEMA RT

Per processori (esempio dei server) si intendono le risorse attive. Due processori si definiscono dello stesso tipo se
funzionalmente identici e possono essere scambiati tra loro. Vengono definiti con la lettera maiuscola P1, … , Pn .

Per Risorse si intendono le risorse passive, necessarie per l’avanzamento dell’applicazione e non sono caratterizzate da
una velocità (a differenza dei processori). Si rappresentano con la lettera maiuscola R (1 … n). Le risorse possono essere:

• Riusabili: rese nuovamente disponibili dopo l’uso


• Consumabili: Scompaiono dopo l’uso
• Abbondanti: Sono quelle trascurabili

Coda di attesa
È il buffer dove sono conservati tutti i job pronti per la propria
esecuzione. Questa coda è gestita attraverso un algoritmo di
scheduling che si occupa di ordinare la coda. Ogni volta che si
attiva un job, la coda viene riordinata.

Modalità di attivazione
I task vengono attivati seguendo due modalità:

• Time driven per i task periodici, quando il processo viene attivato ad intervalli regolari
• Event driven per i task aperiodici, quando il processo viene attivato all’arrivo di un evento o mediante una
primitiva di attivazione. (i task sporadici sono dei task aperiodici che si presentano a intervalli non regolari ma di
cui sappiamo la ripetizione statistica)

Preemption
È una sospensione dell’esecuzione di un job per cedere il processore ad un job più urgente. La sua esecuzione può
riprendere alla fine dell’esecuzione del task a priorità maggiore. Un job può dunque essere preemptable se la sua
esecuzione può essere interrotta in un qualsiasi istante o non-preemptable se all’interruzione della trasmissione la
frame viene scartata e rinviata. Tale tecnica necessita il salvataggio dello stato prima del cambio di contento (context
switch) e questa operazione richiede del tempo.
Schema dei task RT

• ri release time istante di attivazione del processo, quando il job diviene disponibile per l’esecuzione
• si start time (activation time) istante in
cui il processore estrae il task dalla coda
dei processi pronti e lo esegue
• fi finishing time instante in cui finisce
l’esecuzione del task
• di deadline assoluta istante entro la quale
il task deve concludersi
• Di deadline relativa intervallo di tempo dall’attivazione del task alla sua deadline
• Ci execution time tempo di esecuzione stimato (caso peggiore)

Altri parametri

• Tardiness è il ritardo nel completamento del job


rispetto alla deadline
• Residuale wcet indica quanto manca per il termine
dell’esecuzione
• laxity (slack) è il margine di sicurezza
• Response Time tempo di risposta
• Lateness è la differenza tra il tempo di completamento e
la deadline. A differenza della tardiness può avere valori
negativi. Anche I valori negativi possono degradare le
prestazioni.

Jitter è la variazione temporale di un evento periodico

• Finishing-time jitter = f – r

• Start-time jitter = s – r

• Completition-time jitter = f – s

Criteri di ottimalità
Sono dei criteri che ci informano della qualità del sistema

1
• Tempo medio di risposta: 𝑅̅ = 𝑛 ∑𝑛𝑖=1(𝑓𝑖 − 𝑟𝑖 )
• Tempo di completamento totale: 𝑡𝑐 = 𝑚𝑎𝑥(𝑓𝑖 ) − 𝑚𝑖𝑛(𝑟𝑖 )
• Fattibilità
• Avarage response time: tempo medio di risposta di un gruppo di jobs
• Miss rate: percentuale di jobs che non rispettano la deadline
• Loss rate: è la percentule di jobs scartati perché non possono soddisfare la deadline
• Invalid rate: somma della miss rate o della loss rate

Parametri funzionali
Criticità di un job: è l’importanza del risultato prodotto dal task. I task più critici devono essere completati prima della
loro deadline anche a discapito di quelli meno critici. È un valore numerico positivo che esprime l’importanza rispetto ad
altri tasks. È molto importante nel caso di sovraccarico (overhead), quando non si possono rispettare tutte le deadline.
Esecuzione opzionale di un job: Si può strutturare un’applicazione in modo che alcuni job o porzioni di job siano
opzionali, cioè possono essere sacrificati senza pregiudicare le funzionalità del sistema.

Hard & Soft deadline


Il mancato rispetto di una deadline è una deadline miss, si può trattare di:

• Hard deadline: la deadline miss porta ad un guasto fatale con conseguenze disastrose
• Soft deadline: è indesiderabile ma tollerabile

L’efficienza di un sistema viene espressa in misura quantitativa (p) e con il ritardo di completamento (tardiness t)

L’importanza può
L’importanza del diventare nulla nel
risultato si annulla tempo
molto velocemente

Si parla per lo più di hard deadline quando il progettista deve dimostrare che il job rispetta sempre la deadline nelle
condizioni specificate.

• Un sistema è definito hard real time se una parte significativa delle deadline è di tipo hard. Questi sistemi
devono tipicamente gestire task velocemente e richiedono SO specializzati
• Un sistema viene invece definito soft real time se i job hanno deadline di tipo soft.

Schedulazione
Uno schedule è un preciso ordine di assegnamento del processore ai job.

Context switch

Time slice

Assunzioni semplificative: utilizziamo un singolo processore; gli insiemi di task sono omogenei; la task è preemptive;
non ci sono vincoli di precedenza; non ci sono vincoli sulle risorse.
Schedule con preemption
Uno schedule valido deve soddisfare le seguenti condizioni:

• Ogni processore è assegnato a non più di un job alla volta


• Ogni job è assegnato a non più di un processore alla volta
• Nessun job è schedulato prima del suo release time
• L’ammontare complessivo di tempo di CPU (processore) assegnato ad un job è uguale al suo tempo di
esecuzione
• Tutti i vincoli di precedenza e di utilizzo delle risorse devono essere soddisfatti

Feasible schedule
Uno schedule valido è feasible se ogni job completa la sua esecuzione entro la sua deadline. Un insieme di job è
schedulabile rispetto ad un dato algoritmo di scheduling se l’algoritmo produce sempre uno schedule feasible. Un
algoritmo di scheduling hard real-time è ottimo se l’algoritmo produce sempre uno schedule feasible quando l’insieme
dato di job ha uno schedule feasible. Quindi, se un algoritmo ottimo non trova uno schedule feasible per un dato
insieme di job, allora si può concludere che l’insieme di job non è schedulabile da alcun algoritmo.

Valore di utilizzo: Totale tempo schedule/tempo occupato

VINCOLI DI SCHEDULAZIONE

Vincoli temporali di un job. Un’operazione non deve iniziare prima del suo release time e non deve terminare dopo la
sua deadline. Due tipi di vincoli:

• Vincolo di consistenza temporale: stabilisce che per ogni attività (Job) una operazione può iniziare quando la
precedente è terminata.
• Vincolo di consistenza delle risorse: stabilisce che una data risorsa può eseguire una sola operazione alla volta.
In effetti, ogni attività richiede l’utilizzo esclusivo delle risorse.

Per avere consistenza dei dati è dunque necessario introdurre la mutua esclusione delle risorse, ma questo introduce
anche dei ritardi.

Grafo di precedenza
Ci permette di studiare ed osservare i vincoli di precedenza tra i job di un task. Ji precede Jk e Jk non può iniziare la
propria esecuzione finché Ji non è terminata.

• Un insieme di grafi di precedenza per diversi task si chiama task graph. Consente di rappresentare vari tipi di
relazioni.
• Data dependency: esprime la relazione che il job jk consuma i dati prodotti dal job ji. Al collegamento si associa il
parametro che rappresenta il volume di dati scambiati
• Temporal distance: esprime il vincolo tra i tempi di completamento di due job (es. tra video e audio)

• AND precedence constraints

• OR precedence constraints

• Conditional branches
• Pipeline relationship
è una dipendenza tra i due job Produttore-Consumatore

Vincoli temporali effettivi


I vincoli temporali possono essere non consistenti con i vincoli di precedenza. Nel caso di uniprocessore si usano i vincoli
temporali effettivi.
I vincoli temporali effettivi sono consistenti con i vincoli di precedenza.

12 – ALGORITMI DI SCHEDULAZIONE

Classificazione degli algoritmi

• Statici: le decisioni di scheduling dipendono da parametri fissi, assegnati staticamente ai task prima
dell’attivazione.
• Dinamici: le decisioni di scheduling dipendono da parametri che variano nel tempo.
• Online: Le decisioni sono prese in tempo reale quando un nuovo task entra nel sistema o termina
• Offline: L’algoritmo è usato sull’intero set di tasks prima della sua esecuzione. Lo schedule viene memorizzato
• Garantiti: I task sono garantiti e rispettano la loro deadline. Nuovi task vengono accettati solo se l’intero sistema
rimane garantito
• Best effort: Le deadline sono rispettate quanto è possibile e i nuovi task vengono sempre accettati

Algoritmi di scheduling

• Ottimi: Garantiscono di trovare uno schedule fattibile se esiste e, in base ad una metrica, trovare il migliore
schedule
• Euristici: Tendono a fornire buoni risultati senza però garantirne l’ottimalità
• Chiaroveggenti: Conoscono in anticipo gli istanti di arrivo dei tasks

Approcci di scheduling

• Clock-driven (o time driven): le decisioni di scheduling sono prese in istanti precisi di tempo (scelti a priori)
• Priority-driven: Le decisioni vengono prese quando avvengono particolari eventi nel sistema

Clock driven
C’è un istante di scheduling, istante in cui lo scheduler decide quale job eseguire come prossimo (questi istanti sono
definiti a priori). Quando i parametri dei job sono noti a priori la schedule può essere precalcolata e salvata in una
tabella (table driven). Negli istanti di scheduling lo scheduler può usare la priorità per la sua decisione.

Priority driven
Il processore non resta mai inattivo, è chiamato anche (approcci differenti)

• Greedy scheduling : perchè l’algoritmo cerca di prendere decisioni ottimali localmente. Non fa mai attendere un
job che può essere mandato in esecuzione (questo approccio non è sempre il migliore).
• List scheduling : perchè ogni algoritmo priority-driven può essere implementato inserendo i job pronti per
l’esecuzione in una lista ordinata per priorità dei job.

ALGORITMI CLOCK-DRIVEN

Questo approccio è applicabile quando il sistema è basato principalmente su task periodici e deterministico e, al più,
gestire alcuni task aperiodici o sporadici.
Modello
n task periodici con n fisso, i parametri sono noti a priori, i job aperiodici vengono rilasciati a istanti non prevedibili.
L’insieme dei task è caratterizzato da un iperperiodo H, da una utilization di un task e da una total utilization che è
somma di tutte le utilization.

Siccome tutte le caratteristiche sono note a priori è possibile definire offline lo schedule usando algoritmi più o meno
complessi. Lo schedule verrà memorizzato in una tabella (tk, T(tk)). Alcuni intervalli potrebbero risultare inutilizzati dai
task periodici e possono essere usati per eseguire quelli aperiodici.

Frames

Per mantenere la tabella piccola dividiamo la linea del tempo in frame ed effettuiamo le decisioni di scheduling solo in
prossimità della fine di uno di quest’ultimi. Ciascuna schedule principale è suddivisa in una o più schedule secondarie (o
frames). Durante un frame viene eseguita una sequenza di job, se questa termina in anticipo il processore attende
inattivo o esegue job in background fino alla fine dell'intervallo dl tempo Impostato. Se non viene completata in tempo
si verifica un errore di frame overrun. Alla fine di ogni frame vengono prese decisioni riguardo i job da eseguire ed altre
operazioni di monitoring. Le funzioni di un frame sono:

• gestione del temporizzatore


• dispatching deg job
• abilitazione all'esecuzione dl job ln background
• verifica del rispetto delle deadllne
• gestione di errori ed eccezioni

Per quanto riguarda le dimensioni, un frame deve essere abbastanza lungo da contenere interamente ogni singolo job,
ln modo da non doverlo interrompere, ma anche abbastanza piccolo da essere contenuto tra il release time e la
deadline di ogni Job, Inoltre deve essere divisore intero lunghezza dell'iperperiodo. Tale scelta evita la preemption,
minimizza la lunghezza totale dello schedule, assicura che ogni iperperiodo ospiti un numero intero di frame e consente
verificare il rispetto delle deadline. Nel caso i parametri dei task non consentano di soddisfare tutti vincoli
simultaneamente si suddividono i task in sotto-task.

Costruzione di uno schedule ciclico


Tre decisioni fondamentali: scelta della dimensione di un frame, porzionamento dei job in sotto-job e allocazione dei
sotto-job nei frame.
Queste decisioni non sono indipendenti tra di loro.

Mescolare job periodici e aperiodici


Supponiamo di gestire due code diverse per i job periodici e quelli aperiodici.
I job aperiodici sono quelli che tipicamente sono delle risposte ad eventi esterni, che vengono schedulati in intervalli
non utilizzati non utilizzati dai job periodici.
Generalmente avrebbe senso eseguire prima i processi hard real-time e dopo quelli aperiodici, ma questo
aumenterebbe il loro tempo di risposta. Ricordiamo che non è importante completare in anticipo il task real-time, ma
basta che finisca entro la deadline.

Slack stealing
Consiste nell’esecuzione dei job aperiodici prima di quelli periodici, quando possibile.

Chiamando slack time la differenza di tempo tra la dimensione del frame e il tempo in cui è utilizzato da job periodici,
quando sono presenti alcuni di questi nell'apposita coda possiamo attivarli immediatamente per una quantità di tempo
pari allo slack time del frame in cui si trova, nel caso in cui non terminino entro tale intervallo di tempo, l'ultimo job
aperiodico in esecuzione viene riposto in coda fino al prossimo slack time e si passa ad eseguire i consueti job periodici. l
Lo slack time di ciascun frame deve essere precalcolato e memorizzato, l'executive deve tener traccia del tempo
dedicato ai job aperiodici ed aggiornare lo slack time disponibile ed occorre un timer da settare allo slack time
disponibile all'inizio del frame.

Job sporadici
Non hanno né un’attivazione irregolare e né una regolare. Il tempo che intercorre tra uno e l’altro non è noto poiché
hanno istanti di rilascio e tempi di esecuzione non prevedibili, mentre lo è solo il tempo massimo di esecuzione.
Essi richiedono un test di accettazione: è accettato soltanto se non compromette la schedulabilità dei job periodici.

All’aumentare dei job sporadici il sistema diventa sempre più complesso e perde i vantaggi di semplicità caratteristici di
un algoritmo clock-driven.

Approccio clock-driven: vantaggi & svantaggi


Vantaggi: predicibilità, semplicità, assenza di preemption.
Svantaggi: Rigidità, difficoltà di modifica e manutenzione.
13 – PRIORITY DRIVEN NON RT

Classificazione dei processi


Associamo un periodo p ad ogni task T

• Processi periodici: p è il tempo esatto tra il rilascio dei job


• Processi sporadici: p è il tempo minimo tra il rilascio dei job
• Processi aperiodici: vengono rilasciati a tempi arbitrari, i processi non hanno deadline

I task aperiodici e sporadici hanno tempi tra uno e l’altro non noti a priori e possono risultare anche brevi. In
particolare i job sporadici hanno tempi di interarrivo modellati da variabili stocastiche.

Scheduling prioritario
Ogni processo ha una priorità compresa tra 0 e 255 (espresso con un numero naturale). Il processo che verrà
selezionato dalla coda è quello con priorità più alta. I processi a pari priorità sono serviti con politica FCFS (First Come
First Served). Lo scheduling può essere: preemptive, statico/dinamico, online

Approccio priority-driven
In uno schedule priority driven non preemptive le decisioni sono prese solamente quando il processore diventa libero o
un job diventa pronto e il processore è libero per eseguirlo

Una tipologia di approccio è preemptive

1. Assegna la priorità ai job


2. Prende le decisioni di scheduling quando un job diventa pronto, il processore diventa libero oppure le priorità
dei task cambiano
3. In ciascun istante di scheduling viene scelto il job a priorità più elevata

Priorità in basa alla release time: FIFO (FCFS), LIFO


Priorità in base al tempo di esecuzione: SETF (Shortest Execution Time First), LETF (Longest Execution Time First)

First Come First Served (non RT)


Assegna la CPU ai task in base ai loro tempi di arrivo. Tale
algoritmo è non preemptive, dinamico, Online, Best effort.
Imprevidibilità: I tempi di risposta dipendono dai tempi di
arrivo, in base all’ordine di arrivo dei task si hanno diverse
situazioni.

Shortest job first (non RT)


Selezione il job con il tempo di calcolo più corto. Tale algoritmo è: non preemptive, statico, online/offline, Minimizza il
tempo di risposta medio.
Purtroppo non è la scelta migliore di scheduling in un sistema real-time poiché vi sono combinazioni positive
1 1
NOTA: 𝑝𝑖 ∝ 𝐶 è 𝑆𝐽𝐹. 𝑆𝑒 𝑝𝑖 ∝ 𝑟 è 𝐹𝐶𝐹𝑆
𝑖 𝑖

Problema: Utilizzando lo scheduling prioritario è facile trovarsi di fronte alla problematica di starvation (i task a bassa
priorità vengono sempre superati e non vengono messi in esecuzioni)
Soluzione: Si risolve usando la teoria di aging (la priorità sale col tempo di attesa)

Round Robin (non RT)


La coda di ready è gestita con FCFS, ma ogni job, indipendentemente dalla durata, non può eseguire per più di Q unità di
tempo (Q: quanto di tempo).
Esaurito Q il job τ𝑖 viene reinserito nella coda dei processi pronti. Un Q troppo piccolo causerebbe un enorme spreco di
tempo utile in quanto è necessario del tempo per la memorizzazione dello stato del job prima del context switch e
questo richiede un tempo non trascurabile in confronto al tempo del quanto Q.

Multi Level Scheduling


Possiamo avere anche diverse code di attesa con differenti tecniche di scheduling

Anomalie di scheduling
Teorema di Graham: si possono verificare situazioni per cui, aumentando una caratteristica che migliorerebbe lo
scheduling si ottiene l’effetto opposto. Ad esempio aumentando il numero di processori, diminuzione dei tempi di
esecuzione e le rotture dei vincoli di precedenza.

14 – PRIORITY DRIVEN (RT)

A differenza di quelli non RT gli algoritmi Real Time vanno a vedere i job più urgenti in base alla loro deadline.
I task possono essere schedulati in base alla deadline relativa e alla deadline assoluta.

Earliest Due Date (statico)


Seleziona il task con la deadline relativa più corta

• Tutti i task arrivano simultaneamente


• Le priorità sono fisse (Di è nota in anticipo)
• La preemption non è un problema (le priorità sono fisse e anche l’ordinamento)
• Minimizza la massima lateness (distanza tra di e f)

Ricordiamo che se la lateness massima (ritardo massimo) è minore di zero allora tutte le deadline sono rispettate
Per vedere se un insieme di task è fattibile con EDD si fa il test

𝑖 𝑖

∀𝑖 ∑ 𝐶𝑘 ≤ 𝐷𝑖 𝑐𝑜𝑛 𝑓𝑖 = ∑ 𝐶𝑘
𝑘=1 𝑘=1
Earliest Deadline First (dinamico)
È un dynamic priority algorithms, la priorità di un job è in base alla deadline assoluta, in ciascun istante esegui il job con
la deadline più prossima.
Se due task hanno la stessa di allora si sceglie in maniera random

• I task possono arrivare in un qualsiasi istante


• La priorità è dinamica
• I task sono preemptive
• Minimizza la lateness massima

∀𝑖 ∑ 𝑐𝑘 (𝑡) ≤ 𝑑𝑖 − 𝑡
𝑘=1

Teorema di Ottimalità di EDF: in un sistema monoprocessore con preemption, EDF può genera uno schedule fattibile
per un insieme di Job J con istanti di rilascio e Deadline arbitrari se e solo se tale schedule esiste.

Dato un task set di tasks periodici o sporadici, con deadline relative uguali ai periodi, il task set è schedulabile con EDF se
e solo se il fattore di utilizzo complessivo è minore uguale a 1.

𝑁
𝐶𝑖
𝑈=∑ ≤1
𝑝𝑖
𝑖=1

EDF è un algoritmo ottimale nel senso che se un task set è schedulabile, allora è schedulabile da EDF. Infatti se U>1
nessun algoritmo può schedulare il task set, al contrario EDF può schedularlo e anche molti altri algoritmi.

Purtroppo presenta anch’esso degli svantaggi: ad esempio essendo dinamico non è prevedibile, ma conosciamo il suo
comportamento. Il progettista ha poco margine per gestire lo schedule. Questo algoritmo è oltretutto
computazionalmente costoso (per il context switch).

EDF è ancora ottimale quando le deadline relative sono diverse dal periodo, un primo test sufficiente è:

𝑁
𝐶𝑖
𝑈′ = ∑ ≤1
𝐷𝑖
𝑖=1

Ci sono anche altri criteri di ordinamento della priorità:

• Latest release tima (LRT): La priorità cresce all’aumentare dell’istante di rilascio e schedula i job a partire
dall’ultima deadline inserendo via via i job con istante di rilascio maggiore.
• Latest slack time first (LST): si calcola in ciascun istante t lo 𝑠𝑙𝑎𝑐𝑘𝑖 = 𝑑𝑖 − 𝑡𝑒𝑖 (𝑡)
Analogo l’algoritmo Minimum laxity first (MLF)

RIASSUNTO
Algoritmo Rate Monotonic (RM)
È un fixed-priority algorithm, assegna le priorità ai task in base ai loro periodi. Più è breve il periodo più alta è la
priorità. Queste priorità non cambieranno (statico). Si esegue un test di schedulabilità, sufficiente ma non necessario:
𝑚
1 𝑚 = 𝑛𝑢𝑚𝑒𝑟𝑜 𝑑𝑖 𝑡𝑎𝑠𝑘, 𝑚 → ∞
∑ 𝑐𝑖 ∗ 𝑓𝑖 ≤ 𝑚(2𝑚 − 1) 𝑐𝑜𝑛 { 𝑓 = 𝑓𝑟𝑒𝑞𝑢𝑒𝑛𝑧𝑎 = 1/𝑝
𝑖=1 𝑐 = 𝑒𝑥𝑒𝑐𝑢𝑡𝑖𝑜𝑛 𝑡𝑖𝑚𝑒

Al crescere del numero di task, RM fatica a trovare uno schedule fattibile.

Fattore di utilizzo = ∑𝑚 𝑚
𝑖=1 𝑐𝑖 ∗ 𝑓𝑖 = ∑𝑖=1 𝑐𝑖 /𝑝𝑖

Algoritmo deadline monotonic (DM) (statico)


Assegna le priorità ai task in base alla loro deadline relative, più piccola è la deadline più è alta la priorità.

L’assegnamento delle priorità di DM è ottimale per set di eventi indipendenti con risposte eseguite con una costate
priorità e per deadline prima o uguali alla fine del periodo.

Confronto DM e RM:

• Quando la relative deadline di ogni task è proporzionale al suo periodo, gli algoritmi RM e DM sono identici
• Quando la relative deadline è arbitraria, l’algoritmo DM è migliore, nel senso che può (a volte) produrre uno
schedule feasible quando RM fallisce.
• Quando invece l’algoritmo DM fallisce, di sicuro RM fallisce.

Confronto EDF e algoritmi a priorità fissa (RM e DM):

• Vantaggi: Non c’è bisogno di definire le priorità. EDF ha minor numero di context switch e EDF è ottimale
• Svantaggi: nel caso di EDF il mancato rispetto di una deadline produce un effetto domino, ossia anche tutti gli
altri task non rispettano la deadline, invece con FP è più predicibile cioè solo i task a priorità più bassa non
rispettano la deadline.

15 – SCHEDULING SERVERS
Un insieme di task periodici (critici, importante rispettare la deadline) possono essere schedulati con EDF o RM. Ci sono
poi task periodici non critici per una deadline ma che vanno eseguiti velocemente. Si utilizzano alcuni metodi da usare
insieme a EDF e RM (Se non specificato, EDF tratta i job aperiodici come se fossero periodici):

• Background scheduling (Scheduling in background)


Mentre i processi periodici vengono schedulati secondo un qualsiasi algoritmo di schedulazione, i job aperiodici
vengono schedulati in background ed eseguiti quando non c’è nessun processo periodico pronto o in
esecuzione. È semplice da implementare e produce sempre schedulazioni complete.
• Simple Periodic Servers (Server periodico semplice)
i job aperiodici vengono eseguiti da un algoritmo periodic server che si comporta come se fosse un job
periodico. Periodic Server = task periodico che esegue i task aperiodici. Chiamato anche polling server o poller,
un server periodico che esegue i job aperiodici 𝑇𝑝 = (𝑝𝑠 , 𝑒𝑠 ) termina quando la coda aperiodica è vuota o 𝑇𝑝 ha
lavorato per 𝑒𝑠 (il budget di esecuzione è esaurito). Una volta concluso non può tornare in esecuzione fino
all’arrivo del nuovo periodo (budget ripristinato).
Esempio: Periodic Server con RM
• Bandwidth preserving Servers (Migliorare un server periodico)
Un server periodico deve annullare il suo budget ogni volta che la coda dei job aperiodici (in quel periodo) è
vuota. Vogliamo dunque preservare il budget di esecuzione e usarlo più avanti nel periodo (Server che
preservano la banda). Alcuni esempi: Deferrable Server, Server sporadici, Server a banda totale, Server ad
utilizzo costante.
Il periodic server backlogged (si tiene salvato che ha da fare) ogni volta che la coda dei task aperodici non è
vuota o il server sta eseguendo un job. Il serve è in stato di idle (inattivo) quando non è backlogged. Il server è
eligile (eleggibile) per l’esecuzione quando è backlgged (cioè ha qualcosa da fare) e il suo budget è diverso da 0.

Questi Bandwidth preserving Servers differiscono per i tempi di reintegro e per le modalità di preservare il budget.
Come il Simple Periodic Server, lo schedule sospende la sua attività quando il budget è esaurito o ha finito i job da
eseguire, lo scheduler reintegra il budget in certi periodi.

• Deferrable server
Regola di consumo: il budget è consumato per ogni unità di esecuzione
Regola di reintegro: è risettato al max ad ogni fine periodo, il rimanente non può essere utilizzato nei prossimi
periodi.
Esempio DS con RM

Problema: Un’attività periodica ammissibile potrebbe non essere eseguita a causa di un DS a priorità più alta.
Può succedere che il job aperiodico venga eseguito per un intervallo più lungo del budget. Nel caso peggiore
viene eseguito una volta al fine del suo periodo e una volta all’inizio del successivo, cioè eseguito
ininterrottamente per due budget. Esistono altre versioni in cui ci sono regole aggiuntive per cui se un job
aperiodico si presenta alla fine del periodo viene eseguito ma poi sospeso e non può continuare nel periodo
successivo.
• Server sporadici
• TBS
• CUS

Non interessano i dettagli degli altri ma solo che esistano vari algoritmi che vanno per bene per job periodici, aperiodici
e sporadici.

16 – GESTIONE DEL SOVRACCARICO


Tipi di sovraccarico

• Overload transitorio dovuto alle eccessive attivazioni: è tipico dei sistemi event-driven a causa dell’arrivo
eccessivo e contemporaneo di più job aperiodici
• Overload transitorio dovuto alle eccessive esecuzioni: tipico sia dei event-driven che dei clock-driven, dovuto a
processi periodici e aperiodici che vengono eseguiti più volte delle aspettative
• Overload permanente in sistemi con task periodici: i ha quando il fattore di utilizzo dei task è >1

Gli overload possono essere causati da


• Un sistema progettato male
• Un malfunzionamento dei sistemi di input
• Una variazione dell’ambiente
• Eventi che arrivano simultaneamente
Cosa si può fare in caso di sovraccarico (richiesta di risorse computazionali maggiori di quelle disponibili)?
Si progetta il sistema sovradimensionato sopportando gli sprechi, oppure si accetta il problema considerando che alcuni
task possono sforare la deadline, o ancora si possono utilizzare protocolli per gestire guasti.

Definizioni

• Soft periodic task 𝜌 = 𝜆𝑐 (Frequenza di arrivo * tempo medio di esecuzione)


• Hard periodic task 𝜌 = 𝑈 = ∑𝑛𝑖=1 𝐶𝑖 /𝑇𝑖 (Fattore di utilizzo totale)
𝑔(𝑡1 ,𝑡2 )
• General RT task 𝜌 = max
𝑡1 ,𝑡2 𝑡1 − 𝑡2

Carico istantaneo
Massima richiesta del processore dal tempo attuale a tutte le deadline dei task attivi. In un certo istante si guarda se c’è
una richiesta di esecuzione maggiore della disponibilità del processo.

𝑔(𝑡, 𝑑𝑘 ) ∑𝑟 ≤𝑡,𝑑 ≤𝑑 𝑐𝑖 (𝑡)


𝜌(𝑡) = max = max 𝑖 𝑖 𝑘
𝑘 𝑑𝑘 − 𝑡 𝑘 𝑑𝑘 − 𝑡

Se il sistema è meno critico


Picchi di richiesta ma che posso accettare che qualche
stanno nella capacità del task non rispetti la deadline
sistema. A parte i picchi, la ma almeno ho un uso
richiesta di risorse è molto migliore della CPU
inferiore del 100%, ma si
utilizza solo il 30%. È dunque
uno spreco. Soddisfo però
sempre le risorse

Le assunzioni pessimiste portano ad avere un’alta predicibilità ma una bassa efficienza. Ciò comporta un grosso spreco
di risorse dunque un alto costo. È possibile trovare un compromesso con correttezza e costo del sistema sfruttando
tecniche che gestiscono le situazioni di sovraccarico per ridurre gli effetti negativi.

Un sistema nella media prevede alta efficienza e bassa predicibilità.

Le situazioni di overload possono essere gestite in due modi:

• Schedulazione value-based: i task con minore importanza vengono respinti e quelli più importanti serviti
completamente. Esempio automobile: sacrifico il livello del carburante, per tenere il controllo della frenata.
• Calo della performance: tutti i task vengono eseguiti ma con requisiti ridotti, risultato di qualità inferiore.
Esempio: un’immagine meno nitida dopo aver filtrato il rumore.

Value-based scheduling
Se ρ>1 non tutti gli schedule possono finire prima della deadline. Per evitarlo i task meno importanti vengono rigettati.
Per fare questo il sistema deve gestire i task considerando sia i limiti di tempo che i valori di importanza.
Usando gli algoritmi RM e EDF, il valore del task è determinato dal periodo e dalla deadline.

Come assegnare i valori


Ad un task t può essere assegnato un valore v in base a molti criteri, i più comuni
sono:

Vi=deadline + parametro aggiuntivo dato dal progettista


In un sistema real time, il valore di un task dipende dal suo tempo di completamento e dalla soglia critica

Maggiore ritardo,
minore valore

Mancato rispetto della deadline


porta a conseguenza catastrofiche

Schemi di scheduling tipici:

• Best effort scheduling


Tutti i task vengono sempre accettati nel sistema e la performance viene
controllata (rischio di effetto domino)
• Admission control
Ogni task è soggetto ad un test d’ammissione che mantiene il carico ≤1,
prevedendo l’effetto domino. Questo lo rende però poco efficiente

• Robust scheduling
Lo scheduling e il rigetto dei task sono controllati da due politiche
diverse: schedulati in base alla deadline e rigettati in base al valore.
In caso di completamento anticipato i task rigettati possono essere
recuperati tramite un apposito meccanismo.

Robust EDF

Politica di schedule: EDF


Politica di rigetto: Quando si rileva un overload viene rigettato il task che porterebbe il carico >1 (esempio da slide 21)
Politica di recupero: Si mantengono i task in ordine decrescente di valore e quando c’è il tempo vengono riaccettate
(esempio da slide 23)

Performance degradation
Il carico può essere ridotto non solo rigettando i task, ma dividendo i requisiti di performance

• Riducendo la precisione dei risultati


Imprecise computation
In questo modello ciascun task viene diviso in due porzioni: mandatory part, optional part.
Viene detto: fattibile se tutte le parti obbligatorie vengono fatte entro D; preciso se anche le parti opzionali
vengono fatte entro D. l’obbiettivo è minimizzare l’errore.
𝑛

𝐸𝑟𝑟𝑜𝑟𝑒: 𝜀𝑖 = 𝑂𝑖 − 𝜎𝑖 𝐸𝑟𝑟𝑜𝑟𝑒 𝑚𝑒𝑑𝑖𝑜: 𝜀𝑎 = ∑ 𝑤𝑖 𝜀𝑖 (𝑜𝑣𝑣𝑒𝑟𝑜 𝑖𝑙 𝑝𝑒𝑠𝑜 𝑖𝑛 𝑡𝑒𝑟𝑚𝑖𝑛𝑖 𝑑𝑖 𝑟𝑖𝑠𝑢𝑙𝑡𝑎𝑡𝑜)


𝑖=1
• Saltando alcuni job
Job skipping
I sovraccarichi possono esser ridotti saltando
qualche job. Alcuni sistemi tollerano i salti (se non
avvengono troppo spesso). Il progettista deve
però definire la tecnica di skipping.
Il sistema è in sovraccarico, ma i tasks possono
essere schedulabili se τ1 skippa ogni 3.
1 4
𝑈 = + = 1.17 > 1
2 6
Modello FIRM task: implementa il meccanismo di job skipping. I task vengono descritti 𝜏(𝐶𝑖 , 𝑇𝑖 , 𝐷𝑖 , 𝑆𝑖 ) con 𝑆𝑖
numero minimo di esecuzioni tra un jump e l’altro.
Ogni istanza può essere sacrificabile (blu) o non sacrificabile (rossa).
Ci sono tre regole:
o Se un’istanza blu è abortita, allora le prossime s-1 istanze devono essere rosse, cioè devono essere per
forza eseguite.
o Se un’istanza blu, sacrificabile, non viene sacrificata ma eseguita allora l’istanza successiva è blu, cioè
può essere sacrificata
o Le prime s-1 istanze di ogni task devono essere rosse, cioè eseguite per forza.

• Allungando i vincoli di tempo


L’idea è quella di ridurre il carico aumentando la deadline e/o i periodi.
Ogni task deve dunque specificare un range di valori nel quale il periodo deve essere incluso. I periodi vengono
dunque aumentati durante l’overload e vengono ridotti quando l’overload è finito

Adattamento al carico
è possibile modificare i periodi per procedere con uno schedule con U<1, passando lo schedule come se fosse flessibile.
Ci sono infiniti modi per modificare il periodo:

• Modello di task elastico


L’utilizzo del task è trattato come una molla
elastica e può essere soggetto a variazioni di
periodo
La resistenza del task ad una variazione di periodo
è controllata da una costante elastica E
(𝐶𝑖 , 𝑇𝑖0 , 𝑇𝑖−𝑚𝑖𝑛 , 𝑇𝑖−𝑚𝑎𝑥 , 𝐸𝑖 )
Con 𝑇𝑖0 il valore nominale (vale a dire che task più critici avranno una bassa elasticità e devono stare dunque
entro il tempo nominale), 𝐸𝑖 l’elasticità della molla

• Algoritmo di compressione
Durante l’overload il carico deve essere compresso fino ad arrivare ad 1.

L’idea è quella di comprimere i periodi di tutti i task. Ogni task modifica il proprio periodo in funzione della
costante elastica che indica in qualche modo l’importanza del task.

17- ACCESSO ALLE RISORSE CONDIVISE


Un task che aspetta una risorsa esclusiva si definisce bloccato su quella
risorsa; al contrario il task procederà verso la sezione critica e terrà
bloccata la risorsa. Quando un processo esce dalla sezione critica rilascia
la risorsa.
Ogni risorsa esclusiva 𝑅𝑖 deve essere gestita da un Semaforo 𝑆𝑖 , e ogni
sezione critica deve iniziare con wait(𝑆𝑖 ) e finire con signal(𝑆𝑖 ). Tutti i
processi in attesa per quella risorsa sono inseriti in una coda associata al
semaforo e ne usciranno solo in seguito al signal(𝑆𝑖 ) relativo.

Due task che devono accedere ad una risorsa condivisa devono


prenderne il diritto con il lock. Wait→ aspetto che la risorsa si liberi. Uso
la risorsa. Signal→ rilascio la risorsa in modo tale che gli altri task la possano usare.

Parte 𝐽2 che esegue normali istruzioni poi esegue alcune


istruzioni della sezione critica prendendo il lock. Poi procede
𝐽1 perché ha priorità maggiore ma poi necessita della risorsa
detenuta da 𝐽2 , 𝐽1 si interrompe e 𝐽2 finisce per poi rilasciare
il lock.
𝐽1 termina le istruzioni sulla risorsa e quelle normali.

𝐽1 , il task più urgente, è stato interrotto per un intervallo


lungo che dipende da una particolare condizione. Inversione
di priorità: 𝐽1 bloccato 𝐽3 procede

Da notare che i task dovranno comunque rispettare gli ordini di priorità, ma se un processo è entrato nella sua sezione
critica non può abbandonare l’uso della risorsa finchè non ha finito, anche se ciò implica il blocco di un job a priorità
maggiore che vuole usare la stessa risorsa. Ciò può portare a problemi anche molto seri come quello dell’inversione di
priorità: task eseguiti con priorità opposte.

Soluzione: disabilitare la preemption durante l’esecuzione delle sezioni critiche (il task che ha la risorsa non viene
interrotto finchè non finisce tutta l’esecuzione), rilascia il lock appena possibile ma blocca completamente gli altri.

Un’alternativa sarebbe quella di introdurre Protocolli di Accesso (ulteriori regole) che modificano l’assegnamento delle
priorità dei processi che causano il blocco.

• Protocollo di eredità delle priorità PIP (Priority Inheritance Protocol)


• Protocollo del limite di priorità PCP (Priority Ceiling Protocol)

Questi protocolli vengono utilizzati con priorità statiche, non EDF.

PIP – (Priorità fisse e deadline uguali al periodo)


• Assunzioni: n processi che cooperano attraverso m risorse condivise
• Idee di partenza: quando il processo 𝑆𝑖 blocca uno o più processi a priorità maggiore esso assumerà
temporaneamente la priorità più alta tra quelle dei processi bloccati
• Termini: distinguiamo tra priorità nominale P e priorità attiva p, attiva ≥ nominale

Algoritmo: i job sono schedulati in base alle loro priorità nominali, quelli con le stesse priorità seguono FCFS (First Come
First Served). Quando un job 𝐽𝑖 prova ad entrare nella sezione critica e la risorsa è bloccata da un job 𝐽𝑘 a priorità
minore, il job 𝐽𝑖 è bloccato. Quando 𝐽𝑖 è bloccato trasmette la sua priorità attiva al job 𝐽𝑘 (𝑝𝑘 = 𝑝𝑖 ). Quando finisce la
sezione critica rilascia la risorsa che viene presa dal processo con priorità più alta.

Se c’è un task che blocca un altro a priorità maggiore, il task bloccante acquisisce la priorità del task bloccato. Chi ha il
lock ha la priorità più alta in quel momento.

L’ereditarietà della proprietà è transitiva, se 1 è bloccato da 2 e 2 è bloccato da 3, allora 3 eredita la priorità 1.

𝑡2 : 𝑃(𝐽1 ) > 𝑃(𝐽3 )


𝑡3 : 𝑝(𝐽3 ) = 𝑃(𝐽3 )
𝑡3 : 𝑝(𝐽3 ) = 𝑃(𝐽3 )

Blocco diretto: un job a priorità più alta è bloccato da uno a priorità più bassa

Blocco push-throught: un job a priorità media è bloccato da un job a priorità più bassa che ha ereditato la priorità da un
job che blocca direttamente

Sezioni critiche annidate:

𝑡3 : 𝐽1 richiede il lock su una risorsa detenuta da 𝐽2 , 𝐽2 eredita la


priorità di 𝐽1 ma siccome 𝐽2 è bloccato da 𝐽3 . Quindi 𝐽3 eredita
la priorità di 𝐽2 che era di 𝐽2 . 𝐽3 priorità max.
𝐽5 : 𝐽3 rilascia il lock e ritorna alla sua priorità nominale.
𝑡6 : 𝐽2 torna alla priorità nominale
il grafico mi mostra solo l'andamento della priorità di 3
se n è il numero di processi con priorità minore di 𝐽𝑖 e m è il
numero di semafori in cui 𝜏1 può essere bloccato allora: 𝜏1 può
essere bloccato al massimo per min(n,m) sezioni critiche.

Teorema: 𝜏1 può essere bloccato al massimo una volta da ognuno dei processi a priorità più bassa. Tempi di blocco
virtuali
• P1 ha la priorità più alta, può essere bloccato direttamente dalle risorse con priorità inferiori. Da P2 sulla risorsa
A per 2 unità, da P3 su A per 3, da P3 su C per 5. Può essere bloccato su
una sola risorsa a processo, scegliendo i due casi peggiori saranno A2 e C5.
B=d(A2) + d(C3)=7
• P2 è bloccato direttamente da P3 su A per 3 o da P3 su B per 2 ma è anche
bloccato con push-throught da P3 su C per 5, perché se ipotizziamo che P3
inizi per primo e acquisisca il lock e poi P1 richiede la risorsa C, non può e
con il protocollo PIP P3 prende la priorità di P1, bloccando anche
l’esecuzione di P2. B=d(C3)=5
• P3 non può essere bloccato poiché è quello con priorità minore, dunque B3=0

Vantaggi: trasparente al programmatore e impedisce l’inversione di priorità. Svantaggi: non blocca il deadlock e il blocco
a catena.

PCP (Priority Ceiling Protocol)


• Priorità fissa
• Deadline uguale al periodo
• È una specie di PIP con test d’ingresso
• Un processo può entrare nella sua sezione critica solo se è libera e non c’è rischio di blocco a catena
• Per evitare il blocco a catena il processo può bloccarsi all’inizio di una sezione critica libera (blocco di ceiling)

Ad ogni semaforo è assegnata una priorità di ceiling uguale alla priorità del job a priorità più alta che può bloccarlo. A
un solo job è concesso entrare in una sezione critica solo se la sua priorità è più alta di tutte le priorità di ceiling dei
semafori lockati da altri Job. Questa regola non permette a un job di entrare nella sua sezione critica se ci sono semafori
lockati che potrebbero bloccarlo.

Ceiling di risorse

Ad ogni semaforo Sk è assegnato un ceiling 𝐶(𝑆𝑘 ) = max{𝑃𝑖 : 𝜏𝑖 𝑢𝑠𝑒𝑠 𝑆𝑘 }

Un processo può entrare nella sezione critica solo se 𝑃𝑖 > max {𝐶(𝑆𝑘 ): 𝑆𝑘 𝑙𝑜𝑐𝑘𝑒𝑑 𝑏𝑦 𝑡𝑎𝑠𝑘𝑠 ≠ 𝐽𝑖 }

All’inizio 𝑃3 può prendere 𝑆1 perché nessun semaforo è bloccato.


𝑡1 : 𝑃2 non può predendere 𝑆2 perché 𝑆1 con priorità 𝑃1 , massima, è bloccato e 𝑝(𝑃2 ) non è maggiore della priorità
massima tra i semafori bloccati
𝑇1 dopo avere seguito le istruzioni normali non può
prendere 𝑆1 perché la priorità di 𝑃1 non è maggiore
della priorità massima tra i semafori bloccati, è
bloccato 𝑆1 con priorità 𝑃1 (priorità 𝑃1 non è
maggiore di priorità 𝑃1 ). La regola è maggiore, non
maggiore uguale!!
Il test di ingresso evita la concatenazione, al
massimo il task con priorità massima viene bloccato
da uno solo dei task a priorità minore.

Vantaggi PCP: il blocco è ridotto solo ad un CS (???) e previene i deadlock.

Svantaggi PCP: non è trasparente al programmatore e i semafori hanno bidogno di una ceiling (nome della loro priorità).
Altro esempio su PCP:

Consideriamo tre task periodici τ1, τ2, τ3 (con priorità decrescente), i quali condividono le risorse A, B e C, con il
protocollo PCP. Cerchiamo di calcolare il tempo massimo di blocco per ogni
task, grazie alle informazioni nella tabella.

Con il protocollo PCP un task può essere bloccato al massimo per una sezione
critica durante la sua esecuzione.

• L’insieme delle sezioni critiche che può potenzialmente bloccare τ1 è


{su A per 2 unità (A2) , A3, C3}, il caso peggiore (tempo più lungo) è
dato da B1=d(C3)=5

• L’insieme delle sezioni critiche che può potenzialmente bloccare τ2 è {A3, B3, C3}, il caso peggiore (tempo più
lungo) è dato da B2=d(C3)=5

• Il task τ3 non può essere bloccato perché è il task con la priorità più bassa (può essere sono preempted per task
a priorità maggiore) B3=0

18 – ANALISI DI SCHEDULABILITA
Analisi di utilizzo RM
Per D = T c’è un test con condizione sufficiente ma non necessaria (test Liu and Laylan)
𝑁
𝐶𝑖 1 1
∑ ≤ 𝑁(2𝑁 − 1) 𝑟𝑖𝑐𝑜𝑟𝑑𝑎𝑛𝑑𝑜 𝑐ℎ𝑒 lim 𝑁(2𝑁 − 1) = 0,69
𝑇𝑖 𝑛→∞
𝑖=1

Test di legame iperbolico


Lo studio di fattibilità degli algoritmi RM può essere anche eseguito
utilizzando un approccio differente chiamato legame iperbolico. Il test
Hyperbolic Bound Test ha la medesima complessità di altri approcci più
comuni (Liu e Layland) ma è meno pessimista, permettendo dunque di
accettare task set che potrebbero venire rigettati usando gli approcci
originali.

Invece di minimizzare l’utilizzo del processore nel rispetto del periodo dei
task, la condizione di fattibilità può essere manipolata in modo di trovare un
test di schedulabilità sufficientemente stretto in funzione dell’utilizzo relativo
di ogni task.

Teorema: Dato un insieme di n task, dove ogni task 𝜏𝑖 è caratterizzato da un utilizzo del processore (fattore di Utilizzo)
𝑈𝑖 . Allora, tale insieme è schedulabile da un algoritmo RM se
𝑛

∏(𝑈𝑖 + 1) ≤ 2
𝑖=1

Test Sufficiente ma non necessario


Analisi del tempo di risposta
Tecnica che si basa su un procedimento che richiede più tempo ma si assicura una verifica esatta sulla sua schedulabilità

𝑅𝑖 = 𝐶𝑖 + 𝐼𝑖 𝑐𝑜𝑛 𝐶 𝑖𝑙 𝑡𝑒𝑚𝑝𝑜 𝑑𝑖 𝑒𝑠𝑒𝑐𝑢𝑧𝑖𝑜𝑛𝑒 𝑒 𝐼 𝑖𝑙 𝑡𝑒𝑚𝑝𝑜 𝑑𝑖 𝑟𝑖𝑠𝑝𝑜𝑠𝑡𝑎


Se 𝑅𝑖 ≤ 𝐷𝑖 allora è schedulabile, dove 𝜏𝑖 è il task con la response time peggiore. Se il task non venisse mai interrotto
avremmo che 𝑅 = 𝐶 .

Quante volte verrà interrotto un task? Dipende dal periodo dei task a priorità più alta del task trattato

𝑅𝑖
𝑁𝑢𝑚𝑒𝑟𝑜 𝑑𝑖 𝑖𝑛𝑡𝑒𝑟𝑟𝑢𝑧𝑖𝑜𝑛𝑖 𝑑𝑖 𝑖 = [ ]
𝑇𝑗

Con j task a priorità maggiore.


𝑅
L’interferenza totale è dunque data da: [𝑇 𝑖 ] ∗ 𝐶𝑗
𝑗

Equazione del tempo di risposta


𝑅𝑖
𝑅𝑖 = 𝐶𝑖 + ∑ [ ] 𝐶𝑗
𝑇𝑗
𝑗∈ℎ𝑝(𝑖)
𝑑𝑜𝑣𝑒 ℎ𝑝(𝑖) 𝑠𝑖 𝑖𝑛𝑡𝑒𝑛𝑑𝑒 𝑡𝑢𝑡𝑡𝑖 𝑖 𝑡𝑎𝑠𝑘 𝑐𝑜𝑛 𝑝𝑟𝑖𝑜𝑟𝑖𝑡à 𝑚𝑎𝑔𝑔𝑖𝑜𝑟𝑒 𝑑𝑖 𝑞𝑢𝑒𝑙𝑙𝑎 𝑑𝑖 𝑖
Si trova poi ricorsivamente

𝑅𝑖
𝑤𝑖𝑛+1 = 𝐶𝑖 + ∑ [ ] 𝐶𝑗
𝑇𝑗
𝑗∈ℎ𝑝(𝑖)

Quando troveremo 𝑤𝑖𝑛+1 = 𝑤𝑖𝑛 la soluzione dell’equazione è trovata 𝑤𝑖𝑛 = 𝑅𝑖

L’analisi del tempo di Risposta da un risultato necessario e sufficiente per garantire la schedulabilità con RM.

Se D < T allora si utilizza l’algoritmo di scheduling Deadline Monotonic e la formula rimane la stessa, si confronta Ri con
Di, invece che con il periodo come prima.

Se i task condividono risorse bisogna considerare anche il tempo di blocco di ogni task, quindi la formula dell’analisi del
tempo di risposta diventa:

𝑅𝑖
𝑤𝑖𝑛+1 = 𝐶𝑖 + 𝐵𝑖 + ∑ [ ] 𝐶𝑗
𝑇𝑗
𝑗∈ℎ𝑝(𝑖)

Potrebbero piacerti anche