Sunteți pe pagina 1din 15

Tema 9.

Sistemul de intrare/ieșire
Cuprins
 Introducere
 Principiile fizice de organizare a i/o
 Principiile logice de organizare a i/o
 Planificarea cererilor
9.1. Introducere

Funcționarea oricărui sistem de calcul se referă de obicei la două tipuri de lucrări: procesarea
informației și operațiunile de citire-criere a acesteia. Deoarece tot ce se execută într-un sistem de
calcul este organizat ca un set de procese, aceste două tipuri de lucrări sunt efectuate de procese.
Procesele sunt implicate în prelucrarea informațiilor și efectuarea operațiunilor de i/o.
Conținutul conceptelor „procesarea informației” și „operațiuni de intrare-ieșire” depinde de
punctul de vedere din care le privim. Din punctul de vedere al programatorului, „procesarea
informațiilor” se referă la executarea instrucțiunilor procesorului pe datele din memorie,
indiferent de nivelul ierarhiei - în registre, cache, memorie de acces aleatoriu sau memorie
secundară. Prin „operații de i/o”, un programator se referă la schimbul de date între memorie și
dispozitive externe memoriei și procesorului, cum ar fi casete magnetice, discuri, monitor,
tastatură, timer. Din punct de vedere al SO, „procesarea informațiilor” sunt doar operațiunile
efectuate de procesor pe datele localizate în memorie la nivel de ierarhie nu mai jos decât
memoria RAM. Toate celelalte se referă la „operațiuni de i/o”. Pentru a efectua operații cu date
localizate temporar în memoria secundară, SO le pompează mai întâi în memoria RAM și apoi
procesorul efectuează acțiunile necesare.
Înainte de a vorbi despre funcțiile SO în timpul operațiilor de i/o, este necesar să reamintim
câteva informații din cursul „Modern Computer Architecture and Assembler Language” pentru a
înțelege modul în care informațiile sunt transferate între RAM și un dispozitiv extern și de ce
conectarea noilor dispozitive la sistemul de calcul nu necesită reproiectarea SO.

9.2. Principiile fizice ale i/o

Există diferite dispozitive care pot interacționa cu procesorul și memoria: timer, hard disk-uri,
tastatură, mouse, modemuri, dispositive de intrare și afișare în simulatoare aerospațiale etc.
Unele dintre aceste dispozitive sunt încorporate în carcasa computerului, altele se află în afara
acestuia și comunică cu computerul prin diferite linii de comunicare: cablu, fibră optică, releu
radio, satelit etc. Tipul dispozitivelor și metodele de conectare ale acestora, sunt determinate de
obiectivele funcționării sistemului de calcul, dorințele și capacitățile financiare ale utilizatorului.
În ciuda diversității dispozitivelor, gestionarea activității lor și schimbul de informații cu acestea
se bazează pe un set relativ mic de principii.

Prezentare generală asupra arhitecturii computerului


În cel mai simplu caz, procesorul, memoria și numeroasele dispozitive externe sunt conectate
printr-un număr mare de conexiuni electrice - magistrale, care sunt numite magistrala locală a
computerului. Noțiunea de magistrală include nu numai un set de conductoare, ci și un set de
protocoale care definesc o listă de mesaje ce pot fi transmise prin semnale electrice prin aceste
conductoare. În computerele moderne, există cel puțin trei magistrale:
• magistrala de date, formată din linii de date și utilizată pentru a transfera informații între
procesor și memorie, procesor și dispozitive de intrare-ieșire, memorie și dispozitive externe;
• magistrala de adrese, formată din linii de adrese și utilizată pentru a seta adresa unei celule de
memorie sau pentru a indica un dispozitiv de intrare-ieșire implicat în schimbul de informații;
• magistrala de control, formată din linii de control și linii ale stării sale care determină
comportamentul magistralei locale.
Numărul de linii care alcătuiesc magistrala reprezintă lățimea de biți (lățimea) ei. Lățimea
magistralei de adrese, de exemplu, determină dimensiunea maximă a memoriei RAM care poate
fi instalată într-un sistem de calcul. Lățimea magistralei de date determină cantitatea maximă de
informații care poate fi primită sau transmisă la un moment dat.
Operațiile de schimb de informații sunt efectuate cu participarea simultană a tuturor
magistralelor. Să precăutăm, de exemplu, acțiunile care trebuie efectuate pentru a transfera
informații de la procesor în memorie. În cel mai simplu caz, trebuie efectuate trei acțiuni:
1. Pe magistrala de adrese, procesorul trebuie să seteze semnalele corespunzătoare adresei celulei
de memorie către care vor fi transmise informațiile.
2. Pe magistrala de date, procesorul trebuie să seteze semnalele corespunzătoare informațiilor
care trebuie înregistrate în memorie.
3. După efectuarea etapelor 1 și 2, semnalele corespunzătoare operațiilor de scriere în memorie
sunt setate pe magistrala de control, ceea ce va duce la scrierea informațiilor necesare pe adresa
dorită.
Etapele de mai sus sunt necesare, dar nu și suficiente când se ia în considerare funcționarea
anumitor procesoare și cipuri de memorie. Soluțiile arhitecturale specifice pot necesita acțiuni
suplimentare: de exemplu, setarea semnalelor pe magistrala de control pentru a utiliza parțial
magistrala de date (pentru a transfera mai puține informații decât lățimea ei permite); setarea
semnalului corespunzător după finalizarea scrierii în memorie, permițând începerea unei noi
operații, etc.
În timp ce memoria ne o putem imagina ca o secvență de celule numerotate localizate în același
microcircuit sau chipset, această abordare nu se aplică dispozitivelor de i/o. Dispozitivele externe
sunt separate spațial și pot fi conectate la magistrala locală prin un punct sau la un set de puncte,
numite porturi de intrare-ieșire. Cu toate acestea, modul în care celulele de memorie sunt
mapate în mod unic într-un spațiu de adrese de memorie, porturile i/o pot fi mapate în mod unic
într-un alt spațiu de adrese - spațiul de adrese i/o. În acest caz, fiecare port i/o își primește
numărul sau adresa sa în acest spațiu. În unele cazuri, când spațiul de adresă al memoriei
(dimensiunea căruia este determinată de lățimea magistralei de adrese) nu este complet utilizat
(există adrese care nu corespund celulelor de memorie fizică) și protocoalele de lucru cu un
dispozitiv extern sunt compatibile cu protocoalele de lucru cu memoria, unele porturi de i/o pot
fi mapate direct în spațiul de adrese al memoriei, însă aceste porturi nu mai sunt numite porturi.
În situația mapării directe a porturilor i/o către spațiul de adrese ale memoriei, acțiunile necesare
pentru a scrie informații în aceste porturi sau pentru a citi date din ele și stările lor nu diferă de
acțiunile efectuate pentru a transfera informații între memoria principală și procesor, și pentru a
le executa se aplică aceleași comenzi. Dacă portul este mapat în spațiul de adrese i/o, procesul
de schimb de informații este inițiat prin comenzi speciale de i/o și include alte acțiuni. De
exemplu, pentru a transfera date într-un port, se efectuează următoarele acțiuni:
• Pe magistrala de adrese, procesorul trebuie să seteze semnalele corespunzătoare adresei
portului la care vor fi transmise informațiile, în spațiul de adrese al i/o.
• Pe magistrala de date, procesorul trebuie să seteze semnalele corespunzătoare informațiilor
care trebuie transmise către port.
• După efectuarea etapelor 1 și 2, pe magistrala de control sunt setate semnalele care
corespund operațiunilor de scriere și lucru cu dispozitive de intrare-ieșire (schimbarea
spațiilor de adrese), ce va duce la transferul informațiilor necesare în portul dorit.
O diferență semnificativă între dispozitivele de i/o și memorie este că introducerea informațiilor
în memorie este sfârșitul operației de scriere, în timp ce introducerea informațiilor într-un port
reprezintă adesea inițializarea unei operații reale de i/o. Ce ar trebui să facă dispozitivele, după
ce au primit informații prin portul lor și în ce fel ar trebui să furnizeze informații pentru citirea
din port, este determinat de circuitele electronice ale dispozitivelor, numite controlere.
Controlerul poate dirija direct un dispozitiv (de exemplu, un controller de disc) sau mai multe
dispozitive prin comunicarea cu controlerele lor prin magistrale speciale (IDE, SCSI etc.).
Sistemele de calcul moderne pot avea o arhitectură diversă, multe magistrale, poduri pentru
transferul informațiilor de la o magistrală la alta, etc. Pentru noi, acum, sunt importante doar
următoarele moment:
• Dispozitivele i/o sunt conectate la sistem prin porturi.
• Pot exista două spații de adresă: un spațiu al memoriei și un spațiu de i/o.
• Porturile sunt de obicei mapate în spațiul de adrese i/o și uneori direct în spațiul de adrese al
memoriei.
• Utilizarea unuia sau altui spațiu de adrese este determinată de tipul de instrucțiuni executat de
procesor sau de tipul operanzilor săi.
• Controlerul dispozitivului administrează fizic dispozitivul i/o, transmitând informații prin port
și setând unele semnale pe magistrală.
Unicitatea conectării dispozitivelor externe la sistemul de calcul permite adăugarea
dispozitivelor noi, fără a reproiecta întregul sistem.

Structura controlerului dispozitivului


Controlerele dispozitivelor de intrare-ieșire sunt foarte diferite atât prin structura internă, cât și
prin funcționare (de la un cip la un sistem de calcul specializat cu propriul procesor, memorie
etc.), deoarece acestea trebuie să controleze dispozitive complet diferite. Fără a intra în detaliile
acestor diferențe, evidențiem câteva caracteristici comune ale controlerelor de care au nevoie
pentru a interacționa cu sistemul de calcul. De obicei, fiecare controler are cel puțin patru
registre interne numite registre de stare, control, intrare și ieșire. Pentru a accesa conținutul
acestor registre, sistemul de calcul poate utiliza unul sau mai multe porturi, ce nu este important
pentru noi. Pentru simplitate, presupunem că fiecare registru are propriul port.
Registrul de stare conține biți a căror valoare este determinată de starea dispozitivului de
intrare-ieșire și care sunt citite numai de sistemul de calcul. Aceste biți indică finalizarea
comenzii curente pe dispozitiv (bit ocupat), prezența următoarelor date în registrul de ieșire (bit
date prezente), apariția unei erori în timpul executării comenzii (bit de eroare) etc.
Registrul de control primește date care sunt înregistrate de sistemul de calcul pentru a inițializa
dispozitivul de intrare-ieșire sau pentru a executa următoarea comandă, precum și pentru a
schimba modul de operare al dispozitivului. Unii biți din acest registru pot fi alocați codului
comenzii de executat, unii biți vor codifica modul de funcționare a dispozitivului, bitul de
pregătire a comenzii indică faptul că este posibil să înceapă execuția acestuia.
Registrul de date de ieșire este utilizat pentru a plasa date în el pentru citire de către sistemul de
calcul, iar registrul de date de intrare este utilizat pentru a plasa informații care trebuie să fie
transmise către dispozitiv. De obicei, capacitatea acestor registre nu depășește lățimea
magistralei de date (cel mai des mai mică decât aceasta), deși unii controleri pot folosi coada
FIFO ca registre pentru a memora informațiile primite.
Setul de registre și biții lor constituenți este aproximativ, el este destinat să servească ca model
de descriere a procesului de transfer de informații de la sistemul de calcul la un dispozitiv extern
și invers, dar într-o formă sau alta, acesta este de obicei prezent în toate controlerele de
dispozitive.

Interogarea dispozitivelor și întreruperile. Situații de excepție și apeluri de sistem


După ce am construit un model de controler și ne-am imaginat ce înseamnă „citire informații din
port” și „scriere informații în port”, suntem gata să înțelegem procesul de interacțiune dintre
dispozitiv și procesor. Ca exemplu este comanda de scriere, care înseamnă scrierea sau
transmiterea datelor către un dispozitiv extern. În modelul nostru, procesorul și controlerul de
intrare trebuie să interacționeze astfel, pentru plasarea informațiilor de ieșire care sunt plasate în
registrul de date de intrare:
1. Procesorul într-un ciclu citește informațiile din portul registrului de stare și verifică valoarea
bitului ocupat. Dacă bitul ocupat este setat, asta înseamnă că dispozitivul nu a finalizat operația
anterioară, iar procesorul trece la o nouă iterație a ciclului. Dacă bitul ocupat este resetat,
dispozitivul este gata să efectueze o nouă operație, iar procesorul trece la pasul următor.

2. Procesorul scrie codul de comandă de ieșire în portul registrului de control.


3. Procesorul scrie date în portul registrului de intrare.
4. Procesorul stabilește bitul gata de comandă. În următorii pași, procesorul nu este implicat.
5. Când controlerul observă că este setat bitul gata de comandă, acesta setează bitul ocupat.
6. Controlerul analizează codul de comandă din registrul de control și detectează că este o
comandă de ieșire. Preia datele din registrul de intrare și inițiază executarea comenzii.
7. După finalizarea operațiunii, controlerul resetează bitul gata de comandă.
8. După finalizarea cu succes a operației, controlerul resetează bitul de eroare din registrul de
stare; după finalizarea nereușită a comenzii, o setează.
9. Controlerul resetează bitul ocupat.
Dacă este necesar să se scrie o informație nouă, toate aceste etape sunt repetate. Dacă procesorul
este interesat informațiile au fost scrise corect sau incorect, după pasul 4 trebuie să citească
informațiile din portul registrului de stare într-un ciclu până când bitului ocupat rămâne resetat,
apoi este analizată starea bitului eroare.
După cum vedem, la primul pas (și, posibil, după pasul 4), procesorul așteaptă eliberarea
dispozitivului prin sondarea continuă a valorii bitului ocupat. Această interacțiune între
procesor și controler se numește polling sau, în traducere, metodă de sondare a dispozitivului.
Dacă viteza procesorului și a dispozitivelor de intrare-ieșire sunt aproximativ egale, atunci
aceasta nu duce la o scădere semnificativă a productivității procesorului. Dacă viteza
dispozitivului este semnificativ mai mică decât viteza procesorului, atunci această tehnică reduce
dramatic performanțele sistemului și trebuie utilizată o abordare arhitecturală diferită.
Pentru ca procesorul să nu sondeze în ciclu dispozitivul de intrare-ieșire, dar să execute alte
lucrări în acest moment, este necesar ca dispozitivul singur să informeze procesorul despre
disponibilitatea sa. Mecanismul tehnic care permite dispozitivelor externe să comunice
procesorului finalizarea unei comenzi de ieșire sau o comandă de intrare, știm, se numește
mecanismul întreruperilor.
Pentru implementarea mecanismului întreruperilor, la magistrala locală se adaugă o linie care
conectează procesorul și dispozitivele de intrare-ieșire - linia de întreruperi. După finalizarea
operațiunii, dispozitivul extern pune un semnal special pe această linie, conform căruia
procesorul, după executarea instrucțiuni curente (sau după terminarea iterației curente la
executarea comenzilor iterative, adică comenzile care se repetă ciclic cu o deplasare de memorie)
își schimbă comportamentul. În loc să execute următoarea comandă din fluxul de comenzi,
procesorul salvează parțial conținutul registrelor sale și trece la executarea programului de
prelucrare a întreruperii, localizat la o adresă prestabilită. Dacă există o singură linie de
întreruperi, procesorul, în timpul execuției acestui program, trebuie să interogheze starea tuturor
dispozitivelor i/o pentru a determina ce dispozitiv a transmis întreruperea (polling al
întreruperii), să efectueze acțiunile necesare (de exemplu, să emită o altă porțiune de informații
către acest dispozitiv sau să comute procesul corespunzător din starea de așteptare la starea gata
de execuție) și să informeze dispozitivul că întreruperea a fost procesată (eliminare întrerupere).
În majoritatea sistemelor de calcul moderne, se încearcă eliberarea completă a procesorului de
necesitatea interogării dispozitivelor externe, inclusiv de la determinarea prin sondarea
dispozitivelor care a generat semnalul de întrerupere. Dispozitivele își raportează
disponibilitatea către procesor nu în mod direct, ci printr-un controler de întrerupere special și
pentru a comunica cu procesorul, acestea pot utiliza nu o linie, ci o întreagă magistrală de
întreruperi. Fiecărui dispozitiv i se atribuie propriul număr de întrerupere, care, atunci când
apare o întrerupere, controlerul de întrerupere îl plasează în registrul său de stare și apoi pe
magistrala de date sau magistrala de întreruperi, pentru a fi citire de către procesor. Numărul de
întrerupere este un element într-un tabel de întreruperi special, stocat la adresa specificată în
timpul inițializării sistemului de calcul și care conține adresele rutinelor de prelucrare a
întreruperii - vectori de întrerupere. Pentru a distribui dispozitivele în funcție de numerele de
întrerupere, este necesar ca de la fiecare dispozitiv la controlerul de întreruperi să existe o linie
specială corespunzătoare unui număr de întrerupere. Dacă există mai multe dispozitive, o astfel
de conexiune devine imposibilă și mai multe dispozitive sunt conectate la o singură linie (un
număr de întrerupere). În acest caz, procesorul, în timp ce procesează întreruperea, este încă
obligat să interogheze dispozitivele pentru a determina dispozitivul care a emis întreruperea, dar
într-o măsură mult mai mică. De obicei, la instalarea unui nou dispozitiv i/o în sistem, este
necesar să se determine, hard sau soft, care va fi numărul de întrerupere generat de acest
dispozitiv.
Când am studiat cooperarea proceselor și excluderile reciproce, am vorbit despre existența
secțiunilor critice în nucleul SO, în timpul execuției cărora este necesară excluderea oricăror
întreruperi de la dispozitivele externe. Pentru a interzice întreruperile sau, mai exact, pentru
imunitatea procesorului la întreruperi externe, există comenzi speciale care pot masca (interzice)
toate sau unele dintre întreruperile dispozitivelor de intrare-ieșire. În același timp, anumite
situații de criză într-un sistem de calcul (de exemplu, o defecțiune nerecuperabilă în memorie) ar
trebui să necesite răspunsul imediat al acestuia. Astfel de situații provoacă întreruperi care nu
pot fi mascate sau interzise și care intră în procesor printr-o linie special a magistralei de
întreruperi, numită linie nemascată de întrerupere (NMI -- Non-Maskable Interrupt).
Nu toate dispozitivele externe sunt la fel de importante pentru sistemului de calcul. De aceea,
unele întreruperi sunt mai importante decât altele. Controlerul de întreruperi permite, de obicei,
setarea priorităților întreruperilor de la dispozitive externe. Când întreruperile de la mai multe
dispozitive apar aproape simultan, procesorul este informat despre numărul de întrerupere cu
prioritate maximă pentru servirea lui în primul rând. În același timp, o întrerupere cu prioritate
mai mică nu dispare, procesorul va fi informat despre aceasta după prelucrarea unei întreruperi
cu prioritate mai mare. Mai mult decât atât, atunci când procesează o întrerupere, procesorul
poate primi un mesaj despre apariția unei întreruperi cu o prioritate mai mare și trece la
procesarea acesteia.
Mecanismul de prelucrare al întreruperilor, prin care procesorul nu mai execută comenzi în mod
normal și, păstrându-și parțial contextul, este distras de alte acțiuni, s-a dovedit a fi atât de
convenabil încât dezvoltatorii procesoarelor îl folosesc adesea în alte scopuri. Deși aceste cazuri
nu au legătură cu operații de i/o, e necesar să le menționăm aici, astfel încât să nu fie confundate
cu întreruperile. În mod similar procesorul gestionează situațiile de excepție și întreruperile
software.
Întreruperile externe posedă următoarele caracteristici:
• Procesorul detectează o întrerupere externă între execuția unor instrucțiuni (sau între iterații
în cazul executării instrucțiunilor ciclice)
• La prelucrarea întreruperii, procesorul salvează o parte din contextul său înainte de
execuția următoarei comenzi.
• Întreruperile au loc asincron cu procesorul și, în mod imprevizibil, programatorul nu
poate prezice în ce loc va apare o întrerupere.
Stările excepționale apar în timpul execuției de către procesor a unei instrucțiuni. Acestea pot fi:
împărțirea la zero, acces la o pagină de memorie lipsă, depășire de memorie etc. Pentru stările
excepționale este caracteristic:
• Procesorul detectează o stare excepțională în momentul execuției unei instrucțiuni.
• La prelucrarea întreruperii, procesorul salvează o parte din contextul său înainte de
execuția următoarei comenzi.
• Stările excepționale au loc sincron cu procesorul dar, în mod imprevizibil pentru
programator, doar dacă acesta nu a impus procesorul să împartă un număr careva la zero.

Întreruperile software apar după executarea comenzilor speciale, de obicei pentru a efectua
acțiuni privilegiate în cadrul apelurilor de sistem. Întreruperile software au următoarele
proprietăți:
• O întrerupere software apare la execuția unei comenzi speciale.
• Atunci când execută o întrerupere software, procesorul își păstrează contextual înainte de
execuția următoarei instrucțiuni.
• Întreruperile software se produc în mod sincron cu procesorul și sunt absolut previzibile
de programator.
De menționat că implementarea mecanismelor de prelucrare a întreruperilor externe, a situațiilor
excepționale și a întreruperilor software revine în totalitate dezvoltatorilor de procesoare. Există
sisteme de calcul în care toate cele trei situații sunt tratate diferit.

9.3. Principiile logice de organizare a sistemului de i/o


Mecanismele fizice de interacțiune a dispozitivelor de intrare-ieșire cu sistemul de calcul discutat
în secțiunea anterioară permit să înțelegem de ce o varietate de dispozitive externe pot fi
adăugate cu ușurință la computerele existente. Tot ce trebuie să facă utilizatorul atunci când
conectează un dispozitiv nou este să mapeze porturile dispozitivului către spațiul de adrese
corespunzător, să stabilească ce număr va corespunde întreruperii generate de dispozitiv și, dacă
este necesar, să aloce un anumit canal DMA dispozitivului. Pentru funcționarea normală a
hardware-ului va fi suficient. Cu toate acestea, încă nu am spus nimic despre modul în care
subsistemul de gestiune al i/o ar trebui să fie implementat în sistemul de operare pentru a adăuga
cu ușurință și fără durere dispozitive noi și ce funcții îi sunt atribuite în general.

Structura sistemului de intrare/ieșire


Toate dispozitivele sunt foarte diferite în ce privește funcțiile și caracteristicile lor și se pare că
este imposibil să se creeze un sistem care, fără modificări permanente mari, să acopere întreaga
varietate de tipuri. Iată o listă cu doar câteva caracteristici (departe de a fi completate), în care
dispozitivele diferă:
• Viteza schimbului de informații poate varia de la câțiva octeți pe secundă (tastatură) la
câțiva gigabyte pe secundă (carduri de rețea).
• Unele dispozitive pot fi utilizate de mai multe procese în paralel (sunt partajate), în timp ce
altele necesită o captură exclusivă a procesului.
• Dispozitivele pot stoca informațiile afișate pentru introducerea lor ulterioară sau nu au
această funcție. Dispozitivele care stochează informații, la rândul lor, pot fi diferențiate în
funcție de formele de acces la informațiile stocate: pentru a oferi acces secvențial la
acestea într-o ordine strict specificată sau pentru a putea găsi și transmite doar porțiunea
necesară de date.
• Unele dispozitive pot transmite date numai octet cu octet (dispozitive de caracter), iar
altele pot transmite un bloc de octeți în ansamblu (dispozitive bloc).
• Există dispozitive concepute numai pentru introducerea informațiilor, dispozitive
concepute numai pentru afișarea informațiilor și dispozitive care pot efectua atât intrarea
cât și ieșirea.
În domeniul asistenței tehnice, a fost posibil de elaborat mai multe principii de bază pentru
interacțiunea dispozitivelor externe cu sistem de calcul, adică pentru a crea o interfață unică
pentru conectarea acestora, alocând toate acțiunile specifice controlerelor dispozitivelor. Astfel,
proiectanții sistemelor de calcul au transferat toate problemele asociate conectării
echipamentelor externe dezvoltatorilor echipamentului însuși, forțându-i să respecte un anumit
standard.
O abordare similară s-a dovedit a fi potrivită și în domeniul conexiunii software a dispozitivelor
de intrare-ieșire. Putem împărți dispozitivele într-un număr relativ mic de tipuri care diferă prin
setul de operații care pot fi efectuate de acestea, considerând toate celelalte diferențe ca fiind
nesemnificative. Putem apoi specifica interfețele dintre nucleul sistemului de operare, care
implementează o politică generală de i/o, și componentele software care dirijează direct
dispozitivele pentru fiecare din aceste tipuri. Mai mult, dezvoltatorii sistemelor de operare au
ocazia să fie liberi de scrierea și testarea acestor părți software specifice, numite drivere,
transferând această activitate către producătorii de dispozitive externe. De fapt, ajungem să
folosim principiul unei construcții stratificate sau pe nivele a unui sistem de gestiune i/o pentru
un sistem de operare (fig.1).

Fig. 1. Structura sistemului de intrare/ieșire


Cele două niveluri inferioare ale acestui sistem stratificat sunt hardware-ul: dispozitivele în sine,
care efectuează în mod direct operațiunile, și controlerele lor, care sunt utilizate pentru
organizarea lucrărilor comune ale dispozitivelor și restul sistemului de calcul. Următorul nivel
este format din drivere dispozitivelor i/o, care ascund de dezvoltatorii sistemelor de operare
funcționarea specifică a dispozitivelor concrete și oferă o interfață clar definită între hardware și
nivelul superior - nivelul subsistemului i/o de bază, care, la rândul său, oferă un mecanism de
interacțiune între drivere și partea software al sistemul de calcul în ansamblu.

Funcțiile driverelor
Dispozitivele sunt împărțite în funcție de tipul de interfață în următoarele tipuri:
• caracter (tastatură, modem, terminal etc.);
• bloc (discuri magnetice și optice, benzi etc.);
• de rețea (carduri de rețea);
• restul (timere, afișaje grafice, televiziune, camere video etc.).
Vom precăuta doar două grupuri de dispozitive: caractere și bloc. Așa cum am menționat în
secțiunea anterioară, dispozitivele de tip caractere sunt dispozitive care pot transmite date
numai secvențial, byte cu byte, iar dispozitivele bloc pot transmite un bloc de octeți în
ansamblu.
Dispozitivele de tip caractere sunt de obicei dispozitive de introducere a informațiilor, care
generează spontan date de intrare: tastatură, mouse, modem, joystick. Acestea includ, de
asemenea, dispozitive de ieșire a informațiilor, care se caracterizează prin reprezentarea datelor
sub forma unui flux liniar: imprimante, plăci de sunet etc. Prin natura lor, dispozitivele de tip
caractere pot efectua două operații generale: introducerea unui caracter (octet) și afișarea unui
caracter (octet) ) - get și put.
Pentru dispozitivele bloc, cum ar fi discurile magnetice și optice, benzi magnetice etc., sunt
caracteristice operațiile de citire și scriere a unui bloc de informații - read și write, precum și
pentru dispozitivele cu acces direct, operația de căutare a blocului necesar este – seek.
Driverele dispozitivelor de tip caractere și blocui trebuie să ofere subsistemului i/o de bază
funcții pentru efectuarea operațiunilor descrise. În afară de operațiile generale, unele dispozitive
pot efectua operațiuni specifice doar lor - de exemplu, plăcile de sunet pot crește sau scădea
volumul mediu de sunet, afișajele își pot schimba rezoluția. Pentru a efectua astfel de acțiuni
specifice, interfața dintre driver și subsistemul i/o de bază include, de obicei, o altă funcție care
să permită transmiterea direct driverului dispozitivului a unei comenzi arbitrare cu parametri
arbitrari, care să permită utilizarea oricărei caracteristici a driverului fără a schimba interfața. În
sistemul de operare Unix, o astfel de funcție se numește ioctl (de la input-output control).
Pe lângă funcțiile read, write, seek (pentru dispozitive bloc), get, put (pentru dispozitivele de tip
caractere) și ioctl, interfața mai include și următoarele funcții:
• Funcția de inițializare sau reinițializare a driverului și dispozitivului - open.
• Funcția de oprire temporară a lucrului dispozitivului - close.
• Funcția de sondare a stării dispozitivului (dacă, din anumite motive, lucrul cu dispozitivul
se realizează prin sondarea stării acestuia, de exemplu, în sistemele de operare Windows
NT și Windows 9x așa este organizat lucrul cu imprimanta prin portul paralel) - poll.
• Funcția de oprire a driverului, care se execută când sistemul de operare este oprit sau
driverul este descărcat din memorie, halt.
Numele funcțiilor de mai sus pot varia de la un sistem de operare la altul, dar acțiunile efectuate
de drivere sunt tipice pentru majoritatea sistemelor de operare, iar funcțiile corespunzătoare sunt
prezente în interfețele acestora.

Funcțiile subsistemului i/o de bază


Subsistemul i/o de bază servește ca intermediar între procesele unui sistem de calcul și setul de
drivere. Apelurile de sistem pentru efectuarea operațiunilor de i/o sunt transformate de acesta în
apeluri funcționale ale driverului de dispozitiv necesar. Dar responsabilitățile subsistemului de
bază nu se limitează numai la efectuarea unei traduceri a apelului de sistem într-o adresare
directă la o funcție a driverului. Subsistemul de bază furnizează sistemului de calcul servicii
precum asistența pentru apeluri blocate, neblocante și asincrone, buferizarea și cacharea datelor
de intrare și ieșire, spooling și captură exclusivă a dispozitivelor externe, prelucrarea erorilor și
întreruperilor care apar în timpul operațiunilor de intrare-ieșire, planificarea unei secvențe de
solicitări pentru efectuarea acestor operațiuni. Să ne oprim la aceste servicii mai detaliat.

Apeluri de sistemul blocate, neblocate și asincrone


Toate apelurile de sistem legate de implementarea operațiilor de i/o pot fi împărțite în trei
grupuri conform metodelor de implementare a interacțiunii procesului și a dispozitivului de i/o:
• Primul grup, cel mai cunoscut pentru majoritatea programatorilor, include apelurile de
sistem blocate. După cum sugerează și denumirea, utilizarea unui astfel de apel duce la
blocarea procesului care a inițiat-o, adică procesul este transferat de sistemul de operare din
starea de execuție la starea de așteptare. După finalizarea tuturor operațiunilor de i/o
prescrise de apelul de sistem, sistemul de operare transferă procesul din starea de așteptare
în starea de gata. După ce procesul este selectat din nou pentru execuție, acesta va reveni
în sfârșit din apelul de sistem. Tipic pentru utilizarea unui astfel de apel de sistem este
cazul când un proces trebuie să primească o cantitate de date de la un dispozitiv, fără de
care acesta nu-și poate efectua lucrările.
• Al doilea grup include apeluri de sistem care nu blochează. Numele lor nu reflectă exact
esența problemei. În cel mai simplu caz, un proces care utilizează un apel care nu
blochează nu intră deloc într-o stare de așteptare. Apelul de sistem revine imediat
efectuind operațiile de i/o prescrise complet, parțial sau deloc, în funcție de situația actuală
(starea dispozitivului, disponibilitatea datelor etc.). În situații mai complexe, procesul poate
fi blocat, dar condiția pentru deblocarea lui este finalizarea tuturor operațiunilor necesare
sau sfârșitul unui anumit cuantum de timp. O utilizare tipică a unui apel de sistem care nu
blochează poate fi verificarea periodică dacă sunt primirte informațiile de la tastatură
atunci când se efectuează calcule laborioase.
• Al treilea grup include apeluri asincrone de sistem. Un proces care utilizează un apel
asincron de sistem nu este niciodată blocat în el. Un apel de sistem inițiază operațiile de i/o
necesare și se întoarce imediat, după care procesul își continuă activitățile sale. Sistemul de
operare informează ulterior procesul despre finalizarea operației de i/o prin schimbarea
valorilor unor variabile, prin transmiterea unui semnal sau mesaj către acesta sau în un alt
mod. Trebuie să înțelegem diferența dintre apelurile care nu blochează și cele asincrone.
Un apel de sistem care nu blochează pentru a efectua operația read se va întoarce imediat,
cu citirea numărului de octeți solicitat, mai puțini sau nimic. De asemenea, apelul asincron
al sistemului pentru această operațiune va reveni imediat, dar mai devreme sau mai târziu
numărul necesar de octeți va fi citit complet.
Buffering și Cache

De obicei, un buffer (tampon) este o anumită zonă de memorie pentru stocarea informațiilor la
schimbul de date între două dispozitive, două procese sau un proces și un dispozitiv. Schimbul
de informații între două procese aparține domeniului cooperării proceselor și am examinat în
detaliu organizarea lor la lecțiile precedente. Acum vom fi interesați de utilizarea bufferelor
atunci când unul dintre participanții la schimbul de date este un dispozitiv extern. Există trei
motive pentru utilizarea tampoanelor în subsistemul de i/o de bază.
• Primul motiv al bufferizării este viteza diferită de primire și transmitere a informațiilor pe
care participanții la schimb le au. Să analizăm, de exemplu, cazul transferului unui flux de
date de la tastatură la modem. Viteza cu care tastatura furnizează informații este
determinată de viteza de tastare de către persoană și este de obicei substanțial mai mică
decât viteza de transmitere a datelor de către modem. Pentru a nu ocupa modemul pe toată
durata tastării, ceea ce îl face inaccesibil pentru alte procese și dispozitive, este
recomandabil să se acumuleze informațiile introduse într-un tampon sau mai multe
tampoane de dimensiuni suficiente și să fie trimite către modem după umplerea
tampoanelor.
• Al doilea motiv al bufferizării - cantitățile diferite de date care pot fi primite sau trimise
de către participanții la schimbul simultan. Analizăm un alt exemplu. Fie că informațiile
sunt furnizate de modem și scrise pe hard disk. Pe lângă faptul că au viteze diferite de
operare, modemul și hard disk-ul sunt dispozitive de diferite tipuri. Modemul este un
dispozitiv de tip caractere și furnizează date byte cu byte, în timp ce discul este un
dispozitiv bloc și pentru operația de scriere trebuie să acumuleze blocul de date necesar în
buffer. De asemenea, se pot utiliza mai mult de un tampon. După completarea primului
buffer, modemul începe să completeze al doilea, în același timp cu scrierea primului pe
hard disk. Deoarece viteza hard disk-ului este de mii de ori mai mare decât viteza
modemului, până când cel de-al doilea tampon este complet, operația de scriere a primului
va fi finalizată, iar modemul va putea din nou să completeze primul tampon simultan cu
scrierea celui de-al doilea pe disc.
• Al treilea motiv pentru buffering este legat de necesitatea copierii informațiilor din
aplicațiile care efectuiază operații de i/o în bufferul nucleului sistemului de operare și
invers. Să presupunem că un anumit proces utilizator dorește să scrie informații din spațiul
său de adrese pe un dispozitiv extern. Pentru a face acest lucru, el trebuie să efectueze un
apel de sistem cu numele generic write, transmițând ca parametri adresa zonei de memorie
în care se află datele și volumul acestora. Dacă dispozitivul extern este temporar ocupat,
atunci este posibilă situația când, până la eliberarea sa, conținutul zonei de memorie să fie
corupt (de exemplu, la utilizarea unui apel de sistem asincron). Pentru a evita astfel de
situații, înainte de lansarea apelului de system - de copiat datele necesare în bufferul
nucleului sistemului de operare, care se află permanent în RAM și de a le transmite
dispozitivului din acest buffer.
Cuvântul cache (cache - „ rezervă”) reprezintă o regiune a memoriei rapide care conține o copie
a datelor situate undeva într-o memorie mai lentă, concepută pentru a accelera sistemul de calcul.
În subsistemul de i/o de bază, aceste două concept, buffering și caching, nu ar trebui confundate,
deși deseori aceeași zonă de memorie este alocată pentru a îndeplini ambele aceste funcții. Un
buffer conține adesea un singur set de date care există într-un sistem, în timp ce un cache prin
definiție conține o copie a datelor care există în altă parte. De exemplu, bufferul folosit de
subsistemul de bază pentru a copia date din spațiul procesului utilizatorului atunci când este
transmis pe disc poate fi, la rândul său, utilizat ca cache pentru aceleași date, dacă operațiile de
modificare și reluare ale acestui bloc sunt efectuate destul de des.
Funcțiile de bufferizare și de cachare nu trebuie obligator localizate în subsistemul i/o de bază.
Acestea pot fi parțial implementate în drivere și chiar în controlerele de dispozitive, în mod
ascuns pentu subsistemul de bază.

Spooling și captarea dispozitivelor


Am vorbit despre conceptul de spooling ca un mecanism care permite efectuarea operațiilor reale
de i/o ale unei sarcini cu executarea altei sarcini. Acum putem defini acest concept mai precis.
Prin spool înțelegem un buffer care conține date de intrare sau ieșire pentru un dispozitiv pe care
este necesar să se evite alternarea utilizării sale (apariția interleaving) de către diferite procese.
Adevărat, în sistemele moderne de calcul, spool practic nu este utilizat la introducerea datelor, ci
este destinat în principal acumulării informațiilor de ieșire.
Să presupunem că imprimanta este un dispozitiv extern. Deși imprimanta nu poate tipări
informații din mai multe procese simultan, poate să fie necesară tipăririrea în paralel. Pentru
aceasta, sistemul de operare în loc să transfere informația direct către imprimantă, acumulează
datele de ieșire în buffere pe disc, organizate ca fișier-spool separat pentru fiecare proces. După
finalizarea unui proces, fișierul său spool este pus în coadă pentru imprimare reală. Mecanismul
care oferă aceste acțiuni se numește spooling.
Pe unele sisteme de operare, pentru a elimina starea de cursă, spooling este înlocuit de
mecanismul de captare exclusivă a dispozitivelor de către procese. Dacă dispozitivul este liber,
atunci unul dintre procese poate intra în posesia sa exclusivă. În acest caz, toate celelalte procese,
atunci când încearcă să efectueze operațiuni pe acest dispozitiv, vor fi blocate (trecute în starea
wait), fie vor primi informații despre imposibilitatea de a efectua operațiunea până când procesul
care a ocupat dispozitivul nu s-a finalizat sau a înștiințat în mod explicit sistemul de operare că
refuză folosirea lui.

Gestionarea întreruperilor și erorilor


Dacă sistemul de calcul nu folosește metoda de sondare a stării sale atunci când lucrează cu un
dispozitiv extern, ci folosește mecanismul întreruperilor, atunci când apare o întrerupere,
procesorul, salvându-și parțial contextul, transmite controlul unei rutine speciale de procesare a
întreruperii. Am examinat deja acțiunile sistemului de operare cu privire la procese atunci când
se produce o întrerupere, în secțiunea „Comutarea contextului”, unde după apariția întreruperii
au avut loc următoarele acțiuni: salvarea contextului, prelucrarea întreruperii, planificarea
proceselor și restabilirea contextului. Apoi am acordat mai multă atenție acțiunilor legate de
menținerea și restaurarea contextului și planificarea utilizării procesorului. Acum să analizăm
mai atent ce înseamnă „prelucrarea întreruperii”.
Aceeași procedură de procesare a întreruperilor poate fi aplicată mai multor dispozitive i/o (de
exemplu, dacă aceste dispozitive folosesc aceeași linie de întrerupere care pleacă de la ele la
controlerul de întrerupere). Prin urmare, prima acțiune a programului de procesare este de a
determina ce dispozitiv a generat întreruperea. Cunoscând dispozitivul, putem identifica
procesul care a inițiat executarea operației corespunzătoare. Deoarece întreruperea are loc atât
atunci când are succes, cât și atunci când nu reușește, următorul lucru care trebuie făcut este
determinarea succesului operațiunii, verificând valoarea bitului de eroare din registrul de stare
al dispozitivului. În unele cazuri, sistemul de operare poate lua anumite acțiuni pentru a
compensa eroarea care a avut loc. De exemplu, în cazul unei erori de citire de pe dischetă, se
încearcă repetarea operației de mai multe ori. Dacă compensarea erorilor nu este posibilă,
sistemul de operare anunță procesul care a solicitat operațiunea (de exemplu, un cod de retur
special de la un apel de sistem). Dacă acest proces a fost blocat înainte de finalizarea operației,
sistemul de operare îl trece în stare ready. Dacă există alte solicitări nesatisfăcute către acest
dispozitiv, sistemul de operare poate iniția executarea următoarei solicitări, în timp ce anunță
dispozitivul că întreruperea a fost procesată. Astfel prelucrarea întreruperii se încheie, iar
sistemul poate începe să planifice utilizarea procesorului.
Acțiunile pentru procesarea întreruperilor și compensarea erorilor pot fi transferate parțial pe
umerii driverului corespunzător. Pentru a face acest lucru, se adaugă o altă funcție la interfața
dintre driver și subsistemul i/o de bază - funcția de procesare a întreruperii intr.
9.4. Planificarea solicitărilor
La utilizarea unui apel de sistem care nu blochează, se poate întâmpla că dispozitivul solicitat
este deja ocupat. În acest caz, un apel care nu blochează poate reveni imediat fără să execute
comenzile solicitate. Atunci când se organizează o solicitare pentru operațiuni de i/o folosind un
apel de blocare sau asincron, dacă dispozitivul este ocupat, cererea la acest dispozitiv necesită
așteptarea. Drept urmare, cu fiecare dispozitiv este legată o listă de solicitări nesatisfăcute de
procese în stare wait și cereri care rulează în modul asincron. Starea de așteptare este împărțită
într-un set de cozi de procese care așteaptă diverse dispozitive de intrare / ieșire (sau în
așteptarea modificărilor în starea diferitelor obiecte - semafoare, cozi de mesaje, variabile
condiționale în monitoare etc.).
După finalizarea execuției cererii curente, sistemul de operare (în procesul de prelucrare a
întreruperii care a avut loc) trebuie să decidă care solicitare din listă ar trebui să fie satisfăcută
următoarea și să inițieze executarea acesteia. În același mod ca pentru alegerea următorului
proces de execuție din lista celor pregătite, a trebuit să realizăm o planificare pe termen scurt a
proceselor, aici trebuie să planificăm utilizarea dispozitivelor folosind un algoritm pentru această
planificare. Criteriile și obiectivele unei astfel de planificări diferă puțin de criteriile și
obiectivele planificării proceselor.
Sarcina de planificare a utilizării unui dispozitiv este de obicei atribuită subsistemului i/o de
bază, dar pentru unele dispozitive, cei mai buni algoritmi de planificare pot fi strâns legați de
detaliile funcționării lor interne. În astfel de cazuri, operația de planificare este transferată în
driverul dispozitivului corespunzător, deoarece aceste detalii sunt ascunse subsistemului de bază.
Pentru aceasta, se adaugă o altă funcție specială la interfața driverului care selectează următoarea
solicitare - funcția strategy..
În continuare vom precăuta câțiva algoritmi de planificare a solicitării, folosind exemplul unui
hard disk.

Algoritmi de planificare a solicitărilor pe hard disk


Înainte de a prezenta acești algoritmi, să reamintim structura internă a hard disk-ului și să
stabilim ce parametri de solicitare putem folosi pentru planificare.

Structura hard disk-ului și parametrii de planificare

Un disc magnetic dur modern este un set de plăci rotunde amplasate pe aceeași axă și acoperite
pe una sau ambele părți cu un strat magnetic special (vezi fig. 2). În apropierea fiecărei suprafețe
de lucru a fiecărei plăci se află capetele magnetice pentru citirea și scrierea informațiilor. Aceste
capete sunt atașate de o pârghie specială care poate muta întregul bloc de capete pe suprafețele
plăcilor în ansamblu. Suprafețele plăcilor sunt împărțite în inele concentrice, în interiorul cărora,
de fapt, pot fi stocate informații. Setul de inele concentrice de pe toate plăcile pentru o poziție a
capului (adică toate inelele echidistante de axă) formează un cilindru. Fiecare inel din interiorul
cilindrului se numește pistă (una sau două pe placă). Toate pistele sunt împărțite într-un număr
egal de sectoare. Numărul de piste, cilindri și sectoare poate varia de la un hard disk la altul. De
obicei, un sector reprezintă cantitatea minimă de informații care poate fi citită de pe un disc la un
moment dat.
În timpul funcționării discului, setul de plăci se rotește în jurul axei sale cu viteză mare,
expunând pe rând toate sectoarele lor sub capetele pistelor corespunzătoare. Numărul sectorului,
numărul pistei și numărul cilindrului
determină în mod unic poziția datelor pe hard
disk și, împreună cu tipul de operațiune
efectuată - citire sau scriere, caracterizează
complet o parte din cererea asociată
dispozitivului, atunci când schimbul de date
se face de mărimea unui sector.

Fig. 2. Structura hard disk-ului

Parametrul de planificare a solicitărilor unui


hard disk sigur că este timpul necesar pentru a satisface următoarea solicitare. Timpul necesar
pentru citirea sau scrierea unui anumit sector pe o pistă a unui cilindru anume poate fi împărțit în
două componente: timpul de schimb de informații între capul magnetic și computer, care este de
obicei independent de poziția datelor și este determinat de viteza de transfer (transfer speed) și
timpul, necesar pentru poziționarea capului pe un anumit sector - timpul de poziționare
(positioning time). Timpul de poziționare, la rândul său, constă din timpul necesar pentru a muta
capetele pe cilindrul dorit - timpul de căutare (seek time) și timpul necesar pentru ca sectorul
dorit să nimerească sub cap - întârziere de rotație (rotational latency). Timpul de căutare este
proporțional cu diferența dintre numărul de cilindri al solicitărilor anterioare și cele planificate și
sunt ușor de comparat. Întârzierea de rotație este determinată de relații destul de complicate între
numărul de cilindri și sectoarele cererilor anterioare și planificate și de viteza de rotație a discului
și mișcarea capetelor. Fără cunoașterea raportului acestor viteze, compararea devine imposibilă.
De aceea, setul de parametri de planificare este redus la timpul de căutare a diverselor solicitări,
determinate de poziția curentă a capului magnetic și de numărul de cilindri necesari, iar diferența
de întârzieri de rotație este neglijată.

Аlgoritmul First Come First Served (FCFS)


Cel mai simplu algoritm cu care ar fi trebuit să ne obișnuim este algoritmul First Come First
Served (FCFS) - primul venit, primul servit. Toate cererile sunt puse în coadă FIFO și sunt
deservite în ordinea solicitării. Algoritmul este simplu de implementat, dar poate duce la un timp
total de deservire a solicitării destul de lung. Să analizăm un exemplu. Presupunem că avem
următoarea coadă de solicitare pe un disc de 100 de cilindri (de la 0 la 99): 23, 67, 55, 14, 31, 7,
84, 10, iar capetele magnetice sunt inițial pe al 63-lea cilindru. Atunci poziția capetelor se va
schimba după cum urmează, conform algoritmului:
63 23 67 55 14 31 7 84 10

și toate capetele se vor deplasa cu 329 de cilindri. Eficiența algoritmului este bine ilustrată de
ultimele două mutări de la cilindrul 7 prin întregul disc la cilindrul 84 și apoi din nou pe întregul
disc până la cilindrul 10. O simplă înlocuire a ordinii ultimelor două mișcări (7 10 84) ar
reduce semnificativ timpul total de servire al cererilor. Prin urmare, să trecem la un alt algoritm.

Алгоритм Short Seek Time First (SSTF)


După cum am văzut, este rezonabil să deservim cereri, care se află lângă poziția actuală a capului
de citire și apoi cele mai îndepărtate. Algoritmul Short Seek Time First (SSTF) - un timp de
căutare scurt mai întâi - tocmai reese din această ideie. Pentru următorul serviciu, vom alege o
solicitare pentru care datele sunt cele mai apropiate de poziția curentă a capetelor magnetice.
Desigur, în prezența solicitărilor echidistante, decizia de a alege între ele poate fi luată pe baza
unor considerente diferite, de exemplu, conform algoritmului FCFS. Pentru exemplul anterior,
algoritmul va oferi următoarea secvență de poziții ale capului magnetic:
63 67 55 31 23 14 10 7 84

și toate capetele se vor deplasa cu 141 de cilindri. Observăm că algoritmul dat este similar cu
algoritmul de planificare a proceselor SJF, dacă alegem distanța dintre poziția curentă a capului
și poziția necesară pentru a satisface cererea pentru analogul estimării în timp a următorului
proces de ocupare a procesorului. La fel ca algoritmul SJF, poate duce la o întârziere lungă la
planificarea unei solicitări. Trebuie reținut faptul că cererile din coadă pot apărea oricând. Dacă
toate solicitările, cu excepția uneia, sunt grupate în mod constant în zone cu număr mare de
cilindri, atunci această singură solicitare poate fi la coadă la nesfârșit.

Algoritmul SJF este optim pentru un set dat de procese cu timpi de procesare dat. Evident,
algoritmul SSTF nu este optim. Dacă mutăm cererea de service pentru al 67-lea cilindru între
solicitările cilindrilor 7 și 84, vom reduce timpul total de service. Această observație ne conduce
la ideea unei familii întregi de alți algoritmi - algoritmi de scanare.

Algoritmi de scanare (SCAN, C-SCAN, LOOK, C-LOOK)

În cel mai simplu algoritm de scanare - SCAN - capetele se mișcă constant de la o margine a
discului la cealaltă, servind toate solicitările din listă. La atingerea celeilalte margini, direcția
mișcării se schimbă și totul se repetă din nou. În exemplul precedent, fie la momentul inițial,
capetele se deplasează în direcția scăderii numărului cilindrilor. Apoi vom primi lista de
solicitări, obținută la sfârșitul secțiunii anterioare. Secvența de mișcare a capetelor este
următoarea: 63 55 31 23 14 10 7 0 67 84

și toate capetele se vor deplasa cu 147 de cilindri.

Dacă știm că am servit ultima solicitare în direcția de mișcare a capetelor, atunci putem să nu
ajungem la marginea discului, ci să inversăm imediat direcția de mișcare:

63 55 31 23 14 10 7 67 84

iar capetele se vor deplasa cu 133 de cilindri. Modificarea rezultată a algoritmului SCAN se
numește LOOK.

Să presupunem că în algoritmul SCAN până la momentul în care capul ajunge la unul dintre
marginile discului, s-a acumulat un număr mare de solicitări noi la această margine și servirea lor
va dura mult timp (nu uitați că nu numai mișcați capul, dar transmiteți și datele citite!). Atunci,
cererile legate de cealaltă margine a discului și primite mai devreme vor aștepta în mod
nejustificat pentru a fi servite. Pentru a reduce timpul de așteptare pentru aceste solicitări, se
utilizează o altă modificare a algoritmului SCAN - scanare circulară. Când capul ajunge pe unul
dintre marginile discului, fără a citi cererile nou apărute (uneori mult mai repede decât atunci
când se efectuează o căutare normală a cilindrilor), acesta se deplasează pe cealaltă margine, de
unde începe să se deplaseze în aceeași direcție. Pentru acest algoritm, numit C-SCAN, secvența
de mișcare va arăta astfel:
63 55 31 23 14 10 7 0 99 84 67.
Concluzie

Funcționarea oricărui sistem de calcul se referă, de regulă, la două tipuri de lucrări: prelucrarea
informațiilor și operațiile de input-output.

În ciuda întregii varietăți de dispozitive de intrare-ieșire, gestionarea activității lor și schimbul de


informații cu acestea se bazează pe un număr relativ mic de principii. Principiile fizice de bază
pentru construirea unui sistem de intrare-ieșire sunt următoarele: capacitatea de a utiliza diverse
spații de adrese pentru memorie și dispozitive de intrare-ieșire; conectarea dispozitivelor la
sistem prin porturi de intrare / ieșire care sunt mapate într-unul dintre spațiile de adrese;
existența unui mecanism de întreruperi pentru anunțarea procesorului despre finalizarea
operațiilor de i/o; prezența unui mecanism de acces direct al dispozitivelor la memorie, ocolind
procesorul.

O abordare „stratificată” este tipică pentru realizarea părții software a unui sistem de intrare /
ieșire. Driverele de dispozitiv sunt folosite pentru a interacționa direct cu hardware-ul. Driverele
de dispozitiv sunt conectate printr-o interfață strict definită la subsistemul i/o de bază. Accesul la
subsistemul i/o de bază se face prin apeluri de sistem.
Unele funcții ale subsistemului de bază pot fi delegate driverelor de dispozitive și dispozitivelor
de intrare/ieșire.

S-ar putea să vă placă și