Você está na página 1de 35

Estudos SO

MEMÓRIA

gerenciamento de memória

Partições fixas :​ Nesse modelo os espaços de memória são predefinidos. Isso pode causar
problemas de​ fragmentação interna,​ gerando desperdício dentro da área alocada, pois um
processo de tamanho 40K pode estar ocupando 50K de memória, restando 10K. Também pode
causar problemas de ​fragmentação externa, ​pois se houver um espaço de 100k e outro espaço de
25k, e um processo de 110k, esse processo não poderá ser alocado mesmo havendo 125k de
espaço livre.

Partições variáveis: ​Otimiza a utilização da memória, mas complica a alocação e liberação de


memória. Acarreta em uma ​menor fragmentação interna​, pois os processos ocupam todo o espaço
oferecido a ele, mas em uma maior ​fragmentação externa​.

A​ compactação​ é utilizada para recuperar os espaços de memória perdidos pela fragmentação, no


entanto isso exige muito da CPU.

Alocação dinâmica de memória:​ ​Bitmaps e listas encadeadas.

Bitmaps:

1- Memória é dividida em unidades de alocação em Kbytes.


2- Cada unidade corresponde a 1 byte no bitmap. (0 = livre, 1 = ocupado)
3- Tamanho de bitmap depende do tamanho da unidade e do tamanho da memória.

Unidades de alocação pequena = Bitmap grande.


Unidades de alocação grande = Perda de espaço.

Para alocar um novo processo de tamanho k bytes, é preciso percorrer no mapa buscando uma
sequência de K bytes livres, sendo essa uma operação lenta.

Listas encadeadas:

Outra maneira de controlar o uso da memória é manter uma lista encadeada de espaços livres e de
segmentos de memória alocados, onde um segmento contém um processo ou é um espaço vazio
entre dois processos. Nesse modelo atualizar uma lista é um processo simples.
Correção de Erros:

​Bits extras permitem recuperação da informação original

Código de detecção e correção de erros em palavras de dados com 8 bits (M=8).

2^3 – 1 < 8 + 3 ------------ X


2^4 – 1 ​>=​ 8 + 4 ------------ ​OK

Tamanho total =​ nº bits de correção + nº bits do dado = 4 + 8 = 12


Acréscimo percentual =​ nº bits de correção / nº bits do dado = 4 / 8 = 50%

Necessários 4 bits de verificação ​para 8 bits​.

Mapeamento (MMU)

A relação entre endereços virtuais e endereços de memória física é dada pela tabela de
páginas.

Considere a tabela abaixo e faça uma análise do mapeamento:

Primeiramente notamos que nessa tabela existem ​16 quadros de página virtual​, como
64/16 = 4​, então os​ blocos têm 4k, ​como podemos ver nos intervalos da tabela. Para fazer
a análise de forma mais precisa, como sabemos que são 16 quadros de página virtual,
concluímos que precisamos de 4 bits para representá-los, pois 24 = 16​. Como restam 12 bits
para deslocamento, temos que 212 = 4096 , que representa o espaço de cada bloco. Note
que​ 4096 x 16 = 65.539​, que é a representação mais precisa dos 64K, e ​4096 x 8 = .32.768,
que é a representação mais precisa dos 32K.

Exercício da Prova:

Dê o endereço físico correspondente para cada um dos seguintes endereços virtuais:

(20) : ​Pela tabela sabemos que 20 leva para 8K, contudo 20 = 0K + 20, logo deve levar para
8K + 20. Por fim, sabemos que a representação mais precisa de 8K é 4096 x 2 = 8.192.
Então a resposta é 8.192 + 20 = 8202.

(4100) : ​Sabemos que o bloco tem 4096 bits, logo 4100 está entre 4K e 8K, que por sua vez
leva até o bloco 4K a 8K. Como 4100 = 4096 + 4, então teremos como resultado 4K+4, e
como a representação mais precisa de 4K é 4096,​ a resposta é
4.096 + 4 = 4100.

(8300) : ​Como 4096 x 2 = 8192, sabemos que 8300 está no bloco 3, que por sua vez leva ao
bloco 24K a 28K. Temos que 8300 - 8192 = 108, portanto o resultado deverá ser 24K+108,
e como a representação mais precisa de 24 K é 4096 x 6 = 24.576, ​a resposta é
24.576+108 = 24.684.

Obs: ​Se o endereço virtual não estivesse mapeado (X), então haveria Page Fault e o SO
teria que substituir um bloco mapeado pelo bloco que contém o endereço virtual que
desejamos mapear. Por exemplo, 25K não está mapeado, então ele poderia receber o
mapeamento do bloco 2, que aponta para 4k a 8k, enquanto o bloco 2 deixaria de estar
mapeado, recebendo (X).

​Algoritmos de Alocação

​ FIRST FIT
Aloca no 1º espaço que couber e atualiza o espaço para nova checagem. É Rápido, pois a busca é
rápida, mas pode desperdiçar memória por fragmentação.

Problema: Meio termo entre o best e worst, pois pode preencher espaços maiores ou menores, a
depender dos espaços que forem encontrados primeiro, deixando os últimos livres. Pode gerar
problemas dos dois tipos.

NEXT FIT
Aloca no 1º espaço que couber e atualiza o espaço para nova checagem, mas na próxima
alocação inicia busca do ponto que parou anteriormente. Possui desempenho inferior ao First Fit.
BEST FIT
Procura na lista toda e aloca o espaço que mais convém; Menor fragmentação; Mais lento;
Problema:​ Após um longo processamento, pode deixar buracos muito pequenos para serem úteis,
pois gera os menores restos.

WORST FIT

Aloca o maior espaço disponível;


Problema: pode tornar difícil alocar grandes jobs, pois consome primeiro os maiores espaços.

QUICK FIT
Mantém listas separadas para os espaços ​mais requisitados;​

Todos os quatro algoritmos podem ser acelerados mantendo-se listas em separado para os
processos e os espaços livres. Dessa maneira, todos eles devotam toda a sua energia para
inspecionar espaços livres, não processos. O preço inevitável que é pago por essa aceleração na
alocação é a complexidade e lentidão adicionais ao remover a memória, já que um segmento
liberado precisa ser removido da lista de processos e inserido na lista de espaços livres.

Swapping (Se não houver nenhum espaço compatível?)

Tenta resolver o problema de insuficiência da memória para todos os usuários.

Aloca espaço para programas que esperam por memória livre para serem processados.

Mecanismo ineficiente em função do tempo gasto para carregamento.

Uma alternativa é esperar que a região de memória usada pelo programa na ocasião do seu primeiro
carregamento esteja disponível.

Realocação Dinâmica:

○ É a melhor solução, uma implementação no hardware dos computadores, permitindo


que a realocação seja realizada durante a execução do programa.
○ Realizada através de um registrador especial denominado registrador de alocação,
que recebe o endereço inicial da região da memória que o programa irá ocupar no
momento do carregamento do programa na memória.
○ Toda vez que ocorrer uma referência a algum endereço, o endereço contido na
instrução será somado ao conteúdo do registrador, gerando assim, o endereço físico
Memória virtual

A ideia básica é que cada programa tem seu próprio espaço de endereçamento, o qual é dividido em
blocos chamados de ​páginas​. Cada página é uma série contígua de endereços. Elas são mapeadas
na memória física, mas nem todas precisam estar na memória física ao mesmo tempo para executar
o programa. Quando o programa referência uma parte do espaço de endereçamento que está na
memória física, o hardware realiza o mapeamento necessário rapidamente. Quando o programa
referência uma parte de seu espaço de endereçamento que não está na memória física, o sistema
operacional é alertado para ir buscar a parte que falta e re-executa a instrução que falhou.

Gerenciamento de Memória Troca de Páginas - Paginação

Problema: A memória está cheia, portanto queremos substituir uma página por outra que foi
referenciada. Qual página retirar?

Política de substituição local: ​Deve-se remover a página do processo atual que é mais antiga, ou
seja, aquela cuja o ​age​ é menor.

Política de substituição global: ​Como a local, mas olha para todos os processos.

Em geral, algoritmos globais funcionam melhor, especialmente quando o tamanho do conjunto de


trabalho puder variar muito através do tempo de vida de um processo. Se um algoritmo local for
usado e o conjunto de trabalho crescer, resultará em ultrapaginação, mesmo se houver um número
suficiente de quadros de páginas disponíveis. Se o conjunto de trabalho diminuir, os algoritmos locais
vão desperdiçar memória.

Algoritmo Ótimo

Nesse algoritmo já se conhece a dinâmica da paginação, sabendo em qual tempo a página será
referenciada e quando será solicitada a substituição, podendo responder sempre da melhor forma
possível.
Esse algoritmo não existe na prática e é apenas utilizado para simulações, de modo que seus
resultados ótimos possam ser comparados aos resultados dos demais algoritmos.

Então imaginando um caso em que o processo 1 e o processo 2 estão na memória, e com o


algoritmo sabendo que esses processos serão chamados várias vezes futuramente, o algoritmo evita
tirar p1 e p2 da memória para evitar page faults.

Algoritmo Not Recently Used (NRU)

Neste algoritmo são utilizados 2 bits que se encontram na tabela de páginas. O bit ​R​ é relacionado
ao ​referenciamento​ da página, enquanto o bit ​M ​é relacionado a ​modificação​.

Quando ocorre uma falta de página, o sistema operacional inspeciona todas as páginas e as divide
em quatro categorias baseadas nos valores atuais de seus bits R e M:

Classe 0:​ não referenciada, não modificada. (0 0)


Classe 1:​ não referenciada, modificada. (0 1)
Classe 2:​ referenciada, não modificada. (1 0)
Classe 3:​ referenciada, modificada. (1 1)

Quando um processo é inicializado, ambos os bits de páginas para todas as suas páginas são
definidos como 0 pelo sistema operacional.

Páginas ​não ​referenciadas são páginas que não vem sendo utilizadas, enquanto que páginas
modificadas precisam ser atualizadas.

O bit ​R é limpo periodicamente​ para que seu valor seja 1 somente se a página tiver sido
referenciada recentemente, enquanto o bit ​M não é limpo​, visto que o SO precisa dessa informação
até atualizar a página.

Remove uma página ao acaso de sua classe de ordem mais baixa que não esteja vazia​.
Implícito nesse algoritmo está a ideia de que é melhor remover uma página modificada, mas não
referenciada, a pelo menos um tique do relógio (em geral em torno de 20 ms) do que uma página
não modificada que está sendo intensamente usada.

A lista deve ser atualizada a cada referência da memória ​(Alto custo)

Exercício: Dada uma ​memória RAM​ de 4 Kb, uma ​moldura / página​ de 2 Kb e uma​ memória
virtual​ de 6 Kb.

Simule a Execução​ abaixo e informe ​quantas interrupções de sistema​ haverão.

Write 100​ , 1
Write 4K ​, 1
Read 6k
Write 1k + 100 ​, 1
Write 2k + 500 ​, 1
Read 600

Resolvendo.

Definindo paginação:

Para simplificar, adotaremos:


(0 0)​ : 0 a 2k ​(0 1)​ : 2K+1 a 4k ​(1 0)​ : 4K+1 a 6k

Na ​primeira​ execução é recebida a página 0 0 que, como não estava na RAM,​ acarreta em uma
interrupção.

Na ​segunda​ execução, primeiramente ​limpamos R​, em seguida adicionamos a página 0 1, ​pois


ainda cabe na RAM​.​ Novamente há interrupção​, visto que 0 1 não estava na RAM.

Na ​terceira​ execução, a RAM está cheia, ​portanto é preciso realizar substituição​. ​A substituição
será realizada na pagina 0 0, pois tem menor valor em R, sendo assim ​1 0 será executado​.​ R volta
a ser referenciado​, e como a execução é apenas de leitura, ​M recebe 0​. Na página 0 1 é preciso
limpar R, pois foi feita uma nova referência da memória. ​Novamente há interrupção​, pois 1 0 não
estava na memória.

Na ​quarta​ execução, na pagina 1 0 limpamos R. Deve haver substituição da página 0 1, pois é tem
menor valor de R. ​0 0 é processado​, R volta a ser referenciado ​Novamente há interrupção​, pois 0
0 não estava na RAM.
Na ​quinta​ execução, na página 0 0 limpamos R. A página 1 0 deve ser substituída, visto que possui
menor valor de R. ​0 1 é executado​, R volta a ser referenciado e M é atualizado pois é de escrita,
recebendo 1.​Novamente há interrupção​, pois 0 1 não estava na RAM.

Na ​sexta​ execução, 0 0 deve ser substituído pois tem menor valor em R. Como recebemos uma
nova página com modulação 0 0, ​não há interrupção​. Na página 0 0 R volta a ser referenciado e M
passa a ser 0, pois é uma leitura; enquanto que na página 1 0 limpamos R.

Portanto ocorrem 5 interrupções.

Algoritmo FIFO

S.O mantém uma listas das páginas correntes na memória. A página no início da lista é a mais
antiga e a página no final da lista é a mais nova. É simples, mas pode ser ineficiente, pois uma
página que está em uso constante pode ser retirada; por isso é pouco utilizado.

Exercício: Considere uma memória RAM de 4 paginas e os processos P1 (1, 2, 3) e P2 (a, b, c,


d), sendo 1 2 3 a b c d as páginas lógicas.

Páginas acessadas: 2 3 1 a b 3 1 1 c d 1 a.

Simule e indique a quantidade de page faults (interrupções).

Total de 9 Page Faults (4+1+1+1+1+1)


Algoritmo da Segunda Chance (Fifo + bit R)

É como FIFO, só que agora cada página começa com uma chance​ (um bit 1)​. Quando a memória
física estiver cheia e for tentada a substituição, será verificado se o primeiro processo da fila possui 0
chances ​(bit 0)​ - se sim, esse processo irá para o final da fila e será substituído; se não ele irá para o
​ aso a memória esteja cheia, mas não seja necessária a
final da fila trocando o bit para 0.​ C
substituição pelo fato de receber um processo que já está na memória, esse processo
ganhará uma chance.

Exercício: Considere uma memória virtual de 16K, uma memória RAM de 8 K e uma moldura
de 2 K. Mostre a simulação para: ​P1 -> P3 - > P5 - >P2 -> P4 -> P7 -> P2 -> P8.

Algoritmo do Relógio

Lista circular com ponteiro apontando para a página mais antiga. Algoritmo se repete até encontrar
R=0.​ É igual ao de segunda chance, mas circular.

Se o processo para qual o ponteiro aponta tem chance, sua chance é zerada e o ponteiro
aponta para o próximo processo (Sentido horário). Caso o processo para qual o ponteiro
aponta não tenha chance, ele será substituído se receber um processo que gere Page Fault ​ou
ganhará uma chance se receber ele próprio.
Exercício: Faça o exercício anterior, mas com o Algoritmo do relógio.

Note que também haverão 7 Page Faults e o resultado em MR será igual ao do FIFO.

Least Recently Used Page Replacement (LRU)

O LRU é mais simples,​ bastando substituir a página mais antiga​, ou seja, com o menor valor de
age​.

Exercício: Considere uma memória RAM de 3 páginas/modulos e a seguinte ordem de


execução:

Write P1​, 1
Write P3 ​, 1
Write P1​, 1
Read P4
Write P3 ​, 1
Write P1​, 1
Read P2​, 1

Simule e indique a quantidade de interrupções.


Utilizando modelo de Hardware:

Cria uma ​matriz nxn​ onde ​n é o número de módulos da memória RAM.

Quando é obtido um novo processo, em​ toda a linha será colocado 1​, e em t​ oda coluna será
colocado 0​. N
​ ESSA ORDEM!

Quando for necessário fazer substituição,​ deve ser feita por aquele que possuir menor
número em binário na linha.

Interrupções nas matrizes 1, 2, 4 e 7. Total = 4.

Utilizando modelo de Software:

Para elaborar um Software eficiente aplicável ao LRU, é preciso utilizar o conceito ​NFU​ (Not
frequently used) ou LFU (least frequently used). Basicamente serão removidos os processos
​ parecem menos vezes.​
que a
1 - P1 entra com contador 1 e há interrupção, pois não estava na RAM.
2 - P3 entra com contador 1 e há interrupção, pois não estava na RAM.
3 - P1 fica com contador 2 e não há interrupção, pois já estava na RAM.
4 - P4 entra com contador 1 e há interrupção, pois não estava na RAM.
5 - P3 fica com contador 2 e não há interrupção, pois já estava na RAM.
6 - P1 fica com contador 3 e não há interrupção, pois já estava na RAM.
7 - P2 entra com contador 1 e substitui P4 pois é a página menos frequente; e há interrupção, pois
não estava na RAM.

Total de interrupções: 4

O problema desse modelo é que, caso exista um processo muito grande que seja usado muitas
vezes inicialmente, mas depois deixe de ser usado, ele nunca será removido, ocupando espaço de
processos que deveriam estar sendo executados. Para resolver esse problema, podemos utilizar o
método Aging.

Algoritmo Aging

Além de saber quantas vezes a página foi referenciada, também controla quando ela foi
referenciada.

1º) Cria matriz​ ​nº páginas​ ​x​ ​nº bits de clock​.​ ​Primeira coluna recebe o primeiro tick.

2º) Move todos os tick para direita e coloca o próximo tick na primeira coluna - até finalizar.

Questão da prova resolvida no final do PDF.

Algoritmo Working Set (WS)

Objetivo principal: reduzir a falta de páginas


Um processo só é executado quando todas as páginas necessárias no tempo t estão carregadas na
memória. O SO gerencia quais páginas estão no Working Set.

Para simplificar o working set pode ser visto como o conjunto de páginas que o processo referenciou
durante os últimos t segundos de tempo.

Utiliza bit R e o tempo de relógio (tempo virtual) da última vez que a página foi referenciada;

REGRAS

Algoritmo Working Set Clock (WSCLOCK)

Clock + Working Set.

Lista circular de molduras de páginas formando um anel a cada página carregada na memória.

Utiliza bit R e o tempo da última vez que a página foi referenciada.

Bit M utilizado para agendar escrita em disco.


Regras:

Se R == 1​:
faz R = 0 e move o ponteiro.

Se R == 0​:
​ ​ a​ página estiver limpa (m==0):​ ​ Substitui a página​ e move o ponteiro.
se age > t e

​ ​ a página estiver suja (m==1) :​ S


se age > t e ​ olicita escrita no disco e move o ponteiro.

​ erá temporariamente poupada​, e avança o ponteiro procurando um


se age <= t : S
candidato melhor - (Página com R==0 que possua o maior age).
Se não existirem páginas onde R==0, remove uma página arbitrariamente.
​ O que acontece com a página apontada pelo relógio abaixo nos casos de t = 400 e t = 1000?
Para saber qual página tem maior age, basta escolher a que possuir menor Tempo do Último Uso
(TLU).

Sistema de arquivos
Todo arquivo possui um nome e sua data. Além disso, todos os sistemas operacionais associam
outras informações com cada arquivo, por exemplo, a data e o horário em que foi modificado pela
última vez, assim como o tamanho do arquivo.

As sinalizações (flags) são bits ou campos curtos que controlam ou habilitam alguma propriedade
específica. Arquivos ocultos, por exemplo, não aparecem nas listagens de todos os arquivos.
. Dessa maneira, o programa consegue dizer quais arquivos precisam de backup. A sinalização
temporária permite que um arquivo seja marcado para ser deletado automaticamente quando o
processo que o criou for concluído.

Alocação contígua

O esquema de alocação mais simples é armazenar cada arquivo como uma execução contígua de
blocos de disco. Assim, em um disco com blocos de 1 KB, um arquivo de 50 KB seria alocado em 50
blocos consecutivos. Com blocos de 2 KB, ele seria alocado em 25 blocos consecutivos.

A alocação de espaço de disco contíguo tem duas vantagens significativas. Primeiro, ela é simples
de implementar porque basta se lembrar de dois números para monitorar onde estão os blocos de
um arquivo: o endereço em disco do primeiro bloco e o número de blocos no arquivo. Dado o número
do primeiro bloco, o número de qualquer outro bloco pode ser encontrado mediante uma simples
adição. Segundo, o desempenho da leitura é excelente, pois o arquivo inteiro pode ser lido do disco
em uma única operação. Apenas uma busca é necessária (para o primeiro bloco). Depois, não são
mais necessárias buscas ou atrasos rotacionais, então os dados são lidos com a capacidade total do
disco. Portanto, a alocação contígua é simples de implementar e tem um alto desempenho.

Infelizmente, a alocação contígua tem um ponto fraco importante: com o tempo, o disco torna-se
fragmentado. Isso ocorre quando arquivos são liberados, deixando espaços vazios. Compactar é
inviável, e reutilizar os espaços livres para colocar os arquivos não é eficiente, pois seria necessário
saber o tamanho final do arquivo para que ele possa ser alocado em um espaço, e na maioria dos
casos isso não é o que se deseja.

Exemplo de Utilidade: Cd-Romns - todos os tamanhos dos arquivos são conhecidos


antecipadamente.
Alocação por lista encadeada

O segundo método para armazenar arquivos é manter cada um como uma lista encadeada de blocos
de disco. A primeira palavra de cada bloco é usada como um ponteiro para a próxima. O resto do
bloco é reservado para dados.

Diferentemente da alocação contígua, todos os blocos do disco podem ser usados nesse método.
Nenhum espaço é perdido para a fragmentação de disco (exceto para a fragmentação interna no
último bloco). Também, para a entrada de diretório é suficiente armazenar meramente o endereço
em disco do primeiro bloco. O resto pode ser encontrado a partir daí.

Problema: o acesso aleatório é de extrema lentidão. Para chegar ao bloco n, o sistema operacional
precisa começar do início e ler os blocos n − 1 antes dele, um de cada vez. É claro que realizar
tantas leituras será algo dolorosamente lento. Além disso, como os ponteiros ocupam alguns bytes
do bloco, o tamanho não mais segue potências de 2, o que pode tornar mais complicada a
manipulação.

Alocação por lista encadeada usando uma tabela na memória.

Ambas as desvantagens da alocação por lista encadeada podem ser eliminadas colocando-se as
palavras do ponteiro de cada bloco de disco em uma tabela na memória. Essa tabela na memória
principal é chamada de FAT (File Allocation Table — tabela de alocação de arquivos).

Usando essa organização, o bloco inteiro fica disponível para dados. Além disso, o acesso aleatório
é muito mais fácil. Embora ainda seja necessário seguir o encadeamento para encontrar um
determinado deslocamento dentro do arquivo, o encadeamento está inteiramente na memória,
portanto ele pode ser seguido sem fazer quaisquer referências ao disco. Da mesma maneira que no
método anterior, é suficiente para a entrada de diretório manter um único inteiro (o número do bloco
inicial) e ainda assim ser capaz de localizar todos os blocos, não importa o tamanho do arquivo.
Arquivo A: 4,7,2,10,12. (4 leva ao 7; 7 leva ao 2; 2 leva ao 10; 10 leva ao 12)

A principal desvantagem desse método é que a tabela inteira precisa estar na memória o todo o
tempo para fazê-la funcionar. Com um disco de 1 TB e um tamanho de bloco de 1 KB, a tabela
precisa de 1 bilhão de entradas, uma para cada um dos 1 bilhão de blocos de disco. Cada entrada
precisa ter no mínimo 3 bytes. Para aumentar a velocidade de consulta, elas deveriam ter
4 bytes. Desse modo, a tabela ocupará 3 GB ou 2,4 GB da memória principal o tempo inteiro,
dependendo de o sistema estar otimizado para espaço ou tempo. Não é algo muito prático. Claro, a
ideia da FAT não se adapta bem para discos grandes. Era o sistema de arquivos MS-DOS original e
ainda é aceito completamente por todas as versões do Windows.

I-nodes

Nosso último método para monitorar quais blocos pertencem a quais arquivos é associar cada
arquivo a uma estrutura de dados chamada de i-node (index-node — nó-índice) que lista os
atributos e os endereços de disco dos blocos do disco.

Dado o i-node, é então possível encontrar todos os blocos do arquivo. A grande vantagem desse
esquema sobre os arquivos encadeados usando uma tabela na memória é que o i-node precisa estar
na memória apenas quando o arquivo correspondente estiver aberto. Se cada i-node ocupa n bytes e
um máximo de k arquivos puderem estar abertos simultaneamente, a memória total ocupada pelo
arranjo contendo os i-nodes para os arquivos abertos é de apenas kn bytes. Apenas essa quantidade
de espaço precisa ser reservada antecipadamente.

Esse arranjo é em geral muito menor do que o espaço ocupado pela tabela de arquivos descrita na
seção anterior. A razão é simples. A tabela para conter a lista encadeada de todos os blocos de
disco é proporcional em tamanho ao disco em si. Se o disco tem n blocos, a tabela precisa de n
entradas. À medida que os discos ficam maiores, essa tabela cresce linearmente com eles. Por outro
lado, o esquema i-node exige um conjunto na memória cujo tamanho seja proporcional ao número
máximo de arquivos que podem ser abertos ao mesmo tempo. Não importa que o disco tenha 100
GB, 1.000 GB
ou 10.000 GB.

Um problema com i-nodes é que se cada um tem espaço para um número fixo de endereços de
disco, o que acontece quando um arquivo cresce além de seu limite? Uma solução é reservar o
último endereço de disco não para um bloco de dados, mas, em vez disso, para o endereço de um
bloco contendo mais endereços de blocos de disco.

Gerenciamento e otimização de sistemas de arquivos

Arquivos costumam ser armazenados em disco, portanto o gerenciamento de espaço de disco é uma
preocupação importante para os projetistas de sistemas de arquivos. Duas estratégias gerais são
possíveis para armazenar um arquivo de n bytes: ou são alocados n bytes consecutivos de espaço,
ou o arquivo é dividido em uma série de blocos (não necessariamente) contíguos. A mesma escolha
está presente em sistemas de gerenciamento de memória entre a segmentação pura e a paginação.

Como vimos, armazenar um arquivo como uma sequência contígua de bytes tem o problema óbvio
de que se um arquivo crescer, ele talvez tenha de ser movido dentro do disco. O mesmo problema
ocorre para segmentos na memória, exceto que mover um segmento na memória é uma operação
relativamente rápida em comparação com mover um arquivo de uma posição no disco para outra.
Por essa razão, quase todos os sistemas de arquivos os dividem em blocos de tamanho fixo que não
precisam ser adjacentes.

Tamanho do bloco
Uma vez que tenha sido feita a opção de armazenar arquivos em blocos de tamanho fixo, a questão
que surge é qual tamanho o bloco deve ter.

Ter um tamanho de bloco grande significa que todos os arquivos, mesmo um de 1 byte, ocuparão um
cilindro inteiro. Também significa que arquivos pequenos desperdiçam uma grande quantidade de
espaço de disco. Por outro lado, um tamanho de bloco pequeno significa que a maioria dos arquivos
ocupará múltiplos blocos e, desse modo, precisará de múltiplas buscas e atrasos rotacionais para
lê-los, reduzindo o desempenho. Então, se a unidade de alocação for grande demais, desperdiçamos
espaço; se ela for pequena demais, desperdiçamos tempo. Fazer uma boa escolha exige ter
algumas informações sobre a distribuição do tamanho do arquivo.

Como exemplo, considere um disco com 1 MB por trilha, um tempo de rotação de 8,33 ms e um
tempo de busca de 5 ms. O tempo em milissegundos para ler um bloco de k bytes é então a soma
dos tempos de busca, atraso rotacional e transferência: 5 + 8,33/2 + (k/1000000) × 8,33

Monitoramento dos blocos livres

Uma vez que um tamanho de bloco tenha sido escolhido, a próxima questão é como monitorar os
blocos livres. Dois métodos são amplamente usados .O primeiro consiste em usar uma lista
encadeada de blocos de disco, com cada bloco contendo tantos números de blocos livres de disco
quantos couberem nele. Com um bloco de 1 KB e um número de bloco de disco de 32 bits, cada
bloco na lista livre contém os números de 255 blocos livres. (Uma entrada é reservada para o
ponteiro para o bloco seguinte.) Considere um disco de 1 TB, que tem em torno de 1 bilhão de
blocos de disco. Armazenar todos esses endereços em blocos de 255 exige cerca de 4 milhões de
blocos. Em geral, blocos livres são usados para conter a lista livre, de maneira que o
armazenamento seja essencialmente gratuito.

A outra técnica de gerenciamento de espaço livre é o mapa de bits. Um disco com n blocos exige
um mapa de bits com n bits. Blocos livres são representados por 1s no mapa, blocos alocados por 0s
(ou vice-versa). Para nosso disco de 1 TB de exemplo, precisamos de 1 bilhão de bits para o mapa,
o que exige em torno de 130.000 blocos de 1 KB para armazenar. Não surpreende que o mapa de
bits exige menos espaço, tendo em vista que ele usa 1 bit por bloco, versus 32 bits no modelo de
lista encadeada. Apenas se o disco estiver praticamente cheio (isto é, tiver poucos blocos livres) o
esquema da lista encadeada exigirá menos blocos do que o mapa de bits.

Entrada e saída
Algoritmos de escalonamento de braço de disco

Para todos os exemplos vamos considerar que a saída é da pos 0.

FCFS - primeiro a chegar, primeiro a ser servido.

Anda para o próximo cilindro na ordem de solicitação.


Ex: Se entrada é 10, 22, 20, 2, 40, 6, 38.

Partimos do 10.
Percorre ​12​ cilindros até chegar no 22.
Percorre​ 2​ cilindros até chegar no 20.
Percorre ​18​ cilindros até chegar no 2.
Percorre ​38​ cilindros até chegar no 40.
Percorre ​34​ cilindros até chegar no 6.
Percorre ​32​ cilindros até chegar no 38.
Total: ​136​ cilindros (movimentos de braço).
Custoso.

SSF - Busca mais curta primeiro.

Vai para o que estiver mais próximo.

Ex: Se entrada é 10, 22, 20, 2, 40, 6, 38.


Partimos do 10.
Percorre ​4​ cilindros até chegar no 6.
Percorre ​4​ cilindros até chegar no 2.
Percorre ​18​ cilindros até chegar no 20.
Percorre ​2​ cilindros até chegar no 22.
Percorre ​16​ cilindros até chegar no 38.
Percorre ​2​ cilindros até chegar no 40.
Total: ​46 cilindros​ (movimentos de braço).

O problema é quando recebe novas entradas, pode preterir a elas do que as que estão lá a
mais tempo, principalmente nas extremidades.

Elevador

1º deve-se saber qual o bit de direção inicial (​sobe ou desce​)

O algoritmo segue a direção até não encontrar nenhuma entrada que a satisfaça, então volta.

Por exemplo:​ Com bit inicial ​sobe​ ele irá procurar entradas maiores, a partir da primeira, até não
haver mais nenhuma. Em seguida ele volta, pegando todas as menores.

Ex: Se entrada é 10, 22, 20, 2, 40, 6, 38.


Partimos do 10
Percorre ​10 ​cilindros até chegar no 20.
Percorre ​2​ cilindros até chegar no 22.
Percorre ​16​ cilindros até chegar no 38.
Percorre ​2​ cilindros até chegar no 40.
Percorre ​34​ cilindros até chegar no 6.
Percorre ​4​ cilindros até chegar no 2.
Total: ​68 cilindros​ (movimentos de braço).

IMPASSES

Há dois tipos de recursos: preemptíveis e não preemptíveis. Um recurso preemptivo é aquele que
pode ser retirado do processo proprietário sem causar-lhe prejuízo algum. A memória é um exemplo
de um recurso preemptível.

Um recurso não preemptível, por sua vez, é um recurso que não pode ser tomado do seu proprietário
atual sem potencialmente causar uma falha. Se um processo começou a ser executado em um
Blu-ray, tirar o gravador Blu-ray dele de repente e dá-lo a outro processo resultará em um Blu-ray
bagunçado.

Usando semáforos para proteger recursos.

Typedef int semaphore;


semaphore resourse_1;
semaphore resoure_2; //exemplo com 2 recursos

void process_A(void){
dow(&resourse_1);
dow(&resourse_2);
use_both_resourses();
up(&resourse_2);
up(&resourse_1);
}

O problema ocorre quando um​ processo A​ consegue o​ recurso 1​ e o ​processo B​ consegue o


recurso 2​, e ambos bloqueiam a aquisição desses recursos.Então se ​A​ precisa do recurso ​2​, não
conseguirá. ​Isso é um impasse.

Formalmente: “Um conjunto de processos estará em situação de impasse se cada processo no


conjunto estiver esperando por um evento que apenas outro processo no conjunto pode causar”.

Quatro condições para que ocorra um impasse :

Exclusão mútua: cada recurso pode estar somente em uma de duas situações: ou associado a um
único processo ou disponível;
Posse e espera ( hold and wait ): processos que já possuem algum recurso podem requerer outros
recursos;

Não-preempção: recursos já alocados não podem ser retirados do processo que os alocou; somente
o processo que alocou os recursos pode liberá-los;

Espera Circular: um processo pode esperar por recursos alocados a outro processo;

​Todas as condições devem ocorrer para que ocorra um deadlock

Representação:
Processo C​ solicita​ recurso T​, porém o​ recurso T​ está sendo usado pelo ​processo D​; o ​processo
D​ por sua vez não irá liberar o ​recurso T​ pois precisa do ​recurso U​ para dar prosseguimento a sua
ação, contudo o ​recurso U​ está sendo usado pelo​ processo C​.

Executar os processos sequencialmente impede impasses, contudo também não possibilita


paralelismo e por isso executar os processos de maneira estritamente sequencial pode não ser uma
opção ótima.

Estado seguro e inseguro

A diferença entre um estado seguro e um inseguro é que a partir de um seguro o sistema pode
garantir que todos os processos terminarão; a partir de um estado inseguro, nenhuma garantia nesse
sentido pode ser dada. ​Inseguro é diferente de Impasse.

Algoritmo do banqueiro para 1 único recurso.

​ que o algoritmo faz é conferir para ver se conceder a solicitação leva a um estado inseguro. Se
O
afirmativo, a solicitação é negada. Se conceder a solicitação conduz a um estado seguro, ela é
levada adiante.

Observe os estados abaixo.

O estado (a) é seguro​, pois possui 10 recursos disponíveis e com isso pode finalizar qualquer um
dos processos (que demandam 6,5,4 e 7), ​voltar a ter os 10 disponíveis quando finalizar o processo,​
e fazer o mesmo com os outros processos.

O estado (b) é seguro​, pois tendo 2 recursos disponíveis é possível​ finalizar o processo C​,
recuperar 4 recursos​,​ finalizar o processo B ou o processo D​,​ recuperar mais recursos​ e por fim
finalizar o processo A​.

O estado (c) não é seguro​, pois com 1 recurso disponível não é possível finalizar nenhum dos
processos.
---------------------------------------------------------------------------------------------------------------------------
SOLUÇÃO DAS QUESTÕES DA PROVA 2017.1
---------------------------------------------------------------------------------------------------------------------------

Questão 1)​ Tendo ​4​ páginas e um contador de ​8​ bits, O primeiro tick é​ 0 1 1 1 ​e os ticks
subsequentes são ​1011​ , ​1010​, ​1101​, ​0010​, ​1010​, ​1100​ e ​0001​, use o aging e determine os
contadores no último tick.
1º) Cria matriz 4x8​.​ ​Primeira coluna recebe o primeiro tick.
2º) Move todos os tick para direita e coloca o próximo tick na primeira coluna - até finalizar.

Resposta:

0​ 0 0 0 0 0 0 0 1 ​0​ 0 0 0 0 0 0 0​ ​1​ 1​ 0 ​1​ ​1​ ​1​ ​0


1​ 0 0 0 0 0 0 0 0 ​1​ 0 0 0 0 0 0 (. . .) 0 ​1​ ​0​ ​0​ ​1​ ​0​ ​0​ ​1
1​ 0 0 0 0 0 0 0 1​ ​1​ 0 0 0 0 0 0 0 ​0​ ​1 ​1​ ​0 ​1​ ​1​ ​1
1​ 0 0 0 0 0 0 0 0 ​1​ 0 0 0 0 0 0 1 ​0​ ​0​ ​0​ ​1​ ​0​ ​1​ ​1

Questão 2)

Definir se os estados ​A​ e ​B​ são seguros ou inseguros. ​(Crédito do banqueiro = 10)

Resposta:
Questão 3)
Resposta:
Questão 4) ​Considere a memória com as lacunas 10 kb, 4 kb, 20 kb, 18 kb, 7 kb, 9 kb, 12
kb e 15 kb.

Aplique first fit, next fit, worst fit e best fit para as solicitações 12 kb, 10 kb e 9 kb.

Resposta:
First:
Olha o primeiro, se cabe então atualiza espaço e retorna a busca pro início; se não cabe,
então olha o próximo.

solicitação de ​12 kb​: (​Cabe em 20 kb)​


10 kb 4kb ​8kb​ 18 kb 7 kb 9 kb 12 kb 15 kb
Solicitação de ​10 kb​ : ​(Cabe em 10 kb)​
0 kb ​4kb ​8kb​ 18 kb 7 kb 9 kb 12 kb 15 kb

solicitação de ​9 kb​ : (​Cabe em 18 kb​)


0 kb ​4kb ​8kb​ ​9 kb​ 7 kb 9 kb 12 kb 15 kb

Next:
Olha o primeiro, se cabe então atualiza espaço e continua a busca a partir do próximo; se
não cabe, então olha o próximo.

solicitação de ​12 kb​: (​Cabe em 20 kb)​


10 kb 4kb ​8kb​ 18 kb 7 kb 9 kb 12 kb 15 kb

Solicitação de ​10 kb​ : ​(Cabe em 18 kb)​


10 kb ​ ​4kb ​8kb​ 8 kb​ 7 kb 9 kb 12 kb 15 kb

solicitação de ​9 kb​ : (​Cabe em 9 kb​)


10 kb​ ​4kb ​8kb​ ​8 kb​ 7 kb ​0 kb​ 12 kb 15 kb

Best:
Busca pelo espaço cuja diferença é a menor possível.
solicitação de ​12 kb​: (​Cabe em 12 kb)​
10 kb 4kb 20 kb 18 kb 7 kb 9 kb ​0 kb​ 15 kb

Solicitação de ​10 kb​ : ​(Cabe em 10 kb)​


0 kb​ ​ ​4kb 20 kb 18 kb 7 kb 9 kb ​0 kb​ 15 kb

solicitação de ​9 kb​ : (​Cabe em 9 kb​)


0 kb ​4kb 20 kb 18 kb 7 kb ​0 kb​ ​0 kb​ 15 kb

Worst:
Busca pelo espaço cuja diferença é a maior possível.

solicitação de ​12 kb​: (​Cabe em 20 kb)​


10 kb 4kb ​8kb​ 18 kb 7 kb 9 kb 12 kb 15 kb

Solicitação de ​10 kb​ : ​(Cabe em 18 kb)​


10 kb ​ ​4kb ​8kb​ ​8 kb​ 7 kb 9 kb 12 kb 15 kb

Solicitação de ​9 kb​ : ​(Cabe em 15 kb​)


10 kb ​ ​4kb ​8kb​ ​8 kb​ 7 kb 9 kb 12 kb ​6 kb

Questão 5) Um sistema de arquivo Unix adota ​blocos de 2048 bytes ​e 32 bits para endereços de
blocos no disco. O i-node armazena ​8 ponteiros para blocos de dados no disco,​ ​ ​1 ponteiro para
encadeamento simples​ e 1​ ponteiros para encadeamento duplo.

A) Qual o tamanho máximo do arquivo.

32 bits = 4 bytes (quanto endereço ocupa)


2048 bytes / 4 = 512 endereços adicionais de disco (cabem em 1 bloco)

1- Cada ponteiro direto leva a 1 bloco. Como temos 8 ponteiros direitos, serão ​8​ blocos.
2 - Cada ponteiro indireto simples leva aos 512 endereços adicionais de disco, onde cada 1 desses
endereços levam a 1 bloco.​ ​(512 blocos)
3 - Cada ponteiro indireto duplo leva aos 512 endereços adicionais de disco, onde cada 1 desses
endereços levam a novos 512 endereços adicionais de disco, que por sua vez levam a 1 bloco. (​(512
* 512) ​blocos)

Tmax = (​8​ + ​1*(512)¹ ​+ ​1*(512)²​) * ​2048 bytes

Resposta: d)

B) Se o tamanho do bloco variar de 2048 para 1024 pode-se afirmar que:

1024 / 4 = 256 endereços adicionais de disco

Seguindo os passos já descritos, ​Tmax = ( 8


​ ​ + ​1*(256¹)​ + ​1*(256)²)​ * 1
​ 024

a) Não haverá mudança no Tmax (Falso, como pode ser observado na fórmula)
b) Tmax dobrou (Falso, pois diminuiu)
c) Tmax cairá pela metade (Falso, a metade seria (​ ​8​ + ​1*(512)¹ ​+ ​1*(512)²​) * ​1024 Bytes)
d) Tmax triplicou (Falso, diminuiu)
e) n.d.a (Verdadeiro)

C) Se o tamanho do bloco variar de 2048 para 1024 e o número de bits para endereços de
bloco variar de 32 para 16, pode-se afirmar que:

1024 / 2 = 512 endereços adicionais de disco


Tmax = (​8​ + ​1*(512)¹ ​+ ​1*(512)²​) * ​1024 bytes ​ (Que é a metade)

c) Tmax cairá pela metade (Verdadeiro)

---------------------------------------------------------------------------------------------------------------------------
SOLUÇÃO DAS QUESTÕES DA PROVA 2018.1
---------------------------------------------------------------------------------------------------------------------------
Questão 1) ​*Pode haver erro*
Questão 3)​ Igual a questão 4 da prova anterior.
(20) : ​Pela tabela sabemos que 20 leva para 8K, contudo 20 = 0K + 20, logo deve levar para
8K + 20. Por fim, sabemos que a representação mais precisa de 8K é 4096 x 2 = 8.192.
Então a resposta é 8.192 + 20 = 8202.

(4100) : ​Sabemos que o bloco tem 4096 bits, logo 4100 está entre 4K e 8K, que por sua vez
leva até o bloco 4K a 8K. Como 4100 = 4096 + 4, então teremos como resultado 4K+4, e
como a representação mais precisa de 4K é 4096,​ a resposta é
4.096 + 4 = 4100.

(8300) : ​Como 4096 x 2 = 8192, sabemos que 8300 está no bloco 3, que por sua vez leva ao
bloco 24K a 28K. Temos que 8300 - 8192 = 108, portanto o resultado deverá ser 24K+108,
e como a representação mais precisa de 24 K é 4096 x 6 = 24.576, ​a resposta é
24.576+108 = 24.684.

---------------------------------------------------------------------------------------------------------------------------
SOLUÇÃO DAS QUESTÕES DA PROVA 3 2018.1
---------------------------------------------------------------------------------------------------------------------------

Questão 1) Dada a entrada ​10, 22, 20, 2, 40, 6, 38. Considerando 6 ns por cilindro movido.
Use FCFS, SSF e Elevador(bit de subida) para calcular o tempo total.

Para todos os exemplos vamos considerar que a saída é da pos 0.

FCFS - primeiro a chegar, primeiro a ser servido.

Anda para o próximo cilindro na ordem de solicitação.

Ex: Se entrada é 10, 22, 20, 2, 40, 6, 38.

Partimos do 10.
Percorre ​12​ cilindros até chegar no 22.
Percorre​ 2​ cilindros até chegar no 20.
Percorre ​18​ cilindros até chegar no 2.
Percorre ​38​ cilindros até chegar no 40.
Percorre ​34​ cilindros até chegar no 6.
Percorre ​32​ cilindros até chegar no 38.
Total: ​136​ cilindros (movimentos de braço).

Tempo total = ​ 136 * 6ns = 816 ns

SSF - Busca mais curta primeiro.


Vai para o que estiver mais próximo.

Partimos do 10.
Percorre ​4​ cilindros até chegar no 6.
Percorre ​4​ cilindros até chegar no 2.
Percorre ​18​ cilindros até chegar no 20.
Percorre ​2​ cilindros até chegar no 22.
Percorre ​16​ cilindros até chegar no 38.
Percorre ​2​ cilindros até chegar no 40.
Total: ​46 cilindros​ (movimentos de braço).
Tempo total = ​ 46 * 6ns = 276 ns

O problema é quando recebe novas entradas, pode preterir a elas do que as que estão lá a
mais tempo, principalmente nas extremidades.

Elevador

1º deve-se saber qual o bit de direção inicial (​sobe ou desce​)

O algoritmo segue a direção até não encontrar nenhuma entrada que a satisfaça, então volta.

Por exemplo:​ Com bit inicial ​sobe​ ele irá procurar entradas maiores, a partir da primeira, até não
haver mais nenhuma. Em seguida ele volta, pegando todas as menores.

Partimos do 10
Percorre ​10 ​cilindros até chegar no 20.
Percorre ​2​ cilindros até chegar no 22.
Percorre ​16​ cilindros até chegar no 38.
Percorre ​2​ cilindros até chegar no 40.
Percorre ​34​ cilindros até chegar no 6.
Percorre ​4​ cilindros até chegar no 2.
Total: ​68 cilindros​ (movimentos de braço).
Tempo total = ​ 68 * 6ns = 408 ns
Q2)