This is an old revision of the document!
Pentru parcurgerea demo-urilor, folosim arhiva aferentă. Demo-urile rulează pe Linux. Descărcăm arhiva folosind comanda
wget http://elf.cs.pub.ro/so/res/cursuri/curs-10-demo.zip
și apoi decomprimăm arhiva
unzip curs-10-demo.zip
și accesăm directorul rezultat în urma decomprimării
cd curs-10-demo/
Acum putem parcurge secțiunile cu demo-uri de mai jos.
Dorim să investigăm livrarea întreruperilor hardware către sistemul local. Vom urmări întreruperea de ceas (timer) și întreruperea de tastatură.
În Linux fișierul care afișează informații despre tastatură este /proc/interrupts
. În acest fișier sunt afișate informații statistice despre întreruperilor livrate, câte o coloană pentru fiecare procesor. În cadrul fișierului găsim informații și despre întreruperea de ceas și cea de tastatură:
$ cat /proc/interrupts CPU0 CPU1 CPU2 CPU3 0: 14 0 0 0 IR-IO-APIC-edge timer 1: 1358967 0 0 0 IR-IO-APIC-edge i8042 [...] LOC: 96023026 47877718 90900926 54219891 Local timer interrupts [...]
Prima coloană este linia de întrerupere (IRQ line
) pe care se livrează semnalul de întrerupere către procesor. Este 0 în cazul timer-ului programabil (8253) și 1 în cazul controller-ului de tastatură (8042).
Din output-ul comenzii de mai sus am selectat doar intrările referitoare la întreruperea de ceas (timer
și Local timer interrupts) și cea de tastatură (i8042
). La noi rulări ale comenzii
cat /proc interrupts
vom observa actualizări ale valorilor întreruperilor. În figura de mai sus întreruperea de tastatură (i8042
) este tratată doar pe primul procesor (CPU0
) în vreme ce există întreruperi de ceas locale pentru fiecare procesor (de unde și denumirea de local).
Pe sistemele multi-core/multiprocesor se folosesc întreruperile de ceas locale (cele indicate de Local timer interrupts). Acestea sunt livrate de controller-ul de întreruperi (APIC) către fiecare procesor în parte. Din acest motiv există actualizări pentru linia identificată de LOC:
dar nu și pentru timer-ul programabil de pe linia identificată cu timer
. Pe sisteme uniprocesor, pentru livrarea întreruperii de ceas se folosește timer-ul programabil.1)
Informațiile despre întreruperea de ceas sunt actualizate periodic în fișierul /proc/interrupts
pentru că la un interval dat se livrează o nouă întrerupere.
Întreruperile de tastatură sunt livrate la fiecare apăsare de tastă. Pentru a investiga evoluția numărului de întreruperi de tastatură livrate, tastăm șirul de comenzi de mai jos:
$ cat /proc/interrupts | grep ' 1:' 1: 1366012 0 0 0 IR-IO-APIC-edge i8042 $ echo 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa $ cat /proc/interrupts | grep ' 1:' 1: 1366184 0 0 0 IR-IO-APIC-edge i8042
Între prima afișare și a doua afișare a conținutului fișierul /proc/interrupts
am tastat circa 70-80 de taste pentru comanda echo …
și a doua comandă cat
(am mai apăsat și pe tasta Backspace când am greșit). Observăm că diferența între cele două rezultate (întreruperi livrate) este 1336184 - 1336012 = 172
. Au fost livrate circa dublu de întreruperi față de tastele apăsate. Acest lucru se întâmplă pentru că se livrează o întrerupere pentru fiecare apăsare de tastă (key press) și una pentru fiecare eliberare de tastă (key release); de unde și numărul dublu de întreruperi livrate față de taste apăsate.
Dorim să urmărim ce se întâmplă în cazul în care avem date partajate într-un mediu multithread. Pentru aceasta accesăm subdirectorul list-excl/
; urmărim conținutul fișierelor thread-list-app.c
și list.c
. Este vorba de o aplicație care lucrează cu liste înlănțuite într-un mediu multithreaded. Vom observa că există riscul ca datele să fie corupte, fiind necesară sincronizare.
Compilăm fișierele folosind make
. Rezultă două fișiere în format executabil: thread-list-app
și thread-list-app-mutex
.
Programul thread-list-app-mutex
folosește intern un mutex pentru sincronizare. Pentru aceasta folosim macro-ul USE_MUTEX
pe care îl definim în fișierul Makefile
.
Ca să urmărim ce se întâmplă cu o aplicație multithreaded cu date partajate, rulăm de mai multe ori programul thread-list-app
, până la obținerea unei erori:
./thread-list-app
Dorim să urmărim ce se întâmplă în cazul în care avem date partajate într-un mediu multithread. Pentru aceasta accesăm subdirectorul list-excl/
; urmărim conținutul fișierelor thread-list-app.c
și list.c
. Este vorba de o aplicație care lucrează cu liste înlănțuite într-un mediu multithreaded. Vom observa că există riscul ca datele să fie corupte, fiind necesară sincronizare.
Compilăm fișierele folosind make
. Rezultă două fișiere în format executabil: thread-list-app
și thread-list-app-mutex
.
Programul thread-list-app-mutex
folosește intern un mutex pentru sincronizare. Pentru aceasta folosim macro-ul USE_MUTEX
pe care îl definim în fișierul Makefile
.
Ca să urmărim ce se întâmplă cu o aplicație multithreaded cu date partajate, rulăm de mai multe ori programul thread-list-app
, până la obținerea unei erori:
./thread-list-app
Dorim să urmărim ce se întâmplă în cazul în care avem date partajate într-un mediu multithread. Pentru aceasta accesăm subdirectorul list-excl/
; urmărim conținutul fișierelor thread-list-app.c
și list.c
. Este vorba de o aplicație care lucrează cu liste înlănțuite într-un mediu multithreaded. Vom observa că există riscul ca datele să fie corupte, fiind necesară sincronizare.
Compilăm fișierele folosind make
. Rezultă două fișiere în format executabil: thread-list-app
și thread-list-app-mutex
.
Programul thread-list-app-mutex
folosește intern un mutex pentru sincronizare. Pentru aceasta folosim macro-ul USE_MUTEX
pe care îl definim în fișierul Makefile
.
Ca să urmărim ce se întâmplă cu o aplicație multithreaded cu date partajate, rulăm de mai multe ori programul thread-list-app
, până la obținerea unei erori:
./thread-list-app