06.+Sistemul+de+intreruperi;+Deadlocks

= CAPITOLUL 6: SISTEMUL DE ÎNTRERUPERI; DEADLOCKS  =

Un PC poate lucra cu doua tipuri de întreruperi, software şi hardware. În această lucrare vom explica numai întreruperile hardware. Într-un PC întreruperile externe sunt gestionate de un controler de întreruperi de tip 8259A. După ce circuitul 8259A primeşte un semnal de tip cerere de întrerupere pe una din liniile IRQ2 la IRQ7, el transmite un semnal pe intrarea INTR a mP-ului. Apoi 8086 transmite un semnal INTA (interrupt-acknowledge) către 8259. Astfel, microprocesorul poate obţine tipul de întrerupere de la dispozitivul extern ce a solicitat întrerupere. 8086 utilizează tipul citit de la dispozitivul extern pentru a prelua adresa procedurii de servire a întreruperii din tabelul pointerilor de întreruperi din memorie. De notat faptul ca semnalele INTR şi INTA nu sunt prezente în bus-ul ISA, aceste semnale fiind utilizate numai pentru mP şi 8259A. În cazul întreruperilor hardware, nivelul de întrerupere este determinat de o componentă de pe placa de bază, numită controler de întreruperi hardware; acesta primeşte cererea de întrerupere şi o direcţionează către UCP pe un anumit nivel de întrerupere, în funcţie de sursa care a generat-o. //Activitatea sistemului de operare pentru gestionarea resurselor sistemului de calcul// Utilizarea eficientă a unui sistem de calcul trebuie să asigure, în orice moment, executarea cât mai rapidă a unui număr cât mai mare de sarcini. Pentru aceasta este necesară asigurarea exploatării la capacitatea maximă a resurselor sistemului. Sarcinile care trebuiesc executate în sistem sunt complexe, diverse, cu un caracter aleatoriu, din punctul de vedere al naturii lor, al momentului apariţiei sau al ordinii în care se succed. Executarea acestor sarcini se realizează prin intermediul proceselor generate în sistem. Pentru coordonarea optimă a activităţii componentelor sistemului de calcul, în aceste condiţii de nedeterminare, au fost dezvoltate funcţii speciale ale sistemului de operare, cu rolul de a controla modul de desfăşurare a proceselor din sistem, funcţii care alcătuiesc componenta sistemului de operare de gestionare a resurselor sistemului de calcul. Aceste funcţii asigură înlănţuirea execuţiei proceselor într-o ordine determinată şi de contextul lor de execuţie şi alocarea resurselor solicitate de aceste procese conform unor criterii care au în vedere optimizarea modului de utilizare a resurselor. O activitate importantă pentru coordonarea execuţiei proceselor şi a alocării resurselor este activitatea de comunicare între procese şi sistemul de operare, de exemplu pentru a semnala atingerea unei anumite stări în cadrul unui proces (solicitarea unei resurse noi, încheierea utilizării unei resurse, apariţia unei erori care împiedică desfăşurarea în continuare a procesului, etc.); această comunicare este indicat să nu se realizeze prin intermediul UCP, pentru a nu încărca suplimentar această resursă critică a sistemului de calcul. Din acest motiv se utilizează o metodă de comunicare la nivel scăzut (la nivel fizic) prin intermediul sistemului de întreruperi.

6.1. Ierarhizarea întreruperilor
La un moment dat, în sistem, pot fi activate, simultan, mai multe cereri de întrerupere. Acestea sunt servite în ordinea în care apar în sistem. De exemplu: se opreşte, temporar, execuţia unei rutine de întrerupere, pentru a lansa în execuţie o altă rutină de întrerupere, apelată de o cerere de întrerupere apărută ulterior în sistem. Se poate realiza o ierarhizare a întreruperilor, prin acordarea de priorităţi de execuţie fiecărui nivel de întrerupere. În cazul ierarhizării întreruperilor, ordinea de servire a cererii de întrerupere va fi stabilită conform următoarelor principii:
 * servirea unei cereri de întrerupere poate fi întreruptă numai de o cerere de întrerupere cu nivel de prioritate mai mare;
 * întreruperile nemascabile au prioritate maximă;
 * după încheierea unei rutine de tratare a întreruperii se reia execuţia întreruptă, care poate fi a unui proces sau a altei rutine de tratare a unei întreruperi cu prioritate mai mică.

6.2. Funcţiile sistemului de întreruperi
În concluzie, sistemul de întreruperi permite comunicarea în sistemul de calcul şi sincronizarea activităţii UCP cu evenimentele externe sau interne din sistem, asigurând:
 * direcţionarea majorităţii cererilor adresate UCP, din mediul extern
 * degrevarea UCP de sarcina explorării intrărilor în sistemul de calcul, pentru a detecta sarcinile care îi revin
 * micşorarea timpului de răspuns al UCP la solicitările externe sau interne primite
 * detectarea rapidă a unor situaţii de disfuncţionalitate a sistemului, determinând astfel creşterea fiabilităţii acestuia.

6.3. Surse de întreruperi
Sursele de întrerupere identifică acele componente fizice sau logice ale sistemului care pot solicita întreruperi, în cazul apariţiei unor evenimente. Semnalele transmise pentru UCP de către sursele de întrerupere care solicită o întrerupere se numesc cereri de întrerupere (CI). În funcţie de natura surselor de întrerupere şi a evenimentelor care pot genera o întrerupere, se pot identifica mai multe tipuri de întreruperi: întreruperi hardware, generate de surse hardware, pentru evenimente externe procesului; de exemplu:
 * dispozitivele periferice pot solicita, printr-o cerere de întrerupere, servicii sau acţiuni specifice (imprimanta “anunţă” terminarea hârtiei, în timpul unei listări; unitatea de disc “anunţă” încheierea unei operaţii de citire/scriere sau apariţia unei erori în timpul unei astfel de operaţii; tastatura “anunţă” activarea sau dezactivarea unei taste, etc.)
 * dispozitivele hardware de supraveghere a funcţionării normale a sistemului de calcul pot emite cereri de întrerupere în cazul sesizării unor anomalii de funcţionare (circuitele detectoare de paritate pot semnala erori de paritate în timpul unui transfer de date, circuite specializate pot sesiza scăderea tensiunii de alimentare a sistemului, etc.)

6.4. Mecanismul de funcţionare a întreruperilor
În funcţie de sursa întreruperii, fiecare CI se identifică printr-un număr, numit nivel de întrerupere; numărul nivelelor de întrerupere disponibile în sistem este o constantă constructivă a sistemului de calcul, determinată de numărul de linii pe care UCP poate primi cereri de întrerupere. Sursele de întrerupere sunt grupate, fiecare grup având rezervat un anumit nivel de întrerupere (de exemplu, există câte un nivel de întrerupere pentru: unităţile de disc, imprimantă, tastatură, ceasul sistemului, etc.) În cazul întreruperilor hardware, nivelul de întrerupere este determinat de o componentă de pe placa de bază, numită controler de întreruperi hardware; acesta primeşte cererea de întrerupere şi o direcţionează către UCP pe un anumit nivel de întrerupere, în funcţie de sursa care a generat-o. În cazul întreruperilor software, programul care lansează o cerere de întrerupere trebuie să specifice şi nivelul de întrerupere corespunzător. Pentru fiecare nivel de întrerupere există un program de sistem specializat, numit rutină de tratare a întreruperii sau handler. Fiecărui nivel de întrerupere îi corespunde o adresă fixă în memorie, unde este memorată adresa rutinei de tratare a întreruperii respective. Toate aceste adrese fixe formează în memoria internă vectorul de întrerupere. Operaţia de executare a rutinei de tratare a întreruperii corespunzătoare unei cereri de întrerupere poartă numele de servire a cererii de întrerupere respective. Rutinele de tratare a întreruperilor sunt incluse în firmware, de exemplu în ROM-BIOS, sau în componentele sistemului de operare. Pot exista şi rutine de tratare a întreruperilor proprii unor programe de aplicaţie. Aceste rutine pot fi create fie pentru a înlocui o întrerupere standard, fie pentru a crea un nou tip de întrerupere. În consecinţă, mecanismul de funcţionare a întreruperilor presupune: Activitatea UCP poate fi întreruptă la încheierea execuţiei unei instrucţiuni maşină. La apariţia unei cereri de întrerupere, UCP execută următoarele operaţii:
 * lansarea unei cereri de întrerupere şi transmiterea ei pe un nivel de întrerupere
 * întreruperea temporară a procesului activ, cu conservarea stării sale în momentul întreruperii
 * executarea rutinei de tratare a întreruperii de pe nivelul corespunzător
 * reluarea procesului întrerupt şi continuarea lui, pornind de la starea din momentul întreruperii.
 * salvează starea procesului în execuţie, prin memorarea pe stivă a conţinutului registrului contor de program, al cuvântului de stare program şi al registrelor generale
 * acceptă întreruperea şi localizează rutina de întrerupere
 * execută rutina de întrerupere
 * reface contextul de execuţie al procesului întrerupt
 * reia procesul din punctul în care a fost întrerupt.

6.5. Utilizarea întreruperilor
Când vrem să efectuăm transferuri de date cu un port I/O putem utiliza una din următoarele două metode: Putem interoga (Polling) portul ceea ce implică citirea stării portului la intervale regulate pentru a determina dac au fost recepţionate date sau s-a modificat starea portului. Dacă da se poate apela subrutina care deserveşte portul respectiv. Este evident că interogarea portului necesită un anumit timp, timp ce ar putea fi utilizat în alte scopuri (reîmprospătarea ecranului, afişarea orei, etc). O alternativă mai eficientă o reprezintă utilizarea întreruperilor. În această situaţie procesorul poate efectua sarcinile utilizator (reîmprospătare ecran, afişări, etc) iar când portul necesită atenţia sa (recepţionarea unui caracter, schimbarea stării) va emite o cerere de întrerupere (IRQ) către procesor. Odată ce procesorul primeşte o cerere de întrerupere, îşi termină instrucţiunea curentă, salvează în stivă PC-ul (Program Counter) şi execută subrutina de tratare a întreruperilor ISR (Interrupt Service Routine), care poate aduce octetul de la portul de I/E pentru a-l depune într-un buffer. Odată încheiată subrutina de tratare a întreruperilor, procesor îşi reia execuţia de unde a rămas. Folosind această metodă, procesorul nu trebuie să mai irosească timpul interogând dispozitivele I/O, ci acestea vor întrerupe procesorul atunci când au nevoie de atenţie. Calculatorul obişnuit are doar 16 întreruperi Hardware plus una nemascabilă. Restul vectorilor de întreruperi sunt folosiţi pentru întreruperile software şi tratarea excepţiilor. Tratările de excepţii sunt subrutine asemănătoarea ISR-urilor, dar care sunt apelate atunci când apare o eroare. Un exemplu ar fi vectorul de întreruperi care conţine adresa tratării excepţiei împărţire la zero. Atunci când apare o împărţire la 0, microprocesorul încarcă adresa 0000:0000 şi începe executarea instrucţiunilor de la această adresă. Controlerul de întreruperi programabil (Programmable Interrupt Controller PIC) tratează întreruperile hardware. Majoritatea PC-urilor au două astfel de controlere situate la adrese diferite. Unul tratează întreruperile 0..7 şi celălalt pe cele de la 8 la 15, furnizând 15 linii individuale de întreruperi, cel de-al doilea controler fiind cascadat de primul prin IRQ2. În majoritatea cazurilor iniţializarea controlerului de întreruperi este făcut de BIOS, de aceea noi trebuie să avem grijă doar de două instrucţiuni. PIC ne permite mascarea individuală a întreruperilor, pentru ca acestea să nu ajungă la procesor. Aşadar, prima instrucţiune este Operation Control Word 1 (OCW1), pentru a stabili care întrerupere se maschează şi care nu. Având la dispoziţie doua PIC-uri situate la adrese diferite, trebuie mai întâi să stabilim care PIC trebuie folosit. Primul controler aflat la adresa de bază 0x20h controlează întreruperile de la IRQ 0 la IRQ 7. Cel de-al doilea PIC aflat la adresa de bazţ 0xA0h controlează întreruperile de la IRQ 8 la IRQ 15. Microprocesorul mai dispune de două linii pentru semnalele de întrerupere emise de dispozitivele externe: linia INTR (Interrupt Request) şi linia NMI (Non-Maskable Interrupt). Pe linia INTR sosesc întreruperi în urma cărora unitatea centrală, în funcţie de valoarea indicatorului de validare a întreruperilor (IF), execută diferite operaţii. Dacă IF este şters (are valoarea 0) înseamnă că întreruperile semnalate pe linia INTR sunt mascate sau dezactivate, ca urmare unitatea centrală le ignoră şi trece la instrucţiunea următoare. Dacă IF este poziţionat (are valoarea 1) înseamnă că întreruperile de pe linia INTR sunt activate şi unitatea centrală opreşte execuţia normală a instrucţiunilor şi predă controlul rutinei de tratare a întreruperilor. NMI este o linie prin care sosesc întreruperi care anunţă evenimente critice. Aceste întreruperi nu pot fi dezactivate şi unitatea centrală le va lua în considerare de fiecare dată când acestea sosesc. Sistemul de întreruperi este simplu şi uşor de manevrat. Pot fi utilizate cel mult 256 de tipuri de întrerupere, fiecărui tip fiindu-i atribuit un cod specific. Întreruperile pot fi clasificate în întreruperi externe şi întreruperi interne. Cele externe sunt numite şi întreruperi hardware, iar cele interne mai poartă denumirea de întreruperi software. Diferenţa esenţială dintre cele două tipuri de întreruperi este că cele externe sunt cauzate de dispozitivele externe, iar cele interne sunt generate prin program, folosindu-se anumite instrucţiuni. Tabela vectorilor de întrerupere permite asocierea dintre tipul întreruperii (reprezentat de un număr între 0 şi 255) şi rutina de tratare a întreruperii. Fiecare intrare a tabelei ocupă 4 bytes, ea conţinând adresa rutinei de tratare a întreruperii. Tabela ocupă prima zonă a memoriei interne şi poate avea până la 256 de intrări. La apariţia unei întreruperi este suspendată execuţia instrucţiunilor programului curent şi sunt salvate pe stivă registrul cu indicatorii de stare şi control şi adresa instrucţiunii următoare; apoi este activată rutina de tratare a întreruperii.

6.6. Gestionarea întreruperilor
Există o categorie de sarcini a căror apariţie în sistem face necesară tratarea lor imediată de către UCP; vom numi aceste sarcini evenimente. Pe de altă parte, UCP nu trebuie să afecteze timp pentru a verifica dacă a apărut o astfel de solicitare în sistem, ştiut fiind că timpul UCP este o resursă critică a sistemului de calcul. Apare astfel o problemă de comunicare de la componentele fizice sau logice ale sistemului de calcul către UCP, problemă rezolvată, în sistemele de calcul moderne, utilizând tehnica întreruperilor. Întreruperea reprezintă suspendarea temporară a execuţiei procesului care are alocată UCP, în momentul în care apare un eveniment în sistem, în scopul tratării acestui eveniment de către UCP. Pentru ca o întrerupere să fie funcţională, este necesar să poată fi îndeplinite două condiţii:
 * UCP să dispună de capacitatea de a fi întreruptă, adică să fie posibil ca UCP să fie alocată altui proces, înainte de încheierea execuţiei procesului căruia îi este alocată, la un moment dat;
 * să existe posibilitatea de a conserva parametrii procesului suspendat, pentru ca acesta să poată fi continuat ulterior, din punctul în care a fost întrerupt.

6.7. Controlul întreruperilor
În timpul executării unui proces, există anumite operaţii critice, care nu trebuiesc întrerupte. În acest scop, există posibilitatea invalidării unei CI. Controlul întreruperilor se referă la posibilitatea acordată UCP de a accepta sau nu o cerere de întrerupere. În cod maşină există două instrucţiuni complementare: Întreruperile care pot fi invalidate soft se numesc întreruperi mascabile. Există însă şi cereri de întrerupere care trebuie să genereze obligatoriu întreruperea procesului în curs, în momentul apariţiei lor. Întreruperile care nu pot fi invalidate soft se numesc întreruperi nemascabile.
 * EI (Enable Interrupt) care permite validarea unei cereri de întrerupere
 * DI (Disable Interrupt) care nu permite validarea unei cereri de întrerupere, până la o nouă instrucţiune EI. Prin intermediul acestei instrucţiuni se poate realiza invalidarea soft a unei cereri de întrerupere.