You are on page 1of 27

Sistemas Operativos apontamentos

Para Licenciatura em Informtica na Universidade Aberta

Captulo 1 Introduo
SO COMO MQUINA ESTENDIDA O hardware feio: apresenta interfaces complicadas,
inconsistentes e difceis, devidas ao facto de terem de operar sobre demasiados detalhes que so
diferentes de componente para componente, pelo que uma das funes dos SO esconder o
hardware dos programadores, apresentando uma interface elegante e consistente, para que possam
trabalhar sobre ela.
SO COMO GESTOR DE RECURSOS O SO fornece uma alocao ordeira e controlada dos
recursos de hardware para serem partilhados eficientemente entre todas as aplicaes a correr no
hardware. Nos sistemas multi-utilizadores, esta partilha estende-se partilha justa dos recursos
entre os utilizadores. A gesto de recursos inclui a multiplexagem (partilha) quer em tempo quer
em espao. A multiplexagem em tempo inclui, por exemplo, a partilha de tempo do processador
entre os vrios programas, ao passo que a multiplexagem em espao pode incluir a partilha do
espao em memria ou no disco. Isto levanta questes de justia e proteco, que cabe ao SO gerir.
HISTRIA DOS SO
1 gerao: vlvulas: 1945-55; sem SO ou linguagens de programao; primeiros computadores;
no incio da dcada de 50 foram introduzidos os cartes perfurados que permitiam escrever
programas, em vez de programar os computadores atravs de ligaes de cabos (estilo PBX).
2 gerao: transstores e sistemas de lote (batch): 1955-65; incio da produo comercial de
computadores (mainframes), para grandes empresas, universidades e instituies governamentais.
Os programas eram feitos em FORTRAN ou assembly, em cartes perfurados, corridos um de cada
vez. Inventado o batch system em que um computador lia uma srie de trabalhos em cartes
perfurados, copiava-os para fita magntica que era introduzida noutro computador mais potente e
que colocava o resultado noutra fita magntica que era em seguida levada para outro computador
que faria a sua impresso.
3 gerao: circuitos integrados e multiprogramao: 1965-80; inventada a multiprogramao,
a capacidade de ter vrios programas alojados em memria, cada qual na sua partio enquanto
uns aguardavam pela finalizao de processos de entrada ou sada (I/O), outros podiam estar a usar
o processador.
Inventado o spooling (Simultaneous Peripheral Operation On-Line) leitura de um trabalho em
cartes perfurados para o disco assim que ele fosse introduzido, permitindo a sua passagem para a
memria e execuo assim que outro termissae. Esta tcnica continua a ser usada para o
atendimento de vrios sistemas de I/O, nomeadamente as impressoras.
Incio da utilizao de timesharing, um conceito baseado na multiprogramao, que permitia a
partilha entre vrios utilizadores do tempo de processador baseado na utilizao que lhes estavam a
dar. CTSS (Compatible Time Sharing System MIT) MULTICS (MULTiplexed Information
and Computing Service MIT, Bell, GE) UNIX (Ken Thompson, Bell) BSD vs System V
(UC, Berkeley / AT&T) POSIX (IEEE) Minix, Linux, etc.
4 gerao: Computadores Pessoais: (1980-); com o fabrico de processadores em integrados de
larga escala de integrao (LSI), como o i8080 ou Z80, apareceram os microcomputadores e seus
SO: CP/M (Control Program for Microcomputers, Gary Kildall/Digital Research) DOS/MSDOS (IBM PC, Microsoft); com a inveno das GUI (Engelbart/Stanford, adoptada pela Xerox)
surgiram os PC com interfaces amigveis como Apple Macintosh e Windows. Windows NT/2000
Vista. Linux/Free BSD, GUI-> X Window System.

PROCESSOS programa em execuo; cada processo tem associado o seu espao de


endereamento que contm o prprio programa, os seus dados e a sua pilha (stack); associado ao
processo est normalmente um conjunto de informaes e dados, como sejam o estado dos registos,
incluindo SP e PC, lista de ficheiros abertos, lista de processos relacionados e alarmes activos; um
processo , portanto, um contentor com tudo o que um programa necessita para ser executado.
O SO guarda usualmente a informao sobre cada processo em execuo na tabela de processos.
Em alguns SO possvel a um processo criar outros processos, assim chamados de processos
filhos, criando-se uma rvore de processos, que comunicam entre si (interprocess communication
IPC). As chamadas ao sistema que lidam com processos esto normalmente relacionadas com a
criao e remoo de processos. tambm possvel que o sistema envie sinais de alarme a um
processo, que fazem com que este pare o que estava a fazer, guardando toda a informao
necessria para o reatar depois e execute uma funo especial de atendimento do alarme (signal
handling procedure). Estes alarmes podem ser ou no solicitados pelo prprio programa (ex:
avisar que um determinado recurso j est disponvel ou existem dados num determinado ficheiro
de entrada). O SO guarda tambm informao sobre o utilizador (UID) que lanou o processo e
grupo a que este pertence (GID), para avaliar as suas permisses. Em UNIX existe um utilizador
(superuser) que pode violar muitas destas regras.
Apenas o kernel pode correr em modo supervisor, ncleo ou protegido (kernel mode), tendo acesso
a todas as instrues do processador. Os processos normais correm em modo de utilizador (user
mode). Neste modo todas as instrues de I/O e proteco de memria esto desactivadas. Todos
os processadores, excepto os mais simples, como os dos sistemas embebidos, tm estes dois modos
de funcionamento. Para passar de um modo para outro executa-se a instruo TRAP, que, como um
interrupt, consulta uma tabela para correr uma rotina em modo protegido.
ESPAOS DE ENDEREAMENTO Em sistemas que permitem a execuo de vrios
programas simultaneamente, cada processo necessita de ter a sua rea de memria protegida da
aco de outros processos, o que habitualmente responsabilidade do hardware. Como interface
para os programas o SO fornece e gere um espao de endereamento a cada processo, com
endereamentos a partir do 0 at um limite, que pode ser maior que a memria fsica disponvel,
atravs da utilizao de memria virtual.
Em UNIX os processos tm o seu espao de endereamento dividido em trs segmentos: o
segmento de texto, onde se situa o cdigo do programa, o segmento de dados, ou seja, as
variveis, e o segmento da pilha. O segmento de dados situa-se habitualmente logo a seguir ao
segmento de dados e cresce para cima, consoante necessrio. O segmento da pilha situa-se
normalmente no fim do espao de endereamento e cresce para baixo, estando vazio no incio e
indo aumentando e diminuindo medida que o programa executa as suas funes.
FICHEIROS o sistema de ficheiros uma abstraco presente na maioria dos SO, escondendo
as peculiaridades do acesso a discos e outros dispositivos de E/S. Isto feito atravs de chamadas
ao sistema para criar, remover, abrir, fechar, ligar, ler e escrever em ficheiros. Muitos SO fornecem
tambm o conceito de directoria, que uma forma de agrupar os ficheiros numa estrutura
hierrquica semelhante a uma rvore. Existem chamadas ao sistema para criar e remover
directorias vazias, bem como para colocar e remover ficheiros de directoria. Cada directoria pode
conter ficheiros e outras directorias.
Path name (caminho): lista de directorias desde o topo (directoria raiz ou root) at directoria
onde se encontra um ficheiro (ex: /home/antonio/uab/so/puc.pdf).
Working directory (directoria de trabalho): cada processo tem definida, a qualquer instante, a
sua directoria de trabalho, que significa a directoria a partir da qual todos os caminhos relativos
so calculados. Na ausncia deste conceito todos os ficheiros teriam de ser referidos pelo seu
caminho absoluto, o que poderia tornar-se inconveniente para o utilizador.
Mounted file system: sistema de ficheiros que montado a pedido, em UNIX, numa directoria do

sistema de ficheiros raiz, normalmente situado num qualquer dispositivo amovvel (ex: CDROM).
Desse modo permite-se que os ficheiros nesse dispositivo sejam acedidos como se pertencessem ao
sistema de ficheiros habitual.
Special file: conceito em UNIX que permite que dispositivos de E/S sejam acedidos como se
fossem ficheiros no sistema de ficheiros, simplificando assim a sua utilizao por programadores, j
que podem usar as mesma chamadas ao sistema que usam para aceder ao sistema de ficheiros.
Existem dois tipos de ficheiros especiais: block special files, para aceder a dispositivos que
suportam acesso aleatrio (discos) e character special files, para os dispositivos que apenas
suportam acesso sequencial, como impressoras, modems, etc.
Pipe: pseudo-ficheiro para comunicao entre processos. Desta forma, em UNIX, a comunicao
entre processos pode ser efectuada de maneira muito semelhante a escrita e leitura de ficheiros.
ENTRADA/SADA todos os SO tm um subsistema para gerir os dispositivos de entrada e
sada, como teclado, rato, monitor, etc.
PROTECO O SO responsvel por gerir a proteco de ficheiros e outros recursos entre os
diversos utilizadores e grupos de utilizadores. tambm da sua responsabilidade a proteco
contra ameaas externas, como vrus e worms.
CHAMADAS AO SISTEMA o mecanismo que fornece a abstraco do hardware aos
programadores.
Procedimento: para uma chamada ao sistema, o processo tem de colocar na pilha os parmetros da
chamada e chamar a funo de biblioteca correspondente funo desejada. Esta coloca o cdigo
(nmero) da funo desejada num local onde o SO a espera e executa um Trap ao kernel (instruo
TRAP, funciona como um interrupt e passa o modo de operao de modo utilizador user mode
para modo protegido kernel mode). O SO ento, atravs do cdigo da funo, salta para a funo
de atendimento (system call handler), que l os parmetros passados, executa a funo e devolve a
execuo para a funo de biblioteca, que o devolve ao processo que chamou.
Chamadas ao sistema (POSIX):
Gesto de processos:

pid = fork() : criar processo filho semelhante ao pai

pid = waitpid(pid, &statloc, options) : esperar que processo filho termine

s = execve(name, argv, envirnp) : substituir imagem (core image) do processo

exit(status) : terminar processo e devolver estado

Gesto de ficheiros:

fd = open(file, how, ) : abrir ficheiro para leitura, escrita ou ambos

s = close(fd) : fechar ficheiro

n = read(fd, buffer, nbytes) : ler dados de um ficheiro para um buffer

n = write(fd, buffer, nbytes) : escrever dados de um buffer para um ficheiro

position = lseek(fd, offset, whence) : mover o apontador do ficheiro

s = stat(name, &buf) : ler estado de um ficheiro

Gesto de directorias e do sistema de ficheiros:

s = mkdir(name, mode) : criar nova directoria

s = rmdir(name) : remover directoria vazia

s = link(name1, name2) : criar nova entrada name1 a apontar para name2

s = unlink(name) : remover uma entrada da directoria

s = mount(special, name, flag) : montar sistema de ficheiros

s = umount(special) : desmontar sistema de ficheiros

Outras:

s = chdir(dirname) : mudar de directoria de trabalho

s = chmod(name, mode) : alterar permisses

s = kill(pid, signal) : enviar sinal a processo

seconds = time(&seconds) : nmero de segundos desde 1/1/1970

Captulo 2 Processos e tarefas (threads)


Pseudo-paralelismo: ter vrios processos a correr simultaneamente no mesmo processador, por
oposio a paralelismo de hardware, em que vrios processos correm simultaneamente em
processadores diferentes.
MODELO DE PROCESSOS modelo conceptual em que todo o software no computador
dividido em processos sequenciais ou processos. Conceptualmente, cada processo tem o seu
processador virtual, incluindo registos, variveis, program counter, etc. Na realidade o sistema
operativo gere todos os processos, fazendo o processador saltar de um para outro, ao que se chama
multi-programao. Cada processo , ento, uma instncia de um programa em execuo.
CRIAO DE PROCESSOS
Ao iniciar o sistema: vrios processos so criados quando o sistema inicia. Os processos que ficam
a correr em background chamam-se daemons.
Execuo de uma chamada ao sistema por outro processo: um processo pode fazer uma
chamada ao sistema para criar um novo processo. Em UNIX a chamada ao sistema fork(), que
cria um novo processo que uma cpia exacta do pai; depois da criao, o novo processo chama
usualmente uma variante da funo excve(), que substitui o programa por outro. Em Windows a
funo para criar um novo processo CreateProcess().
Novo processo criado pelo utilizador: criar novo processo ao lanar um programa.
Novo processo criado pelo sistema na execuo de um batch job
Na realidade, de um ponto de vista tcnico, todos os processos so criados por uma chamada ao
sistema efectuada por outro processo j existente. Mesmo os novos programas lanados pelo
utilizador so criados pelo processo da shell (interpretador da linha de comando) ou ambiente
grfico.
TERMINAR PROCESSOS os processos podem terminar de 2 formas voluntrias (em UNIX
chamada da funo de sistema exit() ou TerminateProcess() em Windows) (1) quando o programa
termina a sua funo ou o utilizador termina o programa e (2) quando encontra um erro e 2 formas
involuntrias (1) quando ocorre um erro fatal (ex: diviso por zero, acesso a memria fora do seu
alcance) ou (2) quando outro processo, com a devida autorizao, o termina (chamada de sistema
kill() em UNIX ou TerminateProcess() em Windows). Em alguns sistemas os processos terminam
todos os processos filhos ao terminar, mas tal no acontece em UNIX nem em Windows.

ESTADO DOS PROCESSOS os processos esto em qualquer instante num de trs estados: (1)
a correr (running), ou seja, usando o processador no prprio instante, (2) prontos (ready), ou seja,
parados temporariamente enquanto o processador corre outros processos, aguardando que o
scheduler transfira a execuo para si e (3) bloqueados (blocked), impossibilitados de correr at ao
ocorrer de um evento externo, normalmente a chegada de dados de entrada ou a concluso de um
processo de escrita, etc.
A passagem entre ready e running efectuada apenas pelo scheduler, sendo portanto este que
decide qual processo deve correr em cada momento. A passagem de ready para blocked
normalmente efectuada pelo processo (chamadas ao sistema pause() ou wait()) ou
automaticamente pelo sistema operativo (ex: UNIX), quando detecta que um processo no pode
correr enquanto outro evento externo no ocorrer (ex: input de dados). A passagem de blocked para
ready acontece quando ocorre o evento por que o processo aguardava, normalmente por interrupt;
se no houver mais nenhum processo a correr, o scheduler pode passar o processo para running.
Nunca h passagem de blocked para running, porque apenas o scheduler pode passar um processo
para execuo.
Usando o modelo de processos torna-se mais fcil pensar no que ocorre num sistema, pois em
vez de se pensar nas interrupes (interrupts) e nos programas, tudo pode ser encarado como
processos, a correr ou aguardando que ocorra o evento pelo qual esto espera. Ex: processo do
disco (aguardando que cheguem dados do disco), processo do teclado (aguardando que cheguem
dados do teclado), etc. Este modelo pode ser visto como um sistema em que o scheduler o
processo base que vai distribuindo o servio por todos os outros processos que correm em paralelo.
No entanto, poucos sistemas reais seguem este modelo risca.
IMPLEMENTAO DE PROCESSOS O sistema tem uma tabela process table com uma
entrada por processo process control block. Cada entrada contm toda a informao sobre o
estado do processo que deve ser guardada aquando da transio de processo entre os diversos
estados (blocked, running, ready): program counter, stack pointer, memria alocada, estado dos
ficheiros abertos, informao sobre o tempo alocado (scheduling), etc.
A taxa de utilizao do processador num ambiente de multi-programao pode ser obtida de forma
aproximada usando a seguinte forma probabilstica
Utilizao de CPU = 1 pn
em que p a fraco de tempo que cada processo passa a aguardar por I/O e n o nmero de
processos a correr. Ex: se o sistema tem 4 processos que passam 80% do tempo parados, a
utilizao de CPU seria: 1 (0,8)4 = 0,5904 ~ 60% de utilizao.
COMPORTAMENTO DOS PROCESSOS (em relao ao scheduling) os processos podem
ser de computao intensiva (compute-bound) ou de entrada/sada intensiva (I/O-bound). Nos
primeiros o processo passa a maior parte de tempo usando o processador e pouco tempo espera de
processos de E/S; nos segundos passa-se o inverso. Uma vez que o tempo de acesso ao disco ou a
outros componentes de E/S o mesmo para todos os processos, o que varia a necessidade de
acesso ao processador sendo, portanto, importante o desempenho dos algoritmos do scheduler.
Como os processadores esto a tornar-se mais rpidos mais depressa que os discos rgidos,
provvel que os algoritmos de calendarizao dos processos de E/S ganhem importncia (I/O
scheduling).
ALGORITMOS DE SCHEDULING podem ser no-preemptivos (nonpreemptive), que
correm um processo at este bloquear, s ento passando ao seguinte, ou preemptivos (preemptive)
que deixam um processo correr apenas um determinado perodo de tempo, passando ao seguinte
aps esse tempo independentemente do processo a correr ter bloqueado ou no. Os algoritmos
preemptivos dependem da existncia de um interrupt de relgio nas mquinas em que no esteja
presente no se pode usar este tipo de algoritmos.

Vrios tipos de sistemas tm diferentes expectativas dos algoritmos de scheduling. Sistemas de lote
(batch systems) podem usar algoritmos no preemptivos ou preemptivos com grandes tempos de
utilizao para cada processo, j que no h utilizadores espera da resposta a um comando e o
trabalho de cada processo normalmente conhecido e de processamento de grande quantidade de
dados. Sistemas interactivos, por outro lado, necessitam de algoritmos preemptivos, para que
nenhum processo se apodere do processador, impedindo o acesso a outros processos ou utilizadores,
seja pela tarefa que est a executar ou por algum bug. Os servidores enquadram-se neste tipo, bem
como sistemas pessoais. Os sistemas operativos de tempo real no necessitam normalmente de
sistemas preemptivos, j que cada processo corre normalmente por perodos pr-determinados e
curtos de tempo, devolvendo o controlo ao sistema (bloqueando) em seguida. Nestes sistemas
apenas correm processos para levar a cabo a tarefa actual, ao contrrio dos sistemas interactivos que
so de utilizao genrica, no se sabendo, por isso, partida quais os processos que estaro a
correr em cada momento.
OBJECTIVOS DOS ALGORTIMOS DE SCHEDULING
Todos os sistemas: Justia processos idnticos devem receber tempo de CPU idntico;
Aplicao de poltica assegurar-se que a poltica de recursos pr-determinada levada a cabo;
Equilbrio assegurar-se que todos os componente do sistema estejam ocupados durante todo o
tempo.
Sistema de lote: Throughput maximizar o nmero de tarefas por hora; Tempo de entrega
(turnaround time) minimizar o tempo entre a submisso da tarefa e o seu trmino; Utilizao de
CPU Manter o processador ocupado durante todo o tempo.
Sistemas interactivos: Tempo de resposta responder rapidamente aos pedidos;
Proporcionalidade cumprir com as expectativas dos utilizadores.
Sistemas de tempo real: Cumprir prazos no perder dados; Previsibilidade evitar a
degradao de qualidade em sistemas multimdia.
ALGORITMOS DE SCHEDULING PARA PROCESSAMENTO EM LOTE
First-come First-served: no preemptivo, o mais simples, baseando-se numa lista ligada de
trabalhos; cada vez que um termina ou bloqueia retirado o primeiro da lista para colocar em
execuo; quando pedida a execuo de um novo processo ou um processo sai da condio de
bloqueado para a de pronto, esse processo colocado no fundo da lista.
Tem como inconveniente que um processo com uma utilizao intensiva do processador e baixa
utilizao de dispositivos de I/O pode aambarcar o processador, impedindo que os outros
processos recebam o tempo justo de acesso.
Shortest Job First: tambm no preemptivo, baseia-se no conhecimento antecipado do tempo que
cada processo demora a correr. Ir correr primeiro o processo mais pequeno, deixando o maior para
o fim, maximizando dessa forma o turnaround time. Esse objectivo pode no ser atingido se no se
puder prever a ordem de chegada dos processos. S eficaz se todos os processos estiverem
disponveis simultaneamente.
Shortest remaining time next: uma verso preemptiva do algoritmo anterior e baseia-se tambm
no conhecimento prvio do tempo que cada processo tem ainda para correr. Se o trabalho a chegar
demorar menos tempo a terminar do que o que falta correr ao processo em execuo, este
suspenso, iniciando-se a execuo do novo processo. Este esquema permite que pequenos trabalhos
sejam executados muito rapidamente.
ALGORITMOS DE SCHEDULING PARA PROCESSOS INTERACTIVOS
Round robin: algoritmo em que a cada processo atribudo um determinado perodo de tempo
(igual para todos), chamado quantum. Existe um lista de processos que vo correndo vez, sendo
interrompidos quando terminam, bloqueiam ou chega ao fim o seu quantum, passando-se o prximo

processo para execuo e o processo anterior para o fim da lista. A nica situao interessante neste
mtodo a escolha do valor do quantum: se for demasiado baixo ir levar a uma ineficincia da
utilizao do processador, j que este passar a maior parte do tempo a tratar da mudana de
processo em execuo (process ou context switching) guardar e carregar registos, mapas de
memria, actualizar vrias tabelas e variveis, actualizar a cache de memria, etc; por outro lado, se
for demasiado alto ir diminuir a resposta do sistema, j que com uma grande quantidade de
processos ir passar muito tempo entre a execuo dos primeiros e ltimos da lista. Outro factor
que se o valor for ligeiramente superior do tempo mdio de burst do processador, no ser
necessria a preempo j que cada processo ir bloquear antes de terminado o seu quantum. Em
geral deve, portanto, escolher-se um compromisso entre a utilizao eficiente do processador e a
percepo de interactividade por parte dos utilizadores.
Priority scheduling: Baseia-se na atribuio de uma prioridade a cada processo, correndo os de
maior prioridade primeiro. As prioridades podem ser atribudas estaticamente, dependendo, por
exemplo da importncia do dono (utilizador) do processo segundo a hierarquia numa organizao
ou aluguer pago num sistema comercial multi-utilizador ou da importncia relativa de cada
processo um processo a correr uma tarefa rotineira em background menos importante que uma
tarefa interactiva. Para evitar que processos com uma alta prioridade monopolizem todo o tempo de
processador, o valor de prioridade pode ser decrementado a cada tick do relgio do sistema. As
prioridades podem tambm ser definidas dinamicamente pelo sistema operativo. Por exemplo, a
um processo que passe a maior parte do seu tempo em tarefas de I/O, pode ser atribuda uma alta
prioridade, permitindo que outros processos corram em simultneo, j que esse processo ir
bloquear logo que lhe seja atribudo o processador. Um algoritmo simples de atribuir prioridade
dinamicamente usando a frmula 1/f, em que f a fraco do quantum que o processo usou na sua
ltima execuo. Assim, aos processos que use uma pequena fraco do seu tempo antes de
bloquearem ser atribuda uma alta prioridade, enquanto aos que usem todo o seu tempo uma
prioridade mais baixa.
Por vezes, til dividir os processos em classes de prioridade, usando priority scheduling entre as
classes mas round robin para correr os processos dentro de cada classe. Desta forma podem correrse primeiro todos os processos da classe de prioridade mais alta, depois o da classe seguinte, etc. Se
as prioridades no forem ajustada periodicamente, os processos nas classes mais baixas de
prioridade podero nunca correr.
Multiple queues Vrios algoritmos de scheduling de prioridade tm sido usados. Um dos
primeiros no CTSS (MIT), foi influenciado pelo tempo longo que o processador demorava a trocar
de processo, j que apenas um processo podia estar em memria a cada altura, obrigando a que
todos os outros estivessem em spooling no disco e tivessem de ser copiados da para a memria e
vice-versa a cada transio de processos. Este algoritmo atribua uma prioridade menor quanto
mais tempo de processador cada processo usasse, mas dobrava o nmero de quantums em que esse
processo correria da prxima vez sempre que este usava todo o tempo disponvel, diminuindo dessa
forma o nmero de context switches necessrios. Outros algoritmos foram desenvolvidos: por
exemplo, o XDS 940, de Berkeley, dividia os processos em quatro classes: terminal, I/O, quantum
curto e quantum longo. Quando um processo bloqueado espera de interaco do utilizador
acordava, era colocado na primeira classe de prioridade; quando um processo espera de dados de
I/O era acordado, colocava-se na segunda classe; quando um processo usava todo o seu quantum de
processador, era colocado na terceira classe e se o fizesse demasiadas vezes seguidas seria colocado
na quarta classe de prioridade.
Shortest process next Baseia-se na observao de que executando o menor trabalho primeiro
diminui o tempo de resposta dos sistemas (ver algoritmos de scheduling para processamento em
lote). necessrio estimar o tempo de execuo de cada processo o que pode ser feito atravs da
soma pesada do tempo de execuo dos ltimo processo e da estimativa anterior de cada utilizador
usando a frmula: aT0 + (1-a)T1. Da escolha do valor de a depende o tempo que o clculo demora
a esquecer o tempo de execuo dos processos mais antigos. Por exemplo, se a for as estimativas

sucessivas seriam:
T0, T0/2 + T1/2, T0/4 + T1/4 + T2/2, T0/8 + T1/8 + T2/4 + T3/2, etc.
A tcnica de estimar o prximo valor numa srie atravs mdia pesada do valor corrente com a
estimativa anterior chamada envelhecimento (aging) e aplicada frequentemente quando
necessrio produzir um valor baseado em estimativas anteriores. facilmente implementada
usando um valor de para a: basta somar o valor actual e dividir por dois (shift right 1 bit).
Guaranteed scheduling Algoritmo que garante que uma determinada poltica de performance ir
ser cumprida. Uma poltica de fcil implementao garantir que a cada utilizador ser atribudo
um tempo de processamento igual e que o mesmo acontecer a cada processo de cada utilizador
individual para tal basta dividir o tempo disponvel pelo nmero de utilizadores e, para cada um, o
seu tempo pelo nmero de processos. Uma vez que se sabe o tempo de processador que cada
processo j teve, fcil calcular a razo entre o tempo que cada processo usou efectivamente e o
tempo a que, em teoria, teria direito. O algoritmo deve ento correr o processo com a menor razo
at que essa razo ultrapasse a do processo com o menor valor seguinte, passando ento a execuo
para esse processo.
Lottery scheduling O algoritmo de guaranteed scheduling de difcil implementao, apesar de
ser uma boa ideia. Uma alternativa o lottery scheduling: este atribui um nmero de bilhetes de
lotaria a cada processo, fazendo um sorteio a cada context switching para descobrir qual o processo
que deve correr a seguir. Atribuindo mais bilhetes aos processos mais importantes pode ainda
implementar-se uma forma de priority scheduling, uma vez que cada processo tem uma
probabilidade de ser escolhido para correr proporcional ao nmero de bilhetes que possui. Isto
apresenta como vantagem sobre o priority scheduling clssico o facto de aqui ser fcil saber o que
significa uma prioridade de 40% (por exemplo): quer dizer que possui essa percentagem dos
bilhetes disponveis. Alguns sistemas possibilitam ainda que os processos possam oferecer os seus
bilhetes a outros processos por exemplo, um programa cliente que bloqueie espera da resposta
de um servidor, pode oferecer todos os seus bilhetes ao servidor, aumentado assim as possibilidades
que este lhe responda rapidamente; quando o servidor termina a sua tarefa pode devolver os bilhetes
restantes ao cliente (um servidor sem clientes no necessita de tempo de execuo). Este algoritmo
pode ser usado para solucionar problemas de prioridade difceis de resolver por outros meios (ex:
um servidor de vdeo a servir trs processos a 10, 20 e 25 fps pode atribiuir 10, 20 e 25 bilhetes a
cada um, garantindo assim que o tempo de CPU ser divido aproximadamente nessa proporo).
Fair share scheduling Os algoritmos anteriores dividem o tempo disponvel pelo nmero de
processos, no levando em conta que um utilizador pode ter mais processos em execuo que outro.
O algoritmo de fair share scheduling divide o tempo de CPU equalitariamente entre utilizadores,
independentemente do nmero de processos de cada um.
ALGORITMOS DE SCHEDULING PARA SISTEMAS DE TEMPO REAL
Um sistema de tempo real caracteriza-se por ser um sistema em que cada processo deve realizar o
seu trabalho num perodo de tempo perfeitamente previsvel e conhecido a priori. So geralmente
divididos em hard real time, em que todas as deadlines tm de ser escrupulosamente cumpridas, e
em soft real time, em que falhar uma deadline, no desejvel mas tolervel ocasionalmente. O
tempo real conseguido em ambas dividindo um programa em processos de curta durao e de
comportamento previsvel e conhecido antecipadamente. O trabalho do scheduler ordenar os
processos de tal forma que todas as deadlines sejam cumpridas em resposta aos eventos externos.
Os eventos externos podem ser peridicos (ocorrem a perodos fixos) ou aperidicos (ocorrem
imprevisivelmente). Para um sistema conseguir responder a eventos peridicos a sua carga tem de
cumprir a frmula, considerando que o tempo de context switching negligencivel:
m

P i 1
i=1

em que m representa o nmero de eventos peridicos, Pi o periodicidade de cada evento e Ci o


tempo de CPU que cada processo gasta a processar o respectivo evento. Caso esse critrio seja
cumprido, diz-se que o sistema shedulable.
Os algoritmos de scheduling de sistemas de tempo real podem ser estticos, em que as decises de
scheduling so tomadas a priori, ou dinmicos, em que as decises so tomadas durante a execuo.
Os algoritmos estticos necessitam que o conhecimento antecipado do trabalho seja perfeito.
POLTICA vs. MECANISMO DE SCHEDULING
Nenhum dos mecanismos anteriores leva em linha de conta que cada processo pode conhecer a
importncia de cada um dos seus filhos, no permitido assim ao sistema operativo adequar o tempo
atribudo a cada um baseado nesse critrio. A soluo passa por separar o mecanismo de
scheduling da poltica de scheduling, um princpio bastante antigo. Isto conseguido permitindo
a cada processo parametrizar o scheduler para os seus filhos. Desta forma, o processo pai pode
controlar detalhadamente a prioridade atribuda aos seus filhos, embora o scheduling continue a ser
feito pelo sistema operativo, separando-se assim a poltica de scheduling do mecanismo que a
implementa.
THREADS
Tal como os processos, estes so mini-processos que correm de forma quase paralela dentro de um
processo, distinguindo-se apenas pelo facto de partilharem o mesmo espao de endereamento,
permitindo assim partilhar variveis e ficheiros.
Razes para a utilizao de threads:
1. Algumas aplicaes pode ser decompostas em actividades que ocorrem simultaneamente;
dividindo o processo em entidades que correm quase paralelamente torna o modelo de
programao mais simples. A diferena entre fazer isso usando processos e threads
precisamente o facto destes partilharem o mesmo espao de endereamento (dados,
variveis, etc.)
2. Os threads so mais leves que os processos: tipicamente, a sua criao e destruio entre
10 a 100 vezes mais rpidas que as de processos. Em aplicaes onde o nmero de tarefas
se altere dinmica e frequentemente, isso realmente importante.
3. Quando todos os threads so de processamento intensivo, no apresentam qualquer ganho
em relao utilizao de processos. No entanto, se houver uns de processamento intensivo
e outros de utilizao substancial de I/O, a utilizao de threads permite que a sua execuo
se sobreponha, levando a ganhos de performance significativos.
4. Em sistemas com mais de uma CPU, a utilizao de threads permite que eles se distribuam
pelos processadores disponveis, efectivamente correndo em paralelo.
Modelos de programao de processos:
1. Threads: paralelismo, chamadas ao sistema bloqueiam;
2. Processo de um nico thread: sem paralelismo, chamadas ao sistema bloqueiam;
3. Mquina de estados-finitos (finite-state machine): paralelismo, chamadas ao sistema no
bloqueiam.
Nos dois primeiros modelos, cada thread ou processo pode ser visto como um programa sequencial,
em que cada chamada ao sistema bloqueia, esperando que o sistema responda. O terceiro modelo,
pelo contrrio, requer a utilizao de interrupts e chamadas ao sistema que no bloqueiam, tornando
a programao mais complexa, embora conseguindo uma alta performance, semelhante ao modelo
de threads.
Os threads so ainda teis no caso de processos que requeiram a leitura de dados, uma qualquer

computao intensiva sobre eles e a escrita do resultado. No caso de programao com um nico
thread, o processo iria bloquear cada vez que necessitasse ler ou escrever dados no disco.
Utilizando threads, pode ter-se um para ler dados do disco e coloc-los na memria para
processamento, outro para ler os dados da memria de entrada, process-los e escrever o resultado
num buffer de sada e ainda outro para para ler os dados dos buffer de sada e escrev-los no disco.
Desta forma as trs tarefas tornam-se independentes, podendo ocorrer em paralelo isto s
possvel se as chamadas ao sistema bloquearem cada thread individualmente e no todo o processo.
MODELO CLSSICO DE THREADS Os processos usam-se para agrupar os recursos usados
por cada programa, para dar ao programador a iluso de que est a trabalhar sozinho num
computador. Assim, cada processo tem para si:

espao de endereamento

variveis globais

ficheiros abertos

processos filhos

alarmes pendentes

sinais e funes de atendimento de sinais (signal handlers)

informao de contabilizao (accounting information)

Para alm disso tem tambm um caminho, ou thread, de execuo, com:

contador de programa (program counter)

registos

stack

estado

Este thread de execuo independente para cada processo. O que se passa no modelo clssico de
threads que cada processo pode criar e destruir vrios caminhos de execuo que so chamados de
processos leves (lightweight processes), separando assim os recursos de cada caminho do resto dos
recursos do processo, comuns a todos os seus threads. O termo multithreading usado para
descrever a situao em que um processo tem vrios threads em execuo. Tal como um processo,
cada thread pode estar na situao de bloqueado, pronto, em execuo ou terminado.
Uma vez que todos os threads de um processo partilham o mesmo espao de endereamento, os
mesmos ficheiros abertos e as mesmas variveis globais necessrio algum cuidado na sua
programao, para que um thread no use um recurso que invalide a tarefa que outro thread, na
altura bloqueado, se encontra a executar.
POSIX THREADS
Norma 1003.1c do IEEE, consistindo no pacote Pthreads, que define um conjunto de funes para
a implementao portvel de threads e que suportada pela maior parte dos sistemas UNIX. Todos
os threads Pthreads possuem um conjunto de propriedades, incluindo um identificador, os registos
(incluindo o program counter) e um conjunto de atributos, armazenados numa estrutura, tais como
tamanho do stack, parmetros de scheduling e outros.
Chamadas de sistema do pacote Pthreads:

Pthread_create(): criar um novo thread; devolve o identificador do thread criado.

Pthread_exit(): terminar o thread que chamar a funo, libertando o seu stack.

Pthread_join(): esperar que um thread especfico (identificador passado como parmetro)

termine (equivalente a wait()).

Pthread_yield(): sinalizar que a execuo pode passar para outro thread.

Pthread_attr_init(): criar e inicializar uma estrutura de atributos para um novo thread.

Pthread_attr_destroy(): remover uma estrutura de atributos.

Threads implementados no espao do utilizador (user space)


Implementados numa biblioteca, especialmente teis para sistemas operativos onde no existe uma
implementao no kernel space. Os threads so user space so geridos atravs de um run-time que
fornece as funes e cria uma tabela de thread (thread table) em cada processo, anloga existente
no kernel para gerir os processos, excepto que gere apenas as propriedades de cada thread: program
counter, stack pointer, stack, registos, estado, etc. Quando um thread faz algo que pode fazer com
que possa ficar bloqueado localmente, chama uma chamada ao run-time, que verifica se o thread
necessita de ficar no estado bloqueado. Nesse caso guarda os registos na (sua) tabela de threads,
procura outro thread que esteja no estado pronto, carrega os seus registos da tabela e assim que
program counter e stack pointer tenham sido carregados, a execuo passou para o novo thread
automaticamente. No caso do processador possuir uma instruo para guardar os registos e outra
para os carregar, isto ser muito rpido, talvez 10 ou mais vezes que atravs de um TRAP ao kernel
e um argumento a favor da implementao em user-space: no haver context switching,
carregamento de memria e cache, etc. Outra vantagem que cada processo pode ter o seu
algoritmo de scheduling, o que vantajoso para algumas aplicaes ex: para aplicaes com um
garbage colector, no ter de se preocupar com a execuo do thread poder acontecer a qualquer
momento um lado positivo. Os threads em user-space tambm usam menos recursos do kernel, o
que pode ser uma vantagem em ambientes com um grande nmero de threads.
Uma desvantagem da implementao em user-space , por exemplo, a forma como as chamadas ao
sistema que podem bloquear so implementadas deixar que uma chamada ao sistema num thread
bloqueie o processo inaceitvel, j que impediria todos os outros threads de correr, acabando
assim com uma das principais vantagens de usar threads. Uma forma de rodear este problema seria
fazer que nenhuma chamada ao sistema bloqueasse, o que irrealizvel, j que requereria alterar o
sistema operativo, sendo que poder usar sistemas sem suporte nativo para threads era uma das
vantagens de implementar os threads em user-space. Outra forma ser implementar wrappers ou
jackets para todas as chamadas de sistema que possam bloquear no run-time, que verifiquem se
seguro fazer a chamada ao sistema (atravs de uma chamada funo select(), nos sistemas que a
disponibilizam), passando a execuo para outro thread em caso contrrio.
Outro problema ser a ocorrncia de uma page-fault, que far o sistema operativo, ignorante quanto
inexistncia de threads, bloquear todo o processo enquanto a pgina de memria em falta lida e
carregada, embora possam existir outros threads que, no necessitando dessa rea de memria,
pudessem continuar a execuo.
Ainda outro problema que um thread, assim que inicia a sua execuo apenas pode ser
interrompido voluntariamente, j que no h interrupts de clock num processo, tornando impossvel
a utilizao de algoritmos como o round-robin. Uma forma de ultrapassar isto seria que o run-time
requisitasse um interrupt de relgio, no entanto isto deselegante e pode implicar problemas se o
prprio processo necessitar tambm de um interrupt de relgio.
Finalmente, a maior razo para no implementar threads em user-space precisamente que as
aplicaes que mais necessitam de threads so que fazem muitas chamadas ao sistema que podem
bloquear. Uma vez que a chamada tem de ser efectivamente feita, pouco mais trabalho ou impacto
na performance ter fazer o scheduler correr nessa altura e fazer isso elimina as constantes
chamadas a select() para averiguar se uma chamada ao sistema ir ou no bloquear. Para aplicaes
que so de processamento intensivo no haver qualquer necessidade de usar threads, de qualquer
forma.

Threads implementados no kernel


No h necessidade de um run-time nem de uma tabela de threads em cada processo. Quando
necessrio criar ou destruir um novo thread faz-se uma chamada ao sistema que far a actualizao
da tabela de threads no kernel. Esta tabela guarda os registos, estado e outra informao de cada
thread a mesma que guardada na tabela de threads de cada processo quando estes so
implementados em user-space e que um subconjunto da informao que o kernel de um sistema
tradicional guarda para cada processo. O kernel continua a ter a tabela de processos com toda a
outra informao. Todas as chamadas que podem bloquear um thread so implementadas como
chamadas ao sistema, o que bastante mais oneroso que uma chamada ao run-time. Nessa altura o
scheduler ir correr outro thread que esteja, quer seja da mesma aplicao ou no na
implementao em user-space seria sempre escolhido um thread da mesma aplicao, j que cada
processo tem a sua tabela de threads.
Devido ao relativamente maior custo da criao e destruio de threads, alguns sistemas optam por
no destruir os threads, marcando-os em alternativa como no-executveis. Assim, quando for
necessrio criar um novo thread podem aproveitar as estruturas j criadas de um desses threads j
terminados. Isso tambm poderia ser feito em user-space, mas h menos incentivo para isso, j que
a a vantagem seria negligencivel.
No necessrio alterar qualquer chamada ao sistema, implementando chamadas que no
bloqueiem, j que quando isso acontecer (ex: uma page-fault), o kernel pode passar a execuo para
outro thread que esteja no estado pronto at que a pgina em falta seja carregada na memria. A
desvantagem que as chamadas ao sistema requerem mais recursos, pelo que se houver muitas
operaes de threads (criao, destruio, etc.) isso ir ter um impacto negativo na performance.
Apesar de os threads em kernel-space resolverem alguns problemas, outros mantm-se. O que fazer
quando acontece um fork(), copiar todos os threads ou apenas um? Isso pode depender do que o
novo processo ir fazer se executar um exec(), provavelmente melhor copiar apenas um, em
caso contrrio, talvez o indicado seja copiar todos. Outro problema o tratamento de sinais qual o
thread que trata os sinais chegados a um processo (os sinais so enviados ao processo, no aos
threads)?
Impletao hbrida de threads
Cada processo pode criar threads a nvel do kernel e, em cada um destes, threads em user-space,
cuja execuo ser multiplexada no thread do kernel respectivo. Esta a forma que oferece mais
flexibilidade ao programador. O kernel apenas conhece os threads implementados no seu espao,
ingnorando completamente a implementao em user-space.
Threads pop-up
um thread criado aquando do acontecimento de um evento (ex: chegada de uma mensagem num
canal de rede), especialmente para tratar esse evento. Uma vez que o thread criado de novo a cada
novo evento, no necessita de copiar registos ou estado, sendo a sua criao, por esse motivo,
bastante rpida. Se for criado em kernel-space, ser tambm bastante eficaz no processamento de
cada evento de I/O, j que ter acesso s tabelas do kernel e dispositivos de I/O. Por outro lado, um
bug num thread em kernel-space potencialmente mais destrutivo que em user-space por
exemplo, se correr durante um tempo demasiado longo, no haver hiptese de ser interrompido
pelo scheduler e dados de entrada podero perder-se.
Thread scheduling
A grande diferena entre o scheduling de threads em user-space e kernel-space que no primeiro
caso quando um thread entrega a execuo ao scheduler, apenas outro thread do mesmo processo
pode correr, enquanto que no segundo pode ser escolhido um thread de outro processo. Por outro
lado, uma mudana de processo envolve sempre um grande custo, j que necessrio o context-

switching, sendo necessrio a mudana de memria e invalidar a cache. No entanto, uma chamada
ao sistema a bloquear no ir bloquear todos os threads do processo mas apenas o thread que fez a
chamada.
Uma vantagem dos threads em user space que o seu scheduler sabe o que cada thread faz,
podendo correr sempre o thread que for mais importante a cada momento, enquanto que o
scheduler no kernel no sabe de nada acerca de cada thread especfico embora se possa alterar a
prioridade de cada thread.
A desvantagem bvia dos threads implementados no kernel que cada mudana de execuo
requerer o context-switching, mas isso pode ser alterado dando ao scheduler a possibilidade de
escolher um thread do mesmo processo para correr. Em geral, no entanto, os threads
implementados em user-space podem ser melhor afinados que os equivalentes no kernel.
INTERPROCESS COMMUNICATION
Race conditions: situao em que dois ou mais processos acedem ao mesmo recurso (partilhado)
sem conhecimento um do outro; se um dos processos for interrompido aps uma leitura do recurso
e outro processo for ler o mesmo recurso, actuando sobre a sua condio, quando o primeiro for
actuar sobre o valor lido pode acontecer que a situao no seja a mesma, invalidando os dados do
segundo processo ou gerando um erro.
Regies crticas ou seces crticas: pedao de um programa que acede a um recurso partilhado
que possa levar a existncia de race conditions. A forma de conseguir a excluso mtua no acesso
a um determinado recurso, garantindo que apenas um processo acede a um recurso partilhado de
cada vez, impossibilitando assim a corrupo desse recurso por um processo iniciar a sua utilizao
antes de outro ter acabado de usar o mesmo recurso deve preencher estes quatro requisitos:
1. Nenhuns dois processos podem estar simultaneamente dentro das suas regies crticas.
2. No devem fazer-se assumpes relativas velocidade ou nmero de CPUs.
3. Nenhum processo fora das suas regies crticas podem bloquear outros processos.
4. Nenhum processo deve ter de esperar indefinidamente para entrar numa regio crtica.
Sleep and wake-up problem
Se o processo de sincronizao for baseado em busy-wainting (esperar num loop at que a regio
crtica esteja livre) pode acontecer o problema da inverso de prioridade: um processo de
prioridade inferior est dentro de uma regio crtica da qual no consegue sair porque outro
processo de alta prioridade est num loop espera que esse recurso esteja livre. Uma forma de
evitar esse problema usar a chamada de sistema Sleep() para bloquear at que um recurso esteja
livre e Wakeup() para acordar o processo que aguarda pelo recurso.
O recurso s chamadas Wakeup() e Sleep() pode levar ao problema do produtor-consumidor ou
bounded buffer. Se o acesso varivel de indicao se um processo deve acordar o outro processo
no for de excluso mtua, pode acontecer que uma chamada a Wakeup() seja perdida por o
processo no estar tecnicamente a dormir mas ficar a dormir na prxima vez que entre em
execuo, porque j tinha lido a varivel, ficando a dormir para sempre espera de um Wakeup()
que no apanhou. Ex:

#define N 100
int count = 0;
void produce(void)
{
int item;
while(TRUE) {
int produce_item();
if (count == N)
sleep();
insert_item(item);
count++;
if (count == 1)
wakeup(consumer);
}

/* count was zero */

}
void consumer(void)
{
int item;
while(TRUE) {
if (count == 0)
sleep();
item = remove_item();
count--;
if (count == N 1)
wakeup(producer);
/* count was N */
consume_item(item);
}
}

Semforos Conjunto de operaes atmicas sobre uma varivel inteira que implementam uma
generalizao das chamadas Sleep() e Wakeup(). A operao Down() equivalente a Sleep() e
decrementa o valor da varivel se esta for superior a zero; se no for bloqueia (adormece) at que o
valor da varivel seja maior que zero. A operao Up() incrementa o valor da varivel e nunca
bloqueia. Se aps um Up() houver processos aguardando que a varivel seja maior que zero, o
sistema escolher um para completar o seu Down(), fazendo com que a varivel continue zero aps
uma operao Up() mas com menos um processo a aguardar. essencial que estas operaes sejam
atmicas (se realizem sem permitir interrupes) para ser possvel a sincronizao de processos.
Soluo do problema produtor-consumidor com semforos:
#define N
semaphore
semaphore
semaphore

100
mutex = 1;
empty = N;
full = 0;

void producer(void)
{
int item;

/* no. of empty slots */


/* no. of full slots */

while(TRUE) {
item = produce_item();
down(&empty);
down(&mutex);
insert_item(item);
up(&mutex);
up(&full);
}
}

void consumer(void)
{
int item;
while(TRUE) {
down(&full);
down(&mutex);
item = remove_item();
up(&mutex);
up(&empty);
consume_item(item);
}
}

Aqui mutex garante que o acesso ao recurso partilhado seja feito em excluso mtua, full impede
que consumer() corra se no houver dados no recurso e emtpy impede que producer() corra se todos
os slots do recurso estiverem ocupados.
Mutexes
Tipo especial de semforo com apenas dois estados, locked ou unlocked. usado para acesso em
excluso mtua a recursos ou pedaos de cdigo partilhados. Pode ser facilmente implementado
em user-space, desde que o processador disponha de uma instruo TSL ou XCHG. Ao invs de
usar busy waiting para aguardar que o mutex esteja unlocked, passa o controlo para o scheduler de
threads do processo, dando oportunidade a outro thread de correr (relembrar que em user-space no
h interrupts nem clock). Quando o thread bloqueado voltar a correr ir novamente testar a varivel
de lock. Exemplo:
mutex_lock:

ok:
mutex_unlock:

TSL REGISTER, MUTEX


CMP REGISTER, #0
JZE ok
CALL thread_yield
JMP mutex_lock
RET
MOVE MUTEX, #O
RET

Mutexes nos Pthreads

Pthread_mutex_init: criar um mutex

Pthread_mutex_destroy: destruir um mutex

Pthread_mutex_lock: adquirir um lock ou bloquear

Pthread_mutex_trylock: adquirir um lock ou falhar (permite implementar busy waiting)

Pthread_mutex_unlock: libertar um lock

Condition variables nos Pthreads

Pthread_cond_init: criar condition variable

Pthread_cond_destroy: destruir condition variable

Pthread_cond_wait: bloquear aguardando um sinal

Pthread_cond_signal: sinalizar outro thread e acord-lo

Pthread_cond_broadcast: sinalizar todos os threads e acord-los

Barreiras
Mecanismo que impede um grupo de processos de prosseguir a execuo at que todos tenham

atingido um certo ponto ou condio.


Problemas clssicos de IPC: ler seco 2.5 do MOS3e

Captulo 6 Deadlocks
Situao em que um conjunto de processos esto bloqueados permanentemente aguardando um
evento que apenas outro dos processos possa despoletar. Exemplo, dois processos A e B e dois
recursos X e Y. Processo A adquire lock a recurso X, enquanto que processo B adquire lock a
recurso Y; em seguida A tenta adquirir Y e bloqueia, aguardando que B o liberte; por seu turno B
tenta adquirir lock a X e bloqueia aguardando que A o liberte. Agora, nenhum dos processos
conseguir sair dessa situao, ficando em deadlock.
Os recursos num computador podem ser preemptivos, significando que o acesso pode ser retirado
ao processo que o detm sem causar problemas (ex: a memria um recurso preemptivo, j que um
processo pode libertar a memria que detm, ficando em swap), ou no-preemptivos, significando
que o acesso a esse recurso no pode ser retirado ao processo que o detm (ex: retirar o acesso a
uma impressora a meio de uma impresso no possvel, j que iria provavelmente corromper o
documento a ser impresso). Apenas os recursos no-preemptivos podem, em princpio, causar
deadlocks.
Como mostrado acima, uma forma de acontecer um deadlock se dois processos acederem a dois
recursos partilhados pela ordem inversa um do outro.
Condies para a ocurrncia de um deadlock de recursos
1. Condio de excluso mtua. Cada recurso pode estar em dois estados: atribudo a apenas
um processo ou livre.
2. Condio de deteno e espera (wait and hold). Processos que detm algum recurso podem
pedir novos recursos sem libertar o recurso que possuem.
3. Condio de no-preempo. Recursos detidos por um processo no lhe podem ser
retirados, devendo ser explicitamente libertados pelo processo que os detm.
4. Condio de espera circular. Tem de existir uma cadeia circular em que cada processo
espera por um recurso detido pelo prximo processo na cadeia.
Apenas quando todas estas condies esto presentes pode ocorrer um dealock. Note-se que todas
estas condies representam uma poltica que um sistema pode ou no seguir. As vrias formas de
evitar os dealocks so tentar negar uma das condies.
FORMAS DE TRATAR DEADLOCKS
Ignor-los: se um deadlock ocorre com pouca frequncia em relao a outros problemas do
sistema, o prefervel ser ignor-lo, j que no compensa a perda de performance ou trabalho
envolvido para o evitar.
Detectar e recuperar: usar a construo dinmica de mecanismos que detectam a ocorrncia da
condio circular. A recuperao pode ser efectuada de trs formas, nenhuma das quais
especialmente atractiva:
1. Preempo: se for possvel retirar temporariamente um recurso a um processo, pode tentar
evitar-se a condio circular. No entanto, muitas vezes isto requer interveno humana e
depende do tipo de recurso.
2. Rollback: cada processo tem vrios checkpoints em que escreve o seu estado para o disco,
incluindo os recursos utilizados. Ao ser detectado um deadlock um dos processos
envolvidos reposto num ponto antes de adquirir o acesso a um dos recursos em questo,
podendo os outros sair assim do deadlock. O trabalho efectuado pelo processo a que foi

feito o rollback aps o checkpoint obviamente perdido.


3. Matar processos: para resolver um deadlock pode sempre matar-se um dos processos
envolvidos, esperando com isso libertar um dos recursos e possibilitar a recuperao dos
outros processos. Em alternativa pode tambm matar-se outro processo no envolvido mas
que possua um recurso que pode servir para resolver o dealock este processo deve ser
escolhido cuidadosamente. Sempre que possvel deve escolher-se um processo que possa
ser reiniciado sem problemas como um compilador e no um que morrendo possa
implicar a perda de dados como um processo de escrita numa base de dados.
PREVENIR DEADLOCKS
Atacar a condio de excluso mtua: evitar que um recurso seja detido apenas por um processo,
para que no possa existir deadlock. Por exemplo, ao implementar spooling no acesso a uma
impressora apenas o daemon de impresso imprime e todos os processos que necessitem de
imprimir limitam-se a colocar os documentos numa directoria, evitando desta forma um deadlock
no acesso impressora. Na verdade, o deadlock pode ocorrer igualmente se , por exemplo, o
espao disponvel na directoria for esgotado por dois processos sem que estes consigam colocar o
documento completo para impresso estes ficam a aguardar a existncia de espao disponvel e o
daemon de impresso a aguardar que haja um documento completo para imprimir. No entanto, esta
situao bem mais improvvel que a ocorrncia de um deadlock no acesso a uma impressora por
mais de um processo em simultneo. A mesma ideia pode ser usada em vrias situaes.
Atacar a condio de deteno e espera (hold and wait): evitar que um processo que detenha
recursos aguarde por mais recursos. Uma forma de conseguir isto que cada processo tente
adquirir todos os recursos que necessita antes de iniciar a execuo, no a iniciando se um deles no
estiver disponvel. O problema com esta soluo que muitos processos s sabem os recursos de
que iro necessitar aps iniciarem a execuo. Para alm disso, isto coloca tambm um peso sobre
o programador, que tem de definir a priori todos os recursos necessrios, e sobre o sistema, que ir
ter recursos ocupados durante todo o tempo de execuo de um processo mesmo que ele no os
esteja a usar de momento.
Uma alternativa seria que cada vez que um processo necessitasse de aceder a vrios recursos em
simultneo os tentasse aceder de uma s vez. Se descobrisse, durante a execuo, que necessitava
de mais um, teria de libertar os que possua primeiro para os alocar a todos de uma s vez a seguir.
Apesar destas abordagens serem possveis e efectivamente evitarem deadlocks, tornam a
programao bastante complicada e so apenas usadas em alguns mainframes.
Atacar a condio de no-preempo: retirar um recurso fora a um processo para evitar os
deadlocks tambm uma possibilidade. No entanto, h recursos que no podem ver o seu acesso
interrompido, j que isso iria destruir todo o seu trabalho para determinado processo (por exemplo,
uma impressora). Isto pode em alguns casos ser evitado virtualizando esses recursos (ex: no caso
da impressora, usando spooling), mas nem todos os recursos podem ser virtualizados desta forma.
Atacar a condio de espera circular: eliminando esta condio tambm se consegue evitar os
deadlocks. Uma forma simples de o conseguir impor uma regra que impea qualquer processo de
deter um lock para mais do que um recurso em simultneo. No entanto, esta uma grande restrio,
impraticvel em muitas situaes (exemplo, copiar um ficheiro grande de um recurso para outro).
Outra forma ser numerar globalmente todos os recursos e requerer que os processos apenas os
possam adquirir respeitando a sua ordem numrica. Isto tambm evita a espera circular, j que em
qualquer momento haver um processo que detm o recurso de nmero mais elevado e, quando o
libertar, far que os processos esperando por ele possam continuar. Uma variante desta tcnica
requerer que nenhum processo possa aceder a um recurso com valor menor ao menor recurso que
possui, conseguindo o mesmo efeito sem ser to restritivo.
Estas solues tambm so difceis de implementar na prtica, j que numa qualquer situao real o

nmero de recursos existentes to grande e imprevisvel que a sua numerao se torna impossvel.
Sumrio das vrias formas de evitar deadlocks

Excluso mtua: usar spooling para todos os recursos

Deteno e espera: pedir todos os recursos inicialmente

No-preempo: retirar recursos fora

Espera circular: ordenar os recursos numericamente

OUTRAS QUESTES
Locking em duas fases Uma forma de evitar deadlocks fazer o lock aos recursos e a sua
utilizao em duas fases, primeiro tentando adquirir cada recurso necessrio e s quando os tiver a
todos iniciar o trabalho, indo libertando os recursos assim que possvel. Se, na fase de aquisio
dos recursos um no estiver disponvel, libertam-se todos os recursos j alocados e recomea-se de
novo. Este algoritmo , por exemplo, usado no acesso a bases de dados, em que primeiro se faz
lock a todos os registos que se vo actualizar e s depois se inicia a efectiva actualizao.
Isto , na verdade, uma verso do algoritmo de pedir todos os recursos inicialmente. No entanto,
nem todos os tipos de recursos suportam este tipo de mecanismo: por exemplo, um stream de rede
no pode ser repetido em segurana.
Deadlocks de comunicaes Pode ocorrer se um processo enviar uma mensagem a outro e essa
mensagem se perder. O segundo processo fica espera da primeira mensagem e o segundo espera
da resposta, ficando ambos bloqueados esperando em evento que nunca acontecer. A forma de o
evitar usando timeouts. necessrio cuidado ao desenhar os protocolos de rede com timeouts,
para evitar que uma mensagem que esteja apenas atrasada (e no perdida), possa originar uma aco
repetida.
Livelock Situao em que os processos ficam espera no acesso a recursos mas usando busy
wainting e no chamadas que bloqueiam. possvel em diversas situaes (na verdade, em todas as
situaes em que se usam tabelas no kernel) mas ignorado a maior parte das vezes, j que raro
acontecer na realidade e isso prefervel s restries que seria necessrio fazer para os evitar.
Starvation Situao em que um processo espera indefinidamente por um recurso que nunca lhe
alocado, apesar de no estar bloqueado. Por exemplo, se numa fila de impresso for implementado
o algoritmo de shortest job first, pode acontecer que um processo com um ficheiro grande para
ser impresso nunca seja atendido se houver um fluxo constante de trabalhos pequenos. Esta
situao ultrapassada se se usar o algoritmo first come, first served.

Captulo 3 Gesto de Memria


Gestor de memria parte do sistema operativo responsvel por gerir a memria eficientemente:
gerir que partes de memria esto em utilizao, alocar memria para os processos quando estes o
necessitarem e dealoc-la quando j no for necessria.
SEM ABSTRACO DE MEMRIA neste esquema o sistema operativo no apresenta
qualquer sistema de gesto de memria, simplesmente disponibilizando a memria tal como ao
programador. Isto significa que apenas um processo pode correr em cada momento, j que se
houvesse mais do que um iriam provavelmente corromper a memria um do outro. Seria possvel
conseguir paralelismo de execuo usando threads, mas improvvel que um sistema sem
abstraco de memria apresente abstraco de threads.
Vrios esquemas de organizao de memria so possveis, mesmo sem um gestor dedicado:

Sistema operativo em RAM no incio de memria para os programas a seguir. Sistema usado
em alguns mainframes iniciais e mini-computadores, tendo cado em desuso.

Sistema operativo no topo da memria (fim) em ROM e memria para o utilizador no incio.
Usado por alguns sistemas operativos embedded e computadores handheld.

Sistema operativo em RAM no incio, drivers de dispositivos no fim em ROM e memria


para o utilizador a meio. Usado pelos primeiros computadores pessoais (usando MS-DOS);
a ROM chama-se BIOS Basic Input Output System.

A primeira e terceira hipteses tm a inconvenincia de permitirem que um programa escreva por


cima da memria do sistema operativo, com efeitos potencialmente catastrficos.
Correr mltiplos programas sem abstraco de memria
Uma forma de correr vrios programas sem abstraco de memria seria fazer a swap entre a
memria fsica e o disco sempre que um programa entrasse em execuo. Desta forma, apenas o
programa em execuo no momento estaria na memria, eliminando assim os possveis conflitos.
Outra forma, usada pelo IBM 360, foi dividir a memria em blocos, cada um com uma chave de
proteco, no caso de 4 bits. Quando um programa era carregado na memria, o sistema operativo
atribua-lhe uma chave e toda a memria alocada era marcada com essa chave, guardada em
registos especiais na CPU. Qualquer acesso pelo programa a uma rea de memria fora da(s)
zona(s) que lhe era(m) atribuda(s) fazia o programa falhar. Para evitar que acesso atravs de
endereos estticos no funcionasse caso um programa fosse carregado num local de memria
diferente do que estava espera (usualmente o incio da memria), esses endereos eram
convertidos automaticamente somando-lhes o offset da localizao em que o programa era
efectivamente carregado.
Apesar de a maior parte dos sistemas actuais terem todos um gestor de memria, alguns sistemas
existem ainda sem ele, nomeadamente em dispositivos embedded, como equipamentos electrnicos,
etc.
ABSTRACO DE MEMRIA: ESPAOS DE ENDEREAMENTO
Espao de endereamento uma abstraco de memria que fornece a cada processo o seu prprio
endereamento de memria, de forma a que seja possvel correr vrios programas em simultneo.
Para isso necessrio resolver dois problemas: (1) proteco evitar que os programas interfiram
uns com os outros e (2) realocao fazer que os programas possam correr como esperado, seja
qual for o espao fsico na memria que lhes tenha sido alocado.
Registos de base e limite Forma simples de implementar realocao dinmica, usada para
algumas mquinas, como o CDC 6600 ou o Intel 8088, a CPU do primeiro IBM PC. Quando um
programa carregado para memria o endereo de incio colocado num registo especial da CPU
(base) e o tamanho da memria noutro endereo (limite). Antes de qualquer endereamento por um
processo memria, a CPU soma ao endereo pedido o valor do registo base e compara-o com o
limite do processo, impedindo o acesso se o ultrapassar.
Este mecanismo caiu em desuso, tendo como desvantagem ter de se efectuar uma comparao
(relativamente rpida) e soma (potencialmente mais lenta) antes de cada acesso memria.
Swapping Como na maior parte dos sistemas a totalidade dos programas em execuo no
cabem todos na memria em simultneo, um mecanismo foi inventado para passar alguns
programas ou pedaos de programas que no esto em utilizao imediata para o disco, ao que se
chama swapping. Este esquema implica um qualquer esquema de realocao, por exemplo usando
registos base e limite, para converso do endereamento memria.
Um dos problemas deste esquema a criao de buracos na memria, devido aos programas que
so passados para o disco. Esse problema pode ser resolvido atravs da compactao da memria,
puxando todos os programas presentes na memria para endereos contguos. No entanto esse
processo no pode ser feito muitas vezes j que consome muito tempo de CPU.

Outro problema tem a ver com o crescimento em memria dos programas, que pode implicar a
recolocao do programa onde haja espao, caso no exista o suficiente acima do processo em
questo. Vrias solues so possveis:

Impedir que os programas possam crescer para fora do seu segmento de dados. Se os
programas no poderem crescer, basta alocar um espao esttico de memria para cada
programa carregado.

Muitas linguagens de programao oferecem, contudo, mecanismos de alocao dinmica


de memria. Se existir um buraco adjacente ao programa quando este tenta crescer, este
pode us-lo para expandir a sua memria para a. Em caso contrrio, ou quando a
quantidade de memria no buraco no seja suficiente, ser necessrio realocar o programa
ou mesmo bloque-lo at que exista memria disponvel.

Outra soluo ser alocar partida mais espao do que o necessrio para o programa,
reservando logo espao para que este cresa medida que for necessitando da memria.
Uma organizao possvel neste caso ser alocar a memria no topo do programa, outra ser
colocar o programa no fundo, o segmento de dados a seguir e o seu stack no topo desta
forma, quer o stack quer o segmento de dados podero crescer consoante necessrio, cada
um no seu sentido. Se o processo esgotar a memria ter de ser realocado ou morto.

Gesto da memria livre Quando o sistema operativo permite a alocao dinmica de memria,
necessrio que consiga gerir a memria livre. Existem, em geral, dois sistemas para o fazer:

Gesto de memria livre com bitmaps: com um bitmap a memria dividida em unidades
de alocao (tamanho escolhido pelo desenhador do sistema), cada uma representada por um
bit, com informao se a unidade est livre ou ocupada. Este sistema bastante simples e o
tamanho ocupado pela estrutura de gesto depende apenas da razo entre o tamanho da
memria e o das unidades de alocao. , no entanto, ineficiente, j que quando
necessrio alocar uma dada poro de memria o sistema necessita de fazer uma busca bit a
bit em todo o mapa at descobrir um buraco com o tamanho adequado.

Gesto de memria com listas ligadas: com uma lista ligada a memria dividida em
segmentos ou unidades de alocao. Cada segmento pode conter um processo ou estar livre
e cada entrada na lista representa uma srie de segmentos que podem estar livres ou conter
um processo. Cada entrada/n da lista possui assim um indicador, indicando se est livre ou
contm um processo, o nmero do segmento inicial dessa seco, o nmero de segmentos da
seco e um apontador para o prximo n da lista. Como a tabela de processos aponta
normalmente para o n da lista onde cada processo est alojado, prefervel que cada n
tenha tambm um apontador para o n anterior (lista duplamente ligada), para facilitar a
libertao da memria ocupada pelo processo quando este for terminado, transferido para o
disco ou realocado isto pressupe que a lista seja ordenada pelo valor do segmento incial
de cada seco.
Quando necessrio libertar a memria de um segmento basta ento passar o seu indicador
para livre, e verificar se os ns anteriores da lista est livres, caso em que sero
adicionados ao segmento libertado e removidos da lista, ou contm processos, caso em que
nada ser feito.

Algoritmos de alocao de memria para gestores com listas ligadas pressupem que se
conhece o espao necessrio partida:

First fit: percorre a lista desde o incio at encontrar um buraco onde caiba o processo.
Quando o encontra divide-o em dois um para o processo e outro para a rea livre que resta, a
no ser no caso raro do processo ocupar a totalidade do buraco. moderadamente rpido,
porque a busca a menor possvel.

Next fit: como o anterior, mas fazendo a busca a partir do ltimo buraco preenchido.
Simulaes provaram que ligeiramente mais ineficiente que o anterior.

Best fit: percorre a lista na totalidade tentando encontrar o buraco mais pequeno onde caiba
o processo. lento, pois necessita de procurar em toda a lista de cada vez que necessrio
alocar memria e simulaes provam que tende a desperdiar mais memria que os
anteriores, j que esta tende a ficar cheia de buracos minsculos onde no cabe nenhum
processo.

Worst fit: como o anterior, mas escolhendo o maior buraco possvel. Simulaes provam
que tambm no uma boa ideia.

Todos estes algoritmos podem tornar-se mais rpidos se forem mantidas duas listas, uma para os
processos e outra para os buracos, j que a pesquisa apenas feita na ltima. O preo a pagar que
torna a libertao de memria mais onerosa, j que necessrio remover um segmento da lista de
processos e introduzi-lo na lista de buracos.
Se for mantida uma lista separada para os buracos, esta pode ser ordenada por tamanhos, o que
torna o algoritmo best fit to rpido como o first fit. O next fit intil neste caso. Uma optimizao
possvel no caso de listas separadas que os ns da lista de buracos sejam guardados nos prprios
buracos a primeira palavra no buraco seria para o tamanho da seco e a segunda com um
apontador para a prxima seco.
Ainda outro algoritmo possvel o quick fit, que mantm lista separadas para os tamanhos mais
provveis. Desta forma, encontrar o buraco adequado extremamente rpido, mas complica ainda
mais o trabalho de encontrar os vizinhos aquando da remoo de um processo da memria. Se a
memria no fosse juntada quando um processo dealocado, esta rapidamente se fragmentaria
tornando impossvel a alocao de novos processos.
MEMRIA VIRTUAL
Como as necessidades de memria dos programas esto a crescer mais rapidamente que a memria
disponvel nos computadores, existindo muitos programas que, mesmo sozinhos no cabem na
memria fsica ou, em ambientes de multi-programao, os programas em execuo no cabem
totalmente na memria, foi necessrio inventar formas de correr pedaos de um programa de cada
vez, em vez de o ter todo alojado na memria simultaneamente. A primeira tcnica foi os
programadores dividirem os seus programas em mdulos, chamados overlays, que eram carregados
medida que iam sendo necessrios pelo overlay manager para a memria. No entanto, este
esquema era difcil de programar e dado a erros, pelo que foi abandonado por outro, chamado
Memria virtual.
Na memria virtual, cada processo tem disponvel um espao de endereamento completo, dividido
em segmentos de endereos contguos, chamados pginas. Estas pginas so ento carregadas em
separado e mapeadas para a memria fsica. Cada vez que, durante a execuo de um processo,
referenciado um endereo de memria que no se encontra disponvel, gerado uma falha e essa
pgina ento carregada para a memria, repetindo-se ento a instruo que causou a falha.
Enquanto se espera que o disco seja lido e a pgina escrita na memria, a CPU pode ser libertada
para outro processo. Assim, a cada momento a memria fsica conter uma srie de pedaos de
processos, mapeados para a rea de memria virtual de cada um.
Este mecanismo uma generalizao do mecanismo de registos base e limite.
Paginao o mecanismo de diviso da memria virtual em pginas de endereos virtuais e a
memria fsica em molduras de endereos fsicos (page frames) onde essas pginas pginas sero
colocadas. Para isto funcionar necessrio uma unidade de hardware, chamada MMU Memory
managing unit, que transforma os endereos virtuais em endereos fsicos, caso a pgina esteja
presente na memria, ou que gera uma page fault, em caso contrrio, sinalizando o sistema
operativo (TRAP) para carregar a pgina em falta substituindo, se necessrio, uma pgina menos

usada presente em memria.


A MMU funciona da seguinte forma. Na MMU mantida uma tabela de tantas entradas como as
pginas virtuais possveis (n de pginas = tamanho do espao de endereamento virtual / tamanho
de cada pgina). Cada entrada possui um bit (present/absent bit) informando se a pgina est ou
no em memria e o nmero da page frame da memria fsica em que a pgina se encontra, no caso
de esta estar presente. Assim, quando um endereo virtual chega MMU, os seus bits mais
significativos so tomados como um ndice para a tabela e a MMU analisa o bit de
presena/ausncia para saber se a pgina est ou no em memria. Em caso negativo, gerada uma
page fault; em caso contrrio esse bits mais significativos sero substitudos pelo nmero da page
frame no endereo virtual, transformando-o assim num endereo fsico e acedendo memria, que
no necessita de sequer conhecer a existncia da MMU, j que todos os endereos que lhe chegam
so vlidos.
Estrutura de uma entrada numa tabela de pginas (page table):
(livre) caching disabled referenced modified protection present/absent

page frame number

Page frame number: campo mais importante da tabela, o nmero da moldura de memria
fsica em que est a pgina de memria virtual.

Present/absent: bit que informa se a entrada (1) ou no (0) vlida, ou seja, se a entrada
contm o endereo de uma moldura de memria ou se est em falta.

Protection: guarda o tipo de acesso permitido a esta entrada de memria. No caso mais
simples de apenas um bit, significando se a memria pode (1) ou no (0) ser escrita. Numa
situao mais elaborada pode conter 3 bits, cada um especificando se a rea de memria
pode ser lida, escrita ou executada.

Modified: quando a 1 significa que a memria fsica foi alterada desde a altura em que foi
carregada. Isto quer dizer que quando o sistema operativo necessitar de reclamar esta
pgina deve escrever o seu contedo no disco. Tambm chamado de dirty bit pois significa
que a pgina est dirty.

Referenced: quando a 1 significa que a pgina est referenciada, quer para escrita quer para
leitura, o que til para que o sistema operativo possa fazer uma escolha informada na
altura de reclamar pginas para outra utilizao.

Caching disabled: informa o hardware que no deve usar a cache para estes endereos de
memria. til, por exemplo, no caso de representarem endereos de dispositivos, que no
devem ser objecto de cache, j que as suas alteraes de estado so importantes e para ser
atendidas na altura.

til notar que a memria virtual no mais que uma abstraco de um espao de endereamento,
tal como um processo uma abstraco de um processador, permitindo a multi-programao.
ACELERANDO A PAGINAO
Em qualquer sistema de paginao, duas caractersticas so bvias: (1) o mapeamento de endereos
fsicos para endereos virtuais deve ser rpido e (2) quando o espao de endereamento virtual
grande, a tabela de paginao ser grande.
A primeira caracterstica deve-se ao facto de que o mapeamento tem de ser feito a cada acesso
memria, que acontece virtualmente pelo menos uma vez em cada instruo que executada. A
segunda resulta do facto do espao de endereamento dos computadores modernos ser de pelo
menos 32 bits, pelo que uma diviso de pginas de poucos endereos ir resultar num nmero
grande de pginas.

O desenho mais simples ter uma nica tabela de registos do processador, com uma entrada para
cada pgina de memria virtual. Desta forma, durante a execuo no necessria qualquer
referncia extra memria, sendo todos os endereos traduzidos automaticamente. No entanto, este
desenho extremamente caro, j que necessitaria de um registo no processador para cada pgina.
No outro extremo estaria um desenho em que a tabela se encontrasse totalmente na RAM. A
desvantagem bvia que cada endereamento necessitaria de pelo menos mais uma referncia extra
memria, tornando os programas 50% mais lentos na melhor das hipteses.
Translation Lookaside Buffers (TLB)
Uma soluo largamente usada baseada na observao que a maior parte das vezes apenas uma
pequena parte das pginas disponveis utilizada por cada programa. Assim, o que foi concebido
foi ter uma pequena tabela de pginas virtuais no processador, chamada de Translation lookaside
table ou TLB, mantendo a tabela completa em memria. Quando um endereo enviado MMU,
este endereo (ou antes, o nmero da pgina virtual correspondente) comparado simultaneamente
(em paralelo) com todos os nmeros de pginas virtuais presentes nesta tabela. Se a o endereo da
pgina se encontrar l, imediatamente convertido para um endereo fsico. No caso contrrio,
consultada a tabela em memria e copiada a entrada respectiva para a TLB. Desta forma, da
prxima vez que este endereo for pedido, j se encontra na TLB, acelerando assim a sua utilizao.
Quando uma entrada retirada da TLB, apenas o dirty bit copiado para a memria, j que todos os
outros campos j l se encontram, com excepo do reference bit. Quando a TLB carregada da
page table em memria, todos os campos so copiados.
Gesto de TLB em software Existem processadores que no fazem a gesto das falhas de TLB,
relegando isso para o sistema operativo (ex: mquinas RISC, incluindo SPARC, MIPS e HP PA).
Nestes sistemas as entradas da TLB so explicitamente carregadas pelo sistema operativo. Quando
ocorre uma falha de TLB, em vez der a MMU a ir buscar a entrada em falta directamente
memria, gera apenas uma TLB fault, ficando o SO de ir buscar a entrada em falta e carreg-la na
TLB.
necessrio ter a noo de que existem dois tipos de falha TLB: (1) a pgina no se encontra na
TLB mas existe em memria (soft miss), caso que pode ser resolvido com algumas instrues
assembly, bastando ir buscar a entrada em falta page table e (2) a pgina no se encontra na TLB
nem na memria (hard miss), caso em que a pgina deve ser carregada do disco para a memria,
possivelmente para ocupar o lugar de outra pgina existente, caso em que esta tem de ser escrito
primeiro no disco. Este ltimo caso pode bem demorar um milho de vezes mais do que uma soft
miss.
Page tables para memrias grandes quando o espao virtual de endereamento grande , as
tabelas de pginas tambm tero muitas entradas, o que ser um desperdcio, principalmente se nem
todas forem utilizadas, como acontece na maioria dos casos. As solues que se seguem so
usualmente usadas para contornar esse problema:
Tabelas de pginas multi-nvel: existncia de pelo menos dois nveis de tabelas de pginas. O
primeiro, usando os bits mais significativos do endereo virtual, guarda o nmero da tabela de
segundo nvel a ser usada. Cada entrada no segundo nvel, usando como ndice os bits mais
significativos seguintes, guarda ento o nmero da moldura de pgina onde se encontra a pgina de
memria referenciada. Assim, apenas existiro em memria as tabelas de segundo nvel que forem
efectivamente usadas pelo processo, eliminando a necessidade de conter em memria uma tabela
para todas as pginas de memria do endereamento virtual.
Tabelas de pginas invertidas: neste tipo de tabelas de pginas, existe uma entrada da tabela por
cada moldura de pgina fsica de memria e no por cada pgina de endereos virtuais. Assim, o
nmero de pginas grandemente reduzido, permitindo o uso de endereamentos virtuais de 64
bits. Contudo, isto significa que no possvel usar a MMU para fazer a traduo do endereo
virtual pedido por um processo para o endereo fsico, sendo necessrio procurar toda a tabela por

uma entrada do tipo (processo, endereo) at encontrar o referenciado o que invalidaria por
completo a utilizao deste algoritmo. A soluo usar TLB, mantendo as pginas em utilizao
nesta tabela. Quando gerada uma page fault, o SO tem de ento de procurar na sua tabela o par
(processo, endereo) referenciado. Este procedimento pode ser acelerado se o SO mantiver uma
hash table em que a chave o nmero de pgina virtual referenciado.
ALGORITMOS DE SUBSTITUIO DE PGINAS
Algoritmo ptimo: impossvel de realizar, requer um conhecimento prvio de qual das pginas em
memria ir ser utilizada em ltimo lugar, devendo ser essa a escolhida para ser removida.
Algoritmo Not recently used (NRU): usar os bits (R)eferenced e (M)odified para dividir as
pginas em memria em 4 classes classe 0: R,M=0; classe 1: R=0, M=1; classe 2: R = 1, M=0;
classe 3: R,M=1. A cada page fault o algoritmo NRU ir escolher ao acaso uma pgina da menor
classe existente em memria para ser substituda. Este algoritmo simples de implementar e tem
uma performance razovel.
Algoritmo First in, First out (FIFO): o sistema mantm uma lista das pginas entradas, a primeira
no topo da lista e a ltima no fim. Quando ocorre uma page fault a primeira da lista removida da
memria (e da lista) e a nova acrescentada ao fundo da lista. Uma desvantagem deste tipo de
algoritmo que tanto pode remover pginas no usadas h bastante tempo e que, portanto,
provavelmente no faro falta, como tambm as pginas mais usadas, que tero de ser carregadas
brevemente. Por essa razo no ser usado na sua forma original em sistemas reais.
Algoritmo da segunda oportunidade: modificao do FIFO que leva em conta o bit R. Neste
caso, o sistema procura uma pgina que seja simultaneamente velha e no usada. Se a primeira
pgina da lista tiver sido usada h pouco tempo, o seu bit R limpo e a pgina colocada no fundo da
lista. O algoritmo continua a percorrer a lista com o mesmo procedimento at encontrar uma pgina
no referenciada em ltimo caso acabar por substituir a primeira pgina inicial, se todas as
pginas presentes tiverem sido acedidas h pouco tempo (bit R a 1), j que acabar por encontr-la
na segunda volta j com R a 0. Grande melhoria do FIFO.
Algoritmo do relgio: como o anterior mas usando uma lista em anel para no ter de estar
constantemente a mudar os ns da lista do princpio para o fim. Aqui basta ir percorrendo a lista,
sabendo que acabar, em ltimo caso, por dar a volta. Quando se encontra a pgina a substituir, o
seu n tambm substitudo e o apontador no anel avana uma casa. Realista.
Algoritmo Least Recently Used (LRU): requer hardware especfico; baseia-se no princpio de que
deve ser removida a pgina que foi acedida h mais tempo no passado. Excelente mas difcil de
implementar.
Algoritmo Not Frequently Used (NFU): implementao em software do algoritmo anterior. Pode
ser implementado usando um contador de software e atribuindo uma varivel a cada page frame. A
cada interrupt do relgio somado o valor de R a todas as pginas, o que significa que que cada
varivel conter, em princpio um valor mais alto quanto mais usada for uma pgina. A
desvantagem com este algoritmo que no se esquece de nada, levando a que umas pginas que
foram intensivamente usadas numa altura continuem com um valor alto e no sejam removidas
mesmo depois de j no serem usadas h bastante tempo.
Algoritmo Aging: modificao do anterior. O contador primeiro faz um shift para a direita e em
seguida coloca o bit R de cada pgina esquerda. Desta forma, contabilizam-se no apenas o
nmero de acessos como tambm h quanto tempo a pgina foi acedida, tornando o algoritmo bem
mais eficaz na deteco de pginas pouco acedidas. Aproximao bastante eficiente ao algoritmo
LRU.
Algoritmo do Grupo de Trabalho (Working set):
Nos algoritmos anteriores suposto que cada processo comea totalmente em disco. Assim que
inicia ir provocar page faults at que todas as pginas de memria que necessita para trabalhar

estejam em memria fsica esta estratgia chama-se demand paging. A maioria dos processos
tem uma localizao de referncia, querendo isto dizer que durante um certo perodo de execuo
referencia apenas um nmero limitado de pginas de memria de todas as pginas possveis. Ao
conjunto de pginas que um processo est a usar correntemente chama-se working set ou grupo de
trabalho. Se a memria insuficiente para conter todo o grupo de trabalho de um processo, este ir
causar repetidas falhas e correr lentamente. Um programa que cause repetidas page faults diz-se
que est em thrashing. Em sistemas multi-programao, usual um processo ser completamente
removido da memria para deixar outro processo correr. Ao recarregar o processo seria
conveniente carregar logo todas as pginas do seu grupo de trabalho, evitando falhas de pgina
posteriores. A isto chama-se pr-paginao (prepaging) e a este modelo o Modelo do grupo de
trabalho (Working set model).
No caso dos algoritmos de substituio de pginas ser tambm interessante remover as pginas que
no pertenam ao grupo de trabalho do processo. Uma implementao deste algoritmo usa o tempo
em que cada pgina foi acedida (current virtual time) para decidir qual pgina dever ser
substituda. Este algoritmo pouco usado j que a cada page fault necessita de percorrer toda a
tabela de pginas para descobrir qual a que no pertence ao grupo de trabalho.
Algoritmo WSClock: usa tambm o grupo de trabalho e o current virtual time para o descobrir mas
implementa a lista de pginas num anel, tornando-o bastante mais eficiente que o algoritmo
clssico. um dos mais usados na realidade.

Captulo 4 Sistemas de ficheiros


Um sistema de ficheiros uma abstraco de um dispositivo de armazenamento de massa, tal como
um disco, fornecida pelo sistema operativo.
FICHEIROS
Tipos de ficheiros
Ficheiros comuns: contm informao dos utilizadores. Podem ser ficheiros de texto (ASCII) ou
binrios. A grande vantagem de usar ficheiros de texto que podem ser lidos e alterados com
editores convencionais de texto. Para alm disso, se um grande nmero de programas usarem
ficheiros de texto para I/O, fcil ligar a sada de um entrada de outro, como nos pipes da shell.
Os ficheiros binrios tm normalmente uma qualquer estrutura interna conhecida do programa que
os criou e usa.
Directorias: ficheiros de sistema para manter o sistema de ficheiros estruturado.
Ficheiros especiais de carcter: usados pelo UNIX para modelar dispositivos de I/O em srie, tais
como redes, modems e impressoras.
Ficheiros especiais de bloco: usados pelo UNIX para modelar discos.
Todos os sistemas tm de reconhecer pelo menos um tipo de ficheiros, os seus programas (ficheiros
executveis).
Acesso a ficheiros pode ser sequencial ou aleatrio. O acesso aleatrio essencial para alguns
programas, como as bases de dados. Para aceder aleatoriamente a um ficheiro, alguns sistemas
operativos fornecem uma verso de read que aceita a posio onde deve comear o acesso,
enquanto que outros tm uma chamada especial, seek, para colocar a posio de acesso. UNIX e
Windows usam esta ltima verso.
Atributos dos ficheiros: todos os ficheiros tm pelo menos um nome e os seus dados. Para alm
dessa informao, os sistemas operativos guardam outros dados sobre eles, como o dono ou a data
de criao, chamados atributos dos ficheiros ou metadados.
Operaes sobre ficheiros: ex: Create, Delete, Open, Close, Read, Write, Append, Seek, Get

attributes, Set attributes, Rename.


DIRECTORIAS
Podem ser de um nico nvel, em que todos os ficheiros so colocados ou hierrquicas, em que
construda uma rvore de directorias cada uma podendo conter ficheiros e outras directorias.
Caminhos (path names) podem ser absolutos, caso em que comeam pelo separador de
directorias ou realtivos. Para usar caminhos relativos necessrio que o sistema possua o conceito
de directoria de trabalho ou corrente (working directory/current directory), que independente a
cada processo. Em cada directoria existem normalmente duas entradas (. dot e .. dotdot) que
referem respectivamente a directoria em questo e a sua directoria me.
Operaes sobre directorias: Create, Delete, Opendir, Closedir, Readdir, Rename, Link, Unlink.
IMPLEMENTAO DO SISTEMA DE FICHEIROS
Cada disco comea pelo MBR no sector 0, que contm o programa que a BIOS ir ler para iniciar o
sistema operativo. Em seguida est a tabela de parties, uma tabela com os sectores de incio e
fim de cada partio; uma das parties dever estar marcada como activa, contendo o sistema
operativo que deve ser lido e executado.
Cada partio comea com um bloco de boot, onde se situa o primeiro bloco executvel do sistema
operativo. Todas as parties tm este bloco, mesmo que no contenham um sistema operativo.
Em seguida vem um superbloco, com informao sobre o tipo de sistema de ficheiros
implementado na partio e outros parmetros como o nmero de blocos presente, etc. Depois pode
vir informao sobre os blocos livres, i-nodes, a directoria raiz e o resto dos ficheiros e directorias.
Implementao de ficheiros
Alocao contgua simples de implementar e de alta performance. Leva, com o tempo,
fragmentao e implica que o tamanho do ficheiro seja conhecido antes da sua criao. Usado no
incio dos discos magnticos, foi abandonado por ser de difcil utilizao pelos utilizadores, tendo
no entanto sido recuperado para o sistema de ficheiros dos CDROMs.
Alocao por lista ligada cada ficheiro constitudo por uma srie de blocos em que a primeira
palavra um apontador para o prximo bloco do ficheiro. Desta forma no existir fragmentao,
dado que todos os blocos do disco podero ser usados e a nica coisa que o sistema de ficheiros
necessita guardar um apontador para o primeiro bloco de cada ficheiro, conseguindo o resto da
informao a partir da. A desvantagem desta tcnica que torna difcil o acesso aleatrio, j que
necessrio seguir a cadeia de blocos de um ficheiro at ao requerido de cada vez que se faz um seek.
Outra desvantagem que cada bloco j no guarda um nmero de bytes que uma potncia de 2,
visto que a primeira palavra usada para o apontador.
Alocao por lista ligada usando uma tabela em memria como o anterior, com excepo de
que a tabela de apontadores est em memria (chamada FAT File Alocation Table). Isto elimina
as duas desvantagens do sistema anterior, mas introduz outra sendo necessrio guardar a tabela
em memria, impraticvel para discos grandes, j que consumiria muita memria.
I-nodes (index nodes) a cada ficheiro associada uma estrutura com os atributos do ficheiro e
uma lista dos blocos ocupados por ele. A grande vantagem sobre a FAT que apenas h
necessidade de ter na memria os i-nodes dos ficheiros abertos. Assim, a memria gasta pelo
sistema de ficheiros deixa de ser proporcional ao tamanho do disco e passa a ser proporcional ao
nmero de ficheiros que o sistema operativo pode ter abertos em cada momento. Se um ficheiro
gastar mais blocos do que o nmero de entradas na estrutura do i-node, pode usar a ltima entrada
como um apontador para um bloco onde est guardada a lista dos blocos restantes.
Implementao de directorias

A principal funo das directorias mapear um nome em texto para uma informao que permita
aceder ao ficheiro no disco, devolvendo a localizao do ficheiro (alocao contnua), o bloco
inicial (listas ligadas), ou o nmero do i-node. Uns sistemas guardam os atributos na prpria
entrada da directoria, enquanto que outros nos i-nodes.
Outros problemas comuns no desenho de sistemas de ficheiros relacionados com directorias so o
armazenamento de nomes de ficheiros grandes, que pode ser feito na prpria entrada da directoria
ou numa rea a seguir a todas as entradas, com um apontador na entrada, e o tempo de busca no
caso de directorias com um grande nmero de ficheiros, que pode ser resolvido usando um hash
para cada entrada na directoria ou cache para as entradas mais utilizadas.

You might also like