Download Documentazione del progetto

Transcript
CAPITOLO 6.
SCELTE DI IMPLEMENTAZIONE DEL SISTEMA
149
essenzialmente avviene richiamando una per una le funzioni di pulizia denite dai singoli oggetti contenuti nell'oggetto principale (thmx e
thmx_gadget
rispettivamente), per poi de-registrare il modulo presso il kernel.
Essendo
coivolti diversi kernel thread per l'esecuzione, questo ha richiesto una sincronizzazione per la terminazione di tali thread. Tale sincronizzazione è stata
implementata impostando una opportuna variabile atomica da ambo i lati (thmx.disconnect_state sull'host e
thmx_gadget.running
sul gadget).
Visto che tutti i thread eseguono dei loop inniti in cui rimangono in attesa
su delle apposite
wait_queue
nché il chiamante non li sveglia, e solo allora
eseguono il proprio lavoro per poi tornare in attesa, è stato suciente inserire
dei controlli ogni volta che i thread escono dall'attesa: se è stata impostata la variabile di disconnessione del sistema, l'esecuzione può terminare. In
questo modo, il thread principale semplicemente imposta tale variabile e poi
sveglia il thread. Inne, però, la sincronizzazione è stata forzata utilizzando
delle
struct completion:
ogni volta che il thread padre risveglia un glio
per la terminazione, utilizza la funzione
wake_up_interruptible_sync()
la quale fa sì che il processo chiamante mantenga la cpu anche dopo la
chiamata a tale funzione (che comunque non è atomica).
Questo per evi-
tare che il thread glio acquisisca il processore prima che il thread chiamante non lo stia aspettando per la terminazione.
Infatti, subito dopo la
wake_up_interruptible_sync(), il thread chiamante esegue la
wait_for_completion(), attendendo così la terminazione del thread svechiamata a
gliato.
Questo, una volta risvegliato e dopo aver notato che il modulo si
trova in uno stato di terminazione, prima di uscire chiama la
che risveglia il processo in attesa di tale terminazione.
complete(),