Sunteți pe pagina 1din 200

Sisteme de operare

Fire de execuție
Cuprins

• fire de execuție
– kernel
– utilizator
• NPTL

2
Bibliografie

• Modern Operating Systems


– Capitolul 2
• 2.2

• Operating Systems Concepts


– Capitolul 4

3
Tipuri de procese (CPU)

• CPU bound (CPU intensive)


– folosește mult procesorul

• I/O bound (I/O intensive)


– folosește rar procesorul
– folosește multe operații I/O, se blochează des

4
Stările proceselor

5
Exemple de procese

• Editoare de text

• Server Web

• Jocuri

6
FIRE DE EXECUȚIE

7
Fire de execuție

• Unitatea de planificare

• Un proces este format din mai multe fire de


execuție

• Lightweight Processes (LWP)

8
Procese și fire de execuție

9
Fire de execuție

10
Spațiul de memorie

11
Propietățile unui fir de execuție

• TID – identificator
• TLS – thread local storage
• Stack – stiva
• Registre de CPU
• State – starea
• Priority – prioritea

12
Tipuri de fire de execuție

• Nucleu
– Sunt cunoscute de kernel
– Se face schimbare de context

• Utilizator
– Nu sunt cunoscute de kernel
– Nu se face schimbare de context

13
Tipuri de fire de execuție

14
Întrebare?

• Fire de execuție utilizator


– Un fir de execuție face o operație blocantă
– Ce se întâmplă?

Toate firele de execuție se blochează

15
Starea proceselor

16
Schimbarea de context

17
Schimbarea de context

• Se trece prin kernel

• Nu se face flush la TLB

18
Implementarea firelor de execuție

• Many to one

• One to one

• Many to many

19
Many to one

• Fire de execuție
utilizator

• Fiecare fir de execuție


este planificat pe
același fir de execuție
nucleu

20
One to one
• Fire de execuție nucleu
• Fiecare fir de execuție este planificat pe
un fir de execuție nucleu

21
Many to many

• Mai multe fire de


execuție utilizator
sunt planificate pe
mai multe fire de
execuție nucleu

22
Oprirea unui fir de execuție

• Asincron
– Firul de execuție este oprit imediat

• Deffered
– Fire de execuție se oprește singur

23
Implementare

• Windows
– Threads
– Fibers

• UNIX
– pthreads (NPTL)
– bibliotecă

• Java/Go
– Many to many

24
Windows

• Threads
– Nucleu
– Un proces are mai multe fire de execuție nucleu

• Fibers
– Utilizator
– Un fir de execuție nucleu are mai multe fire de
execuție utilizator

25
POSIX

26
Proces nou - UNIX

• fork: creează un proces nou (copil) (aproape


identic cu procesul părinte)
– copierea memoriei

• exec: încarcă imaginea dintr-un executabil în


procesul curent (de obicei folosit de procesul
copil)
– memorie nouă

27
Fire de execuție nou - UNIX

• fork: creează un proces nou (copil) (aproape


identic cu procesul părinte)
– partajează memoria
– stivă diferită
– TCB și local storage

• Linux nu știe fire de execuție


• Un proces e de fapt un grup de procese care
partajează memoria între ele
28
pthread

• biblioteca pthread (POSIX Thread)

• NPTL (New POSIX Thread Library)

29
Funcții

// create a thread
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg);

// stop a thread
int pthread_cancel(pthread_t thread);

// wait for a thread to finish


int pthread_join(pthread_t thread, void **value_ptr);

// send a signal to a thread


int pthread_kill(pthread_t thread, int sig);

// run a function once in a thread


int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));

// detach a thread
int pthread_detach(pthread_t thread)

// exit from a thread


void pthread_exit(void *value_ptr)

30
Exemplu

/* this function is run by thread */


void *run(void *void_ptr)
{
// ... thread code here
return NULL;
}

31
Start

void *data;

int main ()
{
int r;
pthread_t run_thread;

r = pthread_create(&run_thread, NULL, run, data);


if (r != 0)
{
perror ("pthread_create");
}
return 0;
}

32
Probleme

• fork et exec
– se clonează toate firele de execuție?
– exec înlocuiește un singur fir de execuție?

• semnale
– care fire de execuție primește semnalele?

33
Fire de execuție și fork

• Se clonează un singur fir


• Nu e o idee bună să se folosească într-un proces
care are fire de execuție
– descriptori de fișiere
– unde se opresc celelalte fire de execuție
– funcții de bibliotecă

• detalii
https://www.linuxprogrammingblog.com/threads
-and-fork-think-twice-before-using-them
34
Exemplu descriptori de fișiere

fd = open("file",O_RDWR|O_CREAT|O_TRUNC, 0600);
if (fd < 0) {
perror ("open()");
return 0;
}

fcntl (fd, F_SETFD, FD_CLOEXEC);

35
Soluția

int pthread_atfork(
void (*prepare)(void),
void (*parent)(void),
void (*child)(void)
);

36
Semnale

• Firul de execuție curent primește semnalul


• Stiva de semnale este unică
– Blocarea semnalele este făcută de fiecare fir de
execuție în parte
– Acțiunea este partajată

• Excepții (SIGSEV, SIGFPE, SIGBUS ...)


– sunt primite de firul de execuție care execută
excepția

37
Cuvinte cheie

• fir de execuție • fork și thread-uri


• thread • semnale și thread-uri
• thread utilizator • join
• thread nucleu • Thread ID
• TCB • TLS
• fiber • pthread
• many to one • NPTL
• one to many • asynchronous exit
• many to many • deffered exit

38
Întrebări

39
Sisteme de operare

Sincronizare
Cuprins

• cursa
• zona critică
• acțiuni atomice
• busy waiting
• semafor
• mutex

2
Bibliografie

• Modern Operating Systems


– Capitolul 4
• 4.4
• 4.5
• 4.6
• Operating Systems Concepts
– Capitolul 9
• 9.1 – 9.4
• 9.6
• 9.7

3
Sincronizare

• Asigurarea accesului corect la date


– date integre
– determinism

• Acces exclusiv / serializare / atomizare


– regiune critică

• Secvențiere / ordonare
– read after write
– write after write
– use after create

4
Primitive de sincronizare

• Ordonare
– wait
– notify

• Acces exclusiv
– lock
– unlock

5
CURSA

6
Cursa

Proces 1 Proces 2
// shared variable a // shared variable a

int a = 0; int a = 0;
if (a == 0) if (a == 0)
{ {
a++; a++;
} }
printf ("%d\n", a); printf ("%d\n", a);

7
Cursa – varianta secvențială

Proces 1 Proces 2
// shared variable a // shared variable a

int a = 0;
if (a == 0) {
a++;
}
printf ("%d\n", a);

int a = 0;
if (a == 0) {
a++;
}
printf ("%d\n", a);

1 1
8
Cursa – varianta intercalată

Proces 1 Proces 2
// shared variable a // shared variable a

int a = 0;
if (a == 0) {
int a = 0;
if (a == 0) {
a++;
}
a++;
}

printf ("%d\n", a);


printf ("%d\n", a);

2 2
9
Cursa – varianta corectă

Proces 1 Proces 2
// shared variable a // shared variable a

int a = 0;
int a = 0;

if (a == 0) {
a++;
}
if (a == 0) {
a++;
}

printf ("%d\n", a);

printf ("%d\n", a);

1 1
zona critică
10
Zona critică

• o parte de cod care trebuie executată singură


– accesul la variabile (resurse) trebuie să se execute
singur

if (a == 0) {
a++;
}
if (a == 1) {
a--;
}

Motivul este accesul la variabila a


11
Acțiuni atomice

• O acțiune care se execută fără întreruperi

• Întreruperi posibile
– întrerupere sau excepție
– semnal
– schimbare de context

• Instrucțiunile CPU sunt atomice (in single core)


12
Exemplu

int main ()
{
int a = 0;
a++;
}

Mai multe exemple pe https://godbolt.org/

13
Exemplu – x86-64

int main () ; rbp-4 address of


{ variable a
int a = 0; mov DWORD PTR [rbp-4], 0

a++; add DWORD PTR [rbp-4], 1


}

a++ este atomică pe single core

14
Exemplu – ARM

int main () ; fp-8 address of


{ variable a
int a = 0; mov r3, #0
str r3, [fp, #-8]
a++;
} ldr r3, [fp, #-8]
add r3, r3, #1
str r3, [fp, #-8]

a++ nu este atomică

15
Instrucțiuni pentru sincronizare
; rbp-4 address of variable test

if (test == 0) cmp DWORD PTR [rbp-4], 0


{ jne .L2

test = 1;
mov DWORD PTR [rbp-4], 1
// do some work
; do some work
test = 0;
} mov DWORD PTR [rbp-4], 0
.L2:

Nu este atomică
Problema TOCTOU
Time of Check, Time of Utilization
16
Test and set / Compare and swap

• O instrucțiune care
– Execută o comparație
– Execută o atribuire în funcție de comparație
• TSL / CAS

r = value;
value = 1;
if (r == 0) ...

tsl (r, value) tsl r, value


cmp r, 0

17
Instrucțiune pentru sincronizare
; rbp-4 address of variable test

if (tsl(test, 1)) mov eax, 0


{ cmpxchg DWORD PTR
[rbp-4], 1
// do some work jne .L2

test = 0; ; do some work


}
mov DWORD PTR [rbp-4], 0
.L2:

este atomică pe single core

18
Instrucțiune pentru sincronizare
; rbp-4 address of variable test

if (tsl(test, 1)) mov eax, 0


{ lock cmpxchg DWORD PTR
[rbp-4], 1
// do some work jne .L2

test = 0; ; do some work


}
mov DWORD PTR [rbp-4], 0
.L2:

este atomică pentru multicore

19
Primitive cod atomic

• Spinlock

• Semafor

• Mutex

20
SPINLOCK

21
Spinlock

while (test != 0)
Spinlock
continue;

test = 1; Atomic?

// do some work with

test = 0;
22
Spinlock x86
; rbp-4 address of variable test

while (test != 0) .L2:


continue; cmp DWORD PTR [rbp-4], 0
jne .L2
test = 1;
mov DWORD PTR [rbp-4], 1
// do some work with
; do some work
test = 0;
mov DWORD PTR [rbp-4], 0

Nu este atomic

23
Spinlock

while (tsl(test, 1))


Spinlock
continue;

// do some work with

test = 0;

24
Spinlock x86
; rbp-4 address of variable test

while (tsl(test, 1)) mov eax, 0


continue; .L2:
lock cmpxchg DWORD PTR
// do some work with [rbp-4], 1
jne .L2
test = 0;
; do some work

mov DWORD PTR [rbp-4], 0

Este atomic

25
lock și unlock

• lock
– acaparează spinlock-ul

• unlock
– eliberează spinlock-ul

26
lock și unlock

void lock (s) void unlock (s)


{ {
while (tsl(s, 1)); s = 0;
} }

// s - spinlock

27
Exemplu

Proces 1 Proces 2
// shared variables a and s // shared variables a and s
int a = 0; int a = 0;
int s; int s;
lock (s); lock (s);
if (a == 0)
{
a++;
}
unlock (s);
if (a == 0)
printf ("%d\n", a); {
a++;
}
unlock (s);
printf ("%d\n", a);

1 1 28
Exemplu

Proces 1 Proces 2
// shared variables a and s // shared variables a and s
int a = 0; int a = 0;
int s; int s;
lock (s); lock (s);
if (a == 0)
{
a++;
}
unlock (s);
if (a == 0)
{ printf ("%d\n", a);
a++;
}
unlock (s);
printf ("%d\n", a);

1 1 29
Deadlock

Ce se întâmplă când uită să apelăm unlock?

Ce se întâmplă dacă apelăm lock de mai multe


ori fără unlock?

Ce se întâmplă dacă un program se oprește


înainte de folosi unlock?
30
Uitarea lui unlock

Proces 1 Proces 2
// shared variables a and s // shared variables a and s
int a = 0; int a = 0;
int s; int s;
lock (s); lock (s);
if (a == 0)
{
a++;
}

printf ("%d\n", a);

... waits a lot

... 1 31
Folosirea lui de lock mai multe ori

Proces 1 Proces 2
// shared variables a and s // shared variables a and s
int a = 0; int a = 0;
int s; int s;
lock (s); lock (s);
lock (s);

... waits a lot ...waits a lot

... ... 32
Oprirea înainte de unlock

Proces 1 Proces 2
// shared variables a and s // shared variables a and s
int a = 0; int a = 0;
int s; int s;
lock (s); lock (s);
if (a == 0)
{
a++;
}

... waits a lot

... eroare 33
SEMAFOR

34
Spinlock

while (tsl(test, 1))


Spinlock
continue;
Busy Waiting

// do some work with

test = 0;

35
Busy Waiting

• Încarcarea în permanență de a verifica o


valoare

• CPU execută instrucțiuni inutil

• Procesul își va consuma toata cuanta de timp


pentu a verifica mereu valoarea

36
Stările proceselor

Spinlock

37
Stările proceselor

Așteptarea unei resurse

38
Semafor

• Obiect al SO

• Partajat între mai multe procese

• Funcții executate atomic


– P (încearcă) / wait / down
– V (eliberează) / signal / up

• Valoare inițială

• Coadă de procese care așteaptă

39
Funcțiile semaforului

void wait (s) void signal (s)


{ {
while (s <= 0); s = s + 1;
Busy waiting }
s = s - 1;
}
// s - semaphore

40
Variabilă de condiție

• Object cu două funcții


– block / wait
• oprește procesul curent
– starea WAITING

– wakeup / notify
• oprește toate procesele blocate de această variabilă
– starea READY

41
Stările proceselor

block

wakeup

42
Funcționarea semaforului

void wait (s) void signal (s)


{ {
while (s <= 0) s = s + 1;
block (s); wakeup (s);
s = s - 1; }
}
// s - semaphore

43
Tipuri de semafoare

• binare
– valoarea poate fi doar 0 sau 1

• contor
– naloare poate fi orice număr întreg

44
Semafor binar

void wait (s) void signal (s)


{ {
while (s == 0) s = 1;
block (s); wakeup (s);
s = 0; }
}
// s - semaphore

45
Exemplu

Proces 1 Proces 2
// shared variables a and s // shared variables a and s
int a = 0; int a = 0;
int s; int s;
wait (s); wait (s);
if (a == 0)
{
a++;
}
signal (s);
if (a == 0)
printf ("%d\n", a); {
a++;
}
signal (s);
printf ("%d\n", a);

1 1 46
Exemplu

Proces 1 Proces 2
// shared variables a and s // shared variables a and s
int a = 0; int a = 0;
int s; int s;
wait (s); wait (s);
if (a == 0)
{
a++;
}
signal (s);
if (a == 0)
{ printf ("%d\n", a);
a++;
}
signal (s);
printf ("%d\n", a);

1 1 47
Deadlock

Ce se întâmplă dacă uită să folosim signal?

Ce se întâmplă dacă folosim de mai multe ori


wait fără signal?

Ce se întâmplă daca un program se termină fără


să apeleze signal?
48
Uitarea lui signal

Proces 1 Proces 2
// shared variables a and s // shared variables a and s
int a = 0; int a = 0;
int s; int s;
wait (s); wait (s);
if (a == 0)
{
a++;
}

printf ("%d\n", a);

... waits a lot

... 1 49
Folosirea lui wait de mai multe ori

Processus 1 Processus 2
// shared variables a and s // shared variables a and s
int a = 0; int a = 0;
int s; int s;
wait (s); wait (s);
wait (s);

... waits a lot ...waits a lot

... ... 50
Oprirea înainte de signal

Proces 1 Proces 2
// shared variables a and s // shared variables a and s
int a = 0; int a = 0;
int s; int s;
wait (s); wait (s);
if (a == 0)
{
a++;
}

... waits a lot

... eroare 51
MUTEX

52
Mutex

• Mutual Exclusion

• Similar cu un semafor binar

• Utilizat pentru thread-uri (în aceelași proces)

53
lock și unlock

• lock
– acaparează mutex-ul și reține TID-ul care l-a
acaparat
• funcția lock este re-entrantă

• unlock
– eliberează mutex-ul
• la terminare (thread) mutex-ul este eliberat

54
Deadlock

Ce se întâmplă dacă uită să folosim unlock?

Ce se întâmplă dacă folosim de mai multe ori


lock fără unlock?

Ce se întâmplă daca un program se termină fără


să apeleze unlock?
55
Uitarea lui unlock

Proces 1 Proces 2
// shared variables a and s // shared variables a and s
int a = 0; int a = 0;
mutex s; mutex s;
lock (s); lock (s);
if (a == 0)
{
a++;
}

printf ("%d\n", a);

if (a == 0)
{
a++;
}
unlock (s);
printf ("%d\n", a);

1 1 56
Folosirea lui lock de mai multe ori

Proces 1 Proces 2
// shared variables a and s // shared variables a and s
int a = 0; int a = 0;
mutex s; mutex s;
lock (s); lock (s);
lock (s);
if (a == 0)
{
a++;
}
unlock (s);
printf ("%d\n", a);
if (a == 0)
{
a++;
}
unlock (s);
printf ("%d\n", a);

1 1 57
Oprirea înainte de unlock

Proces 1 Proces 2
// shared variables a and s // shared variables a and s
int a = 0; int a = 0;
mutex s; mutex s;
lock (s); lock (s);
if (a == 0)
{
a++;
}

if (a == 0)
{
a++;
}
unlock (s);
printf ("%d\n", a);

1 eroare 58
Spinlock vs semafor/mutex

Spinlock Semafor
• Implementat în user space • Implementat în kernel
• Busy waiting • Blochează procese
• Uitarea lui unlock • Uitarea lui notify

59
Sincronizarea în Java

class Run
{
private Object a;

public synchronized void runAlone ()


{
// run some work
}

public void run ()


{
synchronized (a)
{
// run some work using the variable a
}
}
}

60
Producător / Consumator

• zonă comună partajată


– unul sau mai mulți scriitori (producători)
– unul sau mai mulți cititori (consumatori)
– buffer/zonă cu mai multe celule
• diferență de viteză producători/consumatori
• networking, I/O, message passing

61
Buffer

https://blog.grijjy.com/2017/01/12/expand-
your-collections-collection-part-2-a-generic-
ring-buffer/ 62
Consumare

https://blog.grijjy.com/2017/01/12/expand-
your-collections-collection-part-2-a-generic-
ring-buffer/ 63
Producere

https://blog.grijjy.com/2017/01/12/expand-
your-collections-collection-part-2-a-generic-
ring-buffer/ 64
Producător / Consumator

Producător Consumator
lock(mutex); lock(mutex);
if (is_buffer_full()) if (is_buffer_empty())
wait(buffer_not_full,mutex); wait(buffer_not_empty, mutex);
produce_item(); consume_item();
signal(buffer_not_empty); signal(buffer_not_full);
unlock(mutex); unlock(mutex);

65
Sincronizare

• necesită suport hardware


– test and lock / compare and swap (TSL/CAS)

• acces exclusiv / serial


– spinlock
– mutex

• secvențiere / determinism / ordonare


– semafoare
• cozi de așteptare
– variabile condiție
– monitoare

66
Cuvinte cheie

• sincronizare • TSL (test and lock)


• multi core • CAS (compare and swap)
• determinism • cmpxchg
• condiție de cursă • lock
• TOCTOU • unlock
• acces exclusiv • signal
• busy waiting • wait
• variabilă de condiție • locking pe magistrală
• secvențiere • per-cpu variables
• acțiuni atomice • ring buffer
• mutex • producător-consumator
• spinlock • overhead de sincronizare

67
Întrebări

68
Sisteme de operare

Dispozitive de Intrare/Ieșire
Cuprins

• tipuri de dispozitive
• comunicarea cu
dispozitivele
• tipul de operații I/O
– kernel preemtiv/ne-preemtiv

2
Bibliografie

• Modern Operating Systems


– Capitolul 5
• 5.1
• 5.2
• 5.3
• Operating Systems Concepts
– Capitolul 13
• 13.1
• 13.2
• 13.3
• 13.4
• 13.5

3
Top view

4
Sistemul de Intrare și Ieșire

5
DISPOZIVE

6
Dispozitiv

• Controller
– un procesor care controlează dispozitivul
• probabil are firmware

• Registre (port-uri)
– pentru schimb de date

• Sistem de conectare

7
Registre

• data-in register
• data-out register

• status register
– READY / BUSY

• control register
– trimiterea comenzilor
8
Tipuri de dispozitive (transfer)

• Caracter
– transferul de date se face la nivel de byte

• Block
– transferul de date se face doar în blocuri

9
Tipuri de dispozitive (acces)

• Serial
– transferul de date se face doar serial
• nu se poate face seek

• Aleator
– transferul de date se face către orice poziție
• se poate face seek

10
Tipuri de dispozitive (timp)

• Sincron
– perifericul transferă date doar la cerere

• Asincron
– perifericul transferă date oricând

11
COMUNICAREA CU DISPOZITIVELE

12
Comunicarea cu dispozitivele

• Port mapped I/O


– spațiu de adrese separat de RAM
– instrucțiuni separate

• Memory mapped I/O


– partajarea spațiului de cu RAM
– aceeleași instrucțiuni pentru accesul la memorie

13
Sistemul de Intrare și Ieșire

14
Port Mapped I/O

15
Memory Mapped I/O

16
Port vs Memory Mapped I/O

Port Mapped Memory Mapped


• Spațiu de adrese diferit • Ocupă RAM

• Instrucțiuni speciale • Trebuie dezactivat cache-ul

• Mai rapid • Folosește memoria virtuală

• Magistrală mai complex

• Mai lent

17
Tipuri de interacțiune

• Programmed I/O (PIO)


– polling (busy waiting)
– interrupts

• Direct (Virtual) Memory Access


– DMA / DVMA

18
Polling

while (STATUS != READY);


for (int p = 0; p < BUFFER_SIZE; p++)
{
DATA_OUT = data[p];
while (STATUS != READY);
}

19
Interrupts

Se repetă

20
Interrupts
int p = 0, bool sending = false;

void handle_interrupt() {
if (p < BUFFER_SIZE) {
DATA_OUT = data[p]; p = p + 1;
}
else { disable_interupt(); sending = false; send_done(); }
}

bool send() {
if (!sending) {
p = 0; sending = true; enable_interrupt();
return true;
}
return false;
}

21
Direct Memory Access

22
Direct Memory Access
bool sending = false;

void handle_dma_interrupt () {
sending = false; disable_dma_interupt ();
send_done ();
}

bool send () {
if (!sending) {
sending = true;
DMA_DATA = &data;
DMA_LEN = BUFFER_SIZE;
enable_dma_interrupt ();
return true;
}
return false;
}
23
Direct Memory Access

• Nu încarcă procesorul

• Blochează din când în când magistrala


– Procesorul poate accesa memoria cache

24
Drivere

25
TIPURI DE OPERAȚII IO

26
Tipuri de operații IO

Sincrone Asincrone

27
Sincrone

• Blocante
– daca așteaptă date
– read, write

• Ne-blocante
– nu așteaptă date, întorc buffer gol
– read, write (O_NONBLOCK)

28
Secvența I/O

29
Subsistemul de IO

• Cache

• Buffer de date

• Rearanjarea cererilor

30
API DE INTRARE ȘI IEȘIRE

31
API

• Inițializare

• Control

• Transfer date

32
API Sincron

• Dispozitive block/character
– inițializare: open, close
– control: ioctl
– transfer: read, write

• Dispozitive de rețea
– inițializare: socket, shutdown
– control: setsockopt, getsockopt
– transfer: recv, send

33
API Asincron

• Dispozitive block/character
– inițializare: open, close
– control: ioctl
– transfer:
• read, write + select, poll, epoll
• aio_read, aio_write, aio_suspend

• Dispozitive de rețea
– inițializare: socket, shutdown
– control: setsockopt, getsockopt
– transfer: recv, send + select, poll, epoll

34
IO Completion Port

• Orice obiect: HANDLE


– fișier, socket, etc.

• Flag: OVERLAPPED

35
MSG_ZEROCOPY

if (setsockopt(fd, SOL_SOCKET,SO_ZEROCOPY,&one, sizeof(one)))


error(1, errno, "setsockopt zerocopy");

ret = send(fd, buf, sizeof(buf), MSG_ZEROCOPY);

Nu se mai copiază într-un buffer intermediar

36
Scatter

• Se iau mai multe cereri

• Se face un singur apel către dispozitiv

37
Cuvinte cheie

• dispozitiv caracter • operații asincrone


• dispozitiv block • dispozitiv rețea
• acces serial • subsistem IO
• acces aleator • PIO
• Port Mapped IO • DMA
• Memory Mapped IO • IOCompletion Port
• operații sincrone • zero-copy
• operații blocante • scatter

38
Întrebări

39
Sisteme de operare

Implementarea sistemelor
de fișiere
Contenu

• Fișiere
• Sisteme de fișiere
• Exemple
– DOS (FAT)
– Linux (ext)
– Windows (NTFS)

2
Bibliografie

• Modern Operating Systems


– Capitolul 6
• 6.3
• 6.4

• Operating Systems Concepts


– Capitolul 11
• 11.1 – 11.8

3
FIȘIER

4
Discul

• persistent

• dimensiune de stocare
mare

• tabel de blocuri

5
Sistem de fișiere

• transformă tabelul de blocuri în fișiere și


directoare

• structură de date utilizată de SO

6
Operații pe disc

partiționare
formatare montare backup

disc
fsck folosire

7
Partition

• Zonă contiguă

• Conține un sistem de fișiere

8
Tipuri de partiționare

• MBR – (Master Boot Record)


– partiții primare (maxim 4)
– partiție extinsă – poate fi în locul unei partiții
primare
– partiție logică – în interiorul partiției extinse
• GPT – (GUID Partition Table)
– nu are limită de partiții
– fiecare partiție are un GUID

9
MBR

10
GPT

11
SISTEM DE FIȘIERE

12
Sistem de fișiere

Aplicații
• fișiere și
directoare

Sistemul de
operare
• Structuri de date

13
Exemple de sisteme de fișiere

• ext3
• ReiserFS
• HFS
• NTFS
• FAT32
• ISO9660
• UDF

14
IMPLEMENTAREA

15
Discul

• Pagini
– Mai multe blocuri

• Bloc
– Unitatea de citire și scriere
– Sub-multiplu unei pagini de memorie
• (în general 512 B)

16
Partiția

• Pe o partiție sunt stocate


– date
– metadate

17
Folosirea

18
Structura sistemului de fișiere
Fișier

• Date
– Conțiunutul fișierului

• Metadate
– Informații despre fișier
– FCB – File Control Block

20
Director

• Un fișier special
– în general

• Date
– lista de fișiere

• Metadate
– Informații despre fișier
– FCB – File Control Block

21
Alocarea fișierelor

• Contiguă
– Fișierele sunt stocate una după alta
• Fragmentare

• Liste
– Fiecare bloc are un pointer către următorul bloc
• Viteză de acces redusă
• Evită fragmentarea

• Indexată
– FCB-ul conține o listă de pointeri către fiecare bloc de date
• Evită fragmentarea

22
Alocarea contiguă

• Similară cu alocarea contiguă de memorie

• Fișierele sunt alocate unul după altul


– Fragmentare
– Probleme la modificarea unui fișier

• Metdate (FCB)
– Pointer spre primul bloc al fișierului
– Numărul de blocuri alocate fișierului

• Implementare simplă
• Citire rapidă

23
Alocarea contiguă

Metadate

Date

24
Utilizare

• Sisteme de fișiere ReadOnly

• ISO 9660 (și alte variante)

25
Alocarea cu liste

• Similară cu alocarea contiguă

• Fiecare bloc are un pointer către următorul


– Probleme la modificarea fișierului
– Citire lentă

• Metadate (FCB)
– Pointer sper primul bloc al fișierului
– Pointer spre ultimul bloc al fișierului

• Nu există fragmentare
• Implementare simplă

26
Alocarea cu liste

metadate

date

27
Alocarea cu liste

28
Utilizare

• Sisteme de fișiere folosite de dispozitive


simple
– SD Card Arduino

• FAT
• FAT32
• vFAT

29
Alocare indexată

• Similară cu alocarea paginilor de memorie virtuală

• FCB-ul conține o listă de pointeri către blocurile de date ale


fișierului
– Numărul de pointeri către blocuri de date este limita de dimensiune
– Indirectare (similară cu tabelul de memoria virtuală)

• Metdate (FCB)
– Dimensiunea fișierlui
– Lista de pointeri spre blocurile de date ale fișierlui

• Nu are fragmentare

30
Alocare indexată

metadate

date

31
Utilizare

• Ext2,3,4
• NTFS
• RaiserFS
• HPFS
• AppleFS
• …

32
Exemplu de FCB (i-node)

33
Director
• Un fișier special
• Date
– listă de dentry (directory entry)
• Dimensiunea depinde de numărul de intrări
din listă
• . și .. sunt speciale

34
dentry

• Informații
– numele fișierlui
– id-ul fișierului (entry pentru FAT sau inode)
–…

• Windows
– WIN32_FIND_DATA

• POSIX
– struct dirent

35
Exemplu ext2

36
Link-uri

• Hard Links
– două structuri dentry spre aceelași i-node
– Nu se poate folosi între partiții diferite
• Sym Links (Soft Links)
– i-node special
– datele fișierului reprezintă numele (cu cale)
fișierului original

37
Exemple de link-uri

38
Spațiu liber

• Vector de biți
– 1 liber
– 0 ocupat
• Listă de blocuri
– Un bloc liber are un pointer către următorul bloc
liber
– Primul bloc liber este stocat

39
Exemplu

• disc de 512 GB
• bloc 512 B
• Adresa unui bloc are 32 biți
• Care este dimensiunea:
– Listei de blocuri
– Vectorului de biți

40
Buffer Cache

• Discul este mai lent decât memoria RAM

• SO folosește o memorie cache pentru a


eficientiza

• Buffer Cache

41
Buffer Cache

42
Unified Buffer Cache

43
Alte memorii cache

• i-node cache
– Pune în RAM inode-uri pentru a le putea accesa
mai rapid

• dcache
– Rezolvarea fișierelor

44
Consistența sistemului de fișiere

• Blocuri de date
– erorile nu sunt detectabile
– E numai problema fișierlului

• Blocuri de metadate
– erorile sunt detectabile
– Este problema sistemului de fișiere

45
fsck/scandisk

• Verifică toate blocurile


– Ia toate i-node-urile și marchează blocurile
ocupate

• Compară listele de inode-uri și blocuri ocupate


cu listele inițiale de inode-uri și blocuri libere

46
fsck/scandisk

• Pentru toate fișierele


– Scrie un tabel de referințe
– Ia toate structurile dentry și incrementează
referințele fiecărui inode in tabel
– Compară referința cu referința stocată în inode-ul
inițial

47
Exemplu fsck/scandisk

(a) consistent (c) bloc de date duplicat în


lista de blocuri libere
(b) bloc de date pierdut
(d) bloc de date duplicat
folosit
48
Sisteme de fișiere jurnalizate

• Operațiile unei tranzacții ce urmează a fi


efectuate sunt scrise într-un jurnal

• Operațiile executate sunt sunt marcate în


jurnal

• O tranzacție este completă când toate


operațiile sunt marcate în jurnal
49
Sisteme de fișiere jurnalizate

• La fiecare boot este verificat jurnalul iar


tranzacțiile sunt fie executate mai departe fie
sunt date înapoi

• Avantaje
– Reducerea timpului necesare la verificarea sistemului
de fișiere
– Reducerea posibilității de a pierde date la reboot

• Dezavantaje
– Sistemul de fișiere este mai lent
50
Virtual File System – VFS

• vnode – identifică în mod unic un fișier


– are și informații despre sistemul de fișiere pe care
se găsește fișierul

• Windows
– IFS

• Linux
– VFS

51
Virtual File System – VFS

52
Cuvinte cheie

• metadate • FAT
• date • inode
• pagini • dirent
• bloc • buffer cache
• partiție • fsck
• FCB • fdisk
• alocare contiguă • jurnal
• alocare cu liste • VFS
• alocare indexată • vnode

53
Întrebări

54

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